]> git.neil.brown.name Git - history.git/commitdiff
Import 1.3.68 1.3.68
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:10:36 +0000 (15:10 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:10:36 +0000 (15:10 -0500)
74 files changed:
Documentation/Configure.help
Documentation/filesystems/ncpfs.txt [new file with mode: 0644]
MAINTAINERS [new file with mode: 0644]
Makefile
arch/i386/boot/bootsect.S
arch/i386/defconfig
drivers/block/Config.in
drivers/block/Makefile
drivers/block/ll_rw_blk.c
drivers/block/loop.c [new file with mode: 0644]
drivers/block/loop.h [new file with mode: 0644]
drivers/char/Config.in
drivers/char/softdog.c
drivers/char/wdt.c
drivers/net/Makefile
drivers/net/new_tunnel.c [new file with mode: 0644]
drivers/pci/pci.c
drivers/scsi/scsi.c
fs/exec.c
fs/fat/inode.c
fs/inode.c
fs/ncpfs/Makefile
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/ncpfs/inode.c
fs/ncpfs/mmap.c
fs/ncpfs/ncplib_kernel.c
fs/ncpfs/sock.c
fs/nfs/file.c
fs/proc/array.c
fs/proc/base.c
fs/proc/inode.c
include/linux/fs.h
include/linux/interrupt.h
include/linux/kernel.h
include/linux/mm.h
include/linux/msdos_fs_sb.h
include/linux/ncp_fs.h
include/linux/ncp_fs_sb.h
include/linux/ncp_mount.h
include/linux/netdevice.h
include/linux/pci.h
include/linux/proc_fs.h
include/linux/scc.h
include/linux/sched.h
include/net/ax25.h
include/net/sock.h
kernel/ksyms.c
mm/filemap.c
mm/memory.c
net/ax25/af_ax25.c
net/ax25/ax25_in.c
net/ax25/ax25_out.c
net/ax25/ax25_route.c
net/ax25/ax25_subr.c
net/ax25/ax25_timer.c
net/core/dev.c
net/core/net_alias.c
net/core/sock.c
net/ipv4/af_inet.c
net/ipv4/igmp.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_output.c
net/ipv4/timer.c
net/ipx/af_ipx.c
net/netrom/af_netrom.c
net/netrom/nr_dev.c
net/netrom/nr_out.c
net/netrom/nr_route.c
net/netrom/nr_subr.c
net/unix/af_unix.c
scripts/Configure
scripts/Menuconfig

index 40838d1ac5859fadb22f2e782825ca3512e5aa3c..769a190c2cc4dde1c5c6a7ae2c78d659a3f90230 100644 (file)
@@ -4,24 +4,32 @@
 # corresponds to the kernel versions 1.3.x. Be aware that these
 # are development kernels.
 #
-# The latest version of these help texts is always available from
-#    http://math-www.uni-paderborn.de/~axel/config_help.html
-#
 # 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
 # /pub/Linux/docs/HOWTO. 
 #
-# Format: description<nl>variable<nl>helptext<nl><nl>. The help texts
+# Format of this file: description<nl>variable<nl>helptext<nl><nl>. 
+# If the question being documented is of type "choice", we list
+# only the first occuring config variable. The help texts
 # must not contain empty lines. No variable should occur twice; if it
 # does, only the first occurance will be used by Configure. The lines
 # in a help text should be indented two positions. Lines starting with
-# `#' are ignored. Use emacs' kfill.el to edit this file or you lose.
+# `#' are ignored. To be nice to menuconfig, limit your lines to 70
+# chars. Use emacs' kfill.el to edit this file or you lose.
+#
+# If you add a help text to this file, please try to be as gentle as
+# possible. Don't use unexplained acronyms and generally write for the
+# hypothetical user who has just bought a PC, removed Windows,
+# installed Linux and is now recompiling the kernel for the first
+# time. Tell them what to do if they're unsure. Technical information
+# should go in a README in the Documentation directory. Mention all 
+# the relevant READMEs in the help text.
 #
 # All this was shamelessly stolen from several different sources. Many
 # thanks to all the contributors.  Feel free to use these help texts
 # in your own kernel configuration tools. The texts are copyrighted
-# (c) 1995 by Axel Boldt and governed by the GNU Public License.
+# (c) 1995,1996 by Axel Boldt and governed by the GNU Public License.
 #
 # Send comments to Axel Boldt <boldt@math.ucsb.edu>.
 
@@ -30,21 +38,21 @@ CONFIG_MATH_EMULATION
   Linux can emulate a math coprocessor (used for floating point
   operations) if you don't have one. 486DX and Pentium processors have
   a math coprocessor built in, 486SX and 386 do not, unless you added
-  a 487DX or 387, respectively.  (The messages during boot time can give
-  you some hints here ["man dmesg"]) Everyone needs either a coprocessor or
-  this emulation. If you enable this emulation even though you have a
-  coprocessor, the coprocessor will be used nevertheless. (This
-  behavior can be changed with the kernel command line option
-  "no387", which comes handy if your coprocessor is broken. See the
-  documentation of your boot loader (lilo or loadlin) about how to
-  pass options to the kernel. The lilo procedure is also explained in
-  the SCSI-HOWTO, available via ftp (user: anonymous) in
-  sunsite.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 arch/i386/math-emu/README. If
-  you are not sure, say Y; apart from resulting in a 45kB bigger
-  kernel, it won't hurt.
+  a 487DX or 387, respectively.  (The messages during boot time can
+  give you some hints here ["man dmesg"]) Everyone needs either a
+  coprocessor or this emulation. If you enable this emulation even
+  though you have a coprocessor, the coprocessor will be used
+  nevertheless. (This behavior can be changed with the kernel command
+  line option "no387", which comes handy if your coprocessor is
+  broken. See the documentation 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 sunsite.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
+  arch/i386/math-emu/README. If you are not sure, say Y; apart from
+  resulting in a 45kB bigger kernel, it won't hurt.
 
 Normal floppy disk support
 CONFIG_BLK_DEV_FD
@@ -70,6 +78,15 @@ CONFIG_BLK_DEV_RAM
   Most normal users won't need the RAM disk functionality, and can thus say 
   N here.
 
+Loop device support
+CONFIG_BLK_DEV_LOOP
+  Enabling this option will allow you to mount a file as a file system.
+  This is useful if you want to check an ISO9660 file system before
+  burning the CD, or want to use floppy images without first writing
+  them to floppy.
+  This option also allows one to mount a filesystem with encryption.
+  Most users will answer N here.
+
 Enhanced IDE/MFM/RLL disk/cdrom/tape support
 CONFIG_BLK_DEV_IDE 
   This will use the full-featured IDE driver to control up to four IDE
@@ -135,45 +152,48 @@ CONFIG_BLK_DEV_IDETAPE
 
 CMD640 chipset bugfix/support
 CONFIG_BLK_DEV_CMD640
-  The CMD-Technologies CMD640 chip is used on many common 486 and Pentium
-  motherboards, usually in combination with a "Neptune" or "SiS" chipset.
-  Unfortunately, it has a number of rather nasty design flaws that can cause
-  severe data corruption under many common conditions.  Say Y here to include
-  code which tries to automatically detect and correct the problems under Linux.
-  This also provides support for the enhanced features of the CMD640,
-  for improved support/operation under linux, including access to the secondary
-  IDE ports in some systems.  This driver will work automatically in PCI
-  based systems (most new systems have PCI slots).  But if your system uses
-  VESA local bus (VLB) instead of PCI, you must also supply a kernel boot
-  parameter to enable the CMD640 bugfix/support:  "ide0=cmd640_vlb"
-  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.
+  The CMD-Technologies CMD640 chip is used on many common 486 and
+  Pentium motherboards, usually in combination with a "Neptune" or
+  "SiS" chipset.  Unfortunately, it has a number of rather nasty
+  design flaws that can cause severe data corruption under many common
+  conditions.  Say Y here to include code which tries to automatically
+  detect and correct the problems under Linux.  This also provides
+  support for the enhanced features of the CMD640, for improved
+  support/operation under linux, including access to the secondary IDE
+  ports in some systems.  This driver will work automatically in PCI
+  based systems (most new systems have PCI slots).  But if your system
+  uses VESA local bus (VLB) instead of PCI, you must also supply a
+  kernel boot parameter to enable the CMD640 bugfix/support:
+  "ide0=cmd640_vlb" 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. If unsure, say Y.
 
 RZ1000 chipset bugfix/support
 CONFIG_BLK_DEV_RZ1000
-  The PC-Technologies RZ1000 chip is used on many common 486 and Pentium
-  motherboards, usually along with the "Neptune" chipset.  Unfortunately,
-  it has a rather nasty design flaw that can cause severe data corruption
-  under many conditions.  Say Y here to include code which automatically
-  detects and corrects the problem under Linux.  This may slow disk throughput
-  by a few percent, but at least things will operate 100% reliably.
+  The PC-Technologies RZ1000 chip is used on many common 486 and
+  Pentium motherboards, usually along with the "Neptune" chipset.
+  Unfortunately, it has a rather nasty design flaw that can cause
+  severe data corruption under many conditions.  Say Y here to include
+  code which automatically detects and corrects the problem under
+  Linux.  This may slow disk throughput by a few percent, but at least
+  things will operate 100% reliably. If unsure, say Y.
 
 Other IDE chipset support
 CONFIG_IDE_CHIPSETS
-  Say Y here if you want to include enhanced support for various
-  IDE interface chipsets used on motherboards and add-on cards.
-  This enhanced support may be necessary for linux to be able to access
-  the 3rd/4th drives in some systems.  It may also enable setting of
-  higher speed I/O rates to improve system performance with these chipsets.
-  Most of these also require special kernel boot parameters to actually
-  turn on the support at runtime.
+  Say Y here if you want to include enhanced support for various IDE
+  interface chipsets used on motherboards and add-on cards.  This
+  enhanced support may be necessary for linux to be able to access the
+  3rd/4th drives in some systems.  It may also enable setting of
+  higher speed I/O rates to improve system performance with these
+  chipsets.  Most of these also require special kernel boot parameters
+  to actually turn on the support at runtime.
 
 DTC-2278 chipset support
 CONFIG_BLK_DEV_DTC2278
   This driver is enabled at runtime using the "ide0=dtc2278" kernel
   boot parameter.  It enables support for the secondary IDE interface
-  of the DTC-2278 card, and permits faster I/O speeds to be set as well.
-  See the README.ide and dtc2278.c files for more info.
+  of the DTC-2278 card, and permits faster I/O speeds to be set as
+  well.  See the README.ide and dtc2278.c files for more info.
 
 Holtek HT6560B chipset support
 CONFIG_BLK_DEV_HT6560B
@@ -207,51 +227,95 @@ CONFIG_BLK_DEV_XD
   Very old 8 bit hard disk controllers used in the IBM XT
   computer. Pretty unlikely that you have this: say N.
 
+Support for Deskstation RPC44 
+CONFIG_DESKSTATION_RPC44
+  This is a machine with a R4400 100 MHz CPU. To compile a Linux
+  kernel that runs on these, say Y here. For details about Linux
+  on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+  http://lena.fnet.fr/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic).
+
+Support for Mips Magnum 3000 
+CONFIG_MIPS_MAGNUM_3000
+  To compile a Linux kernel that runs on these, say Y here. For
+  details about Linux on the MIPS architecture, check out the
+  Linux/MIPS FAQ on the WWW at http://lena.fnet.fr/ (To browse the
+  WWW, you need to have access to a machine on the Internet that has
+  one of the programs lynx, netscape or Mosaic).
+
+Support for Mips Magnum 4000
+CONFIG_MIPS_MAGNUM_4000
+  This is a machine with a R4000 100 MHz CPU. To compile a Linux
+  kernel that runs on these, say Y here. For details about Linux
+  on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+  http://lena.fnet.fr/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic).
+
+Support for Olivetty M700
+CONFIG_OLIVETTI_M700
+  This is a machine with a R4000 100 MHz CPU. To compile a Linux
+  kernel that runs on these, say Y here. For details about Linux
+  on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+  http://lena.fnet.fr/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic).
+
 Support for Deskstation Tyne
 CONFIG_DESKSTATION_TYNE
-#####
-##### Anyone have details? It's for the MIPS architecture.
-#####
+  This is a machine with a R4600 134 MHz CPU. The Linux port for this
+  system is idle right now because of hardware or documentation
+  problems. For details about Linux on the MIPS architecture, check
+  out the Linux/MIPS FAQ on the WWW at http://lena.fnet.fr/ (To browse
+  the WWW, you need to have access to a machine on the Internet that
+  has one of the programs lynx, netscape or Mosaic).
 
 Support for Acer PICA 1 chipset
 CONFIG_ACER_PICA_61
-#####
-##### Anyone have details? It's for the MIPS architecture.
-#####
+  This is a machine with a R4400 134/150 MHz CPU. To compile a Linux
+  kernel that runs on these, say Y here. For details about
+  Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the
+  WWW at http://lena.fnet.fr/ (To browse the WWW, you need to have
+  access to a machine on the Internet that has one of the programs
+  lynx, netscape or Mosaic).
 
 Support for DECstation
 CONFIG_DECSTATION
-#####
-##### Anyone have details? It's for the MIPS architecture.
-#####
-
-Generate code for R4x00
-CONFIG_R4X00
-  If your computer uses the 64 bit R4X00 processor (as opposed to the
-  32 bit R3000), you need to say Y here, otherwise N. Note that these
-  processors are not compatible and the kernel can only work on the
-  processor type it was compiled for.
+  The DECStation 3100 (with a MIPS R2000 series CPU) and DECStation
+  5000/xxx (MIPS R3000 series CPU) are also sometimes labeled
+  PMAX. They often run the Ultrix operating system. To compile a Linux
+  kernel that runs on these, say Y here. For details about Linux
+  on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+  http://lena.fnet.fr/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic).
+
+CPU type
+CONFIG_CPU_R3000
+  Give the type of your machine's MIPS CPU. For this question,
+  it suffices to give a unique prefix of the option you want to
+  choose. 
 
 Networking support
 CONFIG_NET
   Unless you really know what you are doing, you should say Y
   here. The reason is that some programs need it even if you configure
   a stand-alone machine that won't be connected to any other computer.
-  If you have recently upgraded from an older kernel, you should
-  consider updating your networking tools too; read net/README for
-  details. 
+  from an older kernel, you should consider updating your networking
+  tools too; read net/README for details.
 
 Network aliasing
 CONFIG_NET_ALIAS
-  This is for setting several network addresses on the same low-level network
-  device driver. Typically used for services that act differently based
-  on the address they listen on (e.g. Apache httpd) or for connecting to
-  different logical networks through the same physical interface.
-  This is the generic part, later when configuring network protocol
-  options you will be asked for protocol-specific aliasing support.
-  See Documentation/networking/alias.txt for more info.
-  If you need this features (for any protocol, like IP) say Y; if unsure, 
-  say N.  
+  This is for setting several network addresses on the same low-level
+  network device driver. Typically used for services that act
+  differently based on the address they listen on (e.g. Apache httpd)
+  or for connecting to different logical networks through the same
+  physical interface.  This is the generic part, later when
+  configuring network protocol options you will be asked for
+  protocol-specific aliasing support.  See
+  Documentation/networking/alias.txt for more info.  If you need this
+  features (for any protocol, like IP) say Y; if unsure, say N.
 
 Network firewalls
 CONFIG_FIREWALL
@@ -269,67 +333,73 @@ CONFIG_BLK_DEV_SUNFD
 
 Alpha system type
 CONFIG_ALPHA_AVANTI
-  Find out what type of Alpha motherboard you have. If you can't
-  find one of the given names, then try "Noname". For this question,
-  it suffices to give a unique prefix of the option you want to
-  choose. 
+  Find out what type of Alpha motherboard you have. You will probably
+  want to read the Linux/Alpha homepage on the WWW at
+  http://www.azstarnet.com/~axplinux/ (To browse the WWW, you need to
+  have access to a machine on the Internet that has one of the
+  programs lynx, netscape or Mosaic). 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)
+     and XL (a.k.a. "Windows NT Dream Machine" :-) AlphaStations.
+     These usually come with a TGA graphics adaptor, so you'll want to
+     say Y to "TGA Console support", below, if you have one of these.
+  ** Jensen: a.k.a. DEC 2000 a.k.a. DECpc AXP 150, the oldest Alpha
+     PC; it sports an EISA bus. The boot process on Jensen machines is
+     difficult (no booting from floppies, MILO doesn't work). You need
+     to have access to a second Linux workstation. The Linux/Alpha
+     FAQ, accessible from the above mentioned WWW page, has details.
+  ** Noname: a.k.a. AXPpci33, a PCI-bus based board using the 21066
+     Alpha CPU, running at either 166 or 233 MHz. You also want to
+     choose this option if you have a UDB (Universal Desktop Box
+     a.k.a. Multia) machine.
+  ** Cabriolet: also called AlphaPC64, a PCI-bus based board using the
+     21064 Alpha CPU typically running at 275 or 300 MHz.
+  ** EB66: "Evaluation Board"
+  ** EB66+: "Evaluation Board"
+###
+### Add info about Platform2000
+###
 
 Limit memory to low 16MB
 CONFIG_MAX_16M
   This is for some buggy motherboards which cannot properly deal with
   the memory above 16MB. If you have more than 16MB of RAM and
   experience weird problems, you might want to try Y, everyone else
-  says N. Note for machines with more than 64MB of RAM: in order for the
-  kernel to be able to use the memory above 64MB, pass the command
-  line option "mem=XXXM" (where XXX is the memory size in
-  megabytes) to your kernel. See the documentation of your boot loader
-  (lilo or loadlin) about how to pass options to the kernel. The lilo
-  procedure is also explained in the SCSI-HOWTO, available via ftp
-  (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.
-  You also need at least 512kB of RAM cache if you have more than 64MB
-  of RAM.
-  Some other things to try when experiencing seemingly random, "weird"
-  problems: 1) passing the "no-hlt" option to the kernel 2) passing
-  the "no-387" option to the kernel 3) passing the "mem=4M" option to
-  the kernel (will disable all but the first 4M of RAM) 4) disabling
-  the cache from your BIOS settings 5) exchanging RAM chips 6)
-  exchanging the motherboard 7) committing suicide.
+  says N. Note for machines with more that 64MB of RAM: in order for
+  the kernel to be able to use the memory above 64MB, pass the command
+  line option "mem=XXXM" (where XXX is the memory size in megabytes)
+  to your kernel during boot time. See the documentation of your boot
+  loader (lilo or loadlin) about how to pass options to the
+  kernel. The lilo procedure is also explained in the SCSI-HOWTO,
+  available via ftp (user: anonymous) in
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  You also need at least 512kB
+  of RAM cache if you have more than 64MB of RAM.  Some other things
+  to try when experiencing seemingly random, "weird" problems: 1)
+  passing the "no-hlt" option to the kernel 2) passing the "no-387"
+  option to the kernel 3) passing the "mem=4M" option to the kernel
+  (thereby disabling all but the first 4M of RAM) 4) disabling the
+  cache from your BIOS settings 5) exchanging RAM chips 6) exchanging
+  the motherboard 7) committing suicide.
 
 Using SRM as bootloader
 CONFIG_ALPHA_SRM
-  This selects whether the Linux kernel on an Alpha machines is being
-  booted through SRM (the DEC Unix firmware).  If you use MILO, answer
-  "no" here.  Except for Cabriolet and some other evaluation-board based
-  machines, this option has no effect and can be set to either value
-  with no ill effects.
-
-Kernel KGDB support
-CONFIG_KGDB
-  Selects whether kernel debugging via serial line should be enabled.
-  Enable this option only if you really plan on debugging the Linux
-  kernel.  If you enable this option, take a look at
-  arch/alpha/kernel/kgdb.c and search for SERIAL_LINE to find out
-  what serial port the kernel will use (either /dev/ttyS0 or
-  /dev/ttyS1).  Then, hook up a serial line to another machine
-  (must be another 64-bit machine when debugging a 64-bit kernel)
-  and start "gdb vmlinux" on that machine.  Then boot the kernel on
-  the target system with boot option "kgdb".  The kernel will display:
-     kgdb: stealing /dev/ttyS0 and initializing it to 38400 baud
-     kgdb: waiting for gdb to connect...
-  At this point, enter the following commands on the system running
-  gdb:
-     gdb> set remotebaud 38400
-     gdb> set target remote /dev/<whatever>
-  After a few seconds, gdb should respond with the usual prompt, showing
-  the source at which the kernel is currently executing.  You can now
-  use the normal gdb features such as breakpoints to debug the kernel.
-  WARNING: when CONFIG_KGDB is enabled, send a Ctrl-C character over
-  the serial line will drop the kernel into the debugger!
-
-Kernel tracing support
-CONFIG_KGDB_TRACING
-  Enabling this option allows to collect kernel execution traces.  Don't
-  try this at home!
+  There are two different types of booting firmware on Alphas: SRM,
+  which is command line driven, and ARC, which uses menus and arrow
+  keys. The usual way to load Linux on an Alpha machine is to use MILO
+  (a bootloader that lets you pass command line parameters to the
+  kernel just like LILO does) which can be loaded either from ARC or
+  can be installed directly as a permanent firmware replacement from
+  floppy (which requires changing a certain jumper on the
+  motherboard). If you want to do either of these, say N here. If MILO
+  doesn't work on your system (true for Jensen motherboards), you can
+  bypass it altogether and boot Linux directly from an SRM console;
+  say Y here in order to do that. Note that you won't be able to boot
+  from an IDE disk using SRM. If unsure, say N. Details about the
+  Linux/Alpha booting process are contained in the Linux/Alpha FAQ,
+  accessible on the WWW from http://www.azstarnet.com/~axplinux/ (To
+  browse the WWW, you need to have access to a machine on the Internet
+  that has one of the programs lynx, netscape or Mosaic).
 
 Echo console messages on /dev/ttyS1
 CONFIG_SERIAL_ECHO
@@ -340,26 +410,29 @@ CONFIG_SERIAL_ECHO
 
 TGA Console Support
 CONFIG_TGA_CONSOLE
-  Many Alpha systems are shipped with a graphics card that implements the
-  TGA interface (much like the VGA standard, but older TGA adaptors are
-  *not* VGA compatible).  On such systems, this option needs to be enabled
-  such that the TGA driver rather than the standard VGA driver is used.
+  Many Alpha systems (e.g the Multia) are shipped with a graphics card
+  that implements the TGA interface (much like the VGA standard, but
+  older TGA adaptors are *not* VGA compatible).  On such systems, this
+  option needs to be enabled so that the TGA driver rather than the
+  standard VGA driver is used.  Note that, at this time, there is no X
+  server for these systems. If unsure, try N.
 
 PCI bios support
 CONFIG_PCI
   Find out whether you have a PCI motherboard. PCI is the name of a
   bus system, i.e. the way the CPU talks to the other stuff inside
-  your box. Other bus systems are ISA, EISA, Microchannel or VESA. If
-  you have PCI, say Y, otherwise N. Note: some old PCI motherboards
-  have BIOS bugs and may crash if this is enabled (but they run fine
-  without this option). The PCI-HOWTO, available via ftp (user:
-  anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO, contains
-  valuable information about which PCI hardware works under Linux and
-  which doesn't.  If some of your PCI devices don't work and you get a
-  warning during boot time ("man dmesg"), please follow the instructions 
-  at the top of include/linux/pci.h. The buggy PCTech RZ 1000 IDE
-  harddrive controller which is used in some PCI systems is detected
-  and correctly handled by this driver.
+  your box. Other bus systems are ISA, EISA, Microchannel (MCA) or
+  VESA. If you have PCI, say Y, otherwise N. Note1: MCA systems are
+  not supported by the standard kernels, but patches exist at
+  http://www.undergrad.math.uwaterloo.ca/~cpbeaure/mca-linux.html on
+  the WWW. Note2: some old PCI motherboards have BIOS bugs and may
+  crash if "PCI bios support" is enabled (but they run fine without
+  this option). The PCI-HOWTO, available via ftp (user: anonymous) in
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO, contains valuable information
+  about which PCI hardware does work under Linux and which doesn't.
+  If some of your PCI devices don't work and you get a warning during
+  boot time ("man dmesg"), please follow the instructions at the top
+  of include/linux/pci.h. 
 
 PCI bridge optimization (experimental)
 CONFIG_PCI_OPTIMIZE
@@ -369,14 +442,13 @@ CONFIG_PCI_OPTIMIZE
 
 Intel 430FX (Triton) chipset DMA support
 CONFIG_BLK_DEV_TRITON
-  This option is valid only if PCI BIOS support was also selected earlier.
   If your PCI system uses an IDE harddrive (as opposed to SCSI, say)
-  and includes the Intel 430FX PCI Triton chipset, you will want
-  to enable this option to allow use of bus-mastering DMA data transfers.
-  Read the comments at the beginning of drivers/block/triton.c.
-  The hdparm utility can be obtained via ftp (user: anonymous)
-  from sunsite.unc.edu:/pub/Linux/kernel/patches/diskdrives/.
-  It is safe to say Y.
+  and includes the Intel 430FX PCI Triton chipset, you will want to
+  enable this option to allow use of bus-mastering DMA data transfers.
+  Read the comments at the beginning of drivers/block/triton.c.  The
+  hdparm utility can be obtained via ftp (user: anonymous) from
+  sunsite.unc.edu:/pub/Linux/kernel/patches/diskdrives/.  It is safe
+  to say Y.
 
 System V IPC
 CONFIG_SYSVIPC
@@ -404,14 +476,15 @@ CONFIG_BINFMT_ELF
   (this does *not* mean that you will be able to run executables from
   different architectures or operating systems!) and makes building
   run-time libraries very easy. Many new executables are distributed
-  solely in ELF format. You definitely want to say Y here. Information about
-  ELF is on the WWW at http://www.sjc.ox.ac.uk/users/barlow/elf-howto.html
-  (To browse the WWW, you need to have access to a machine on the
-  Internet that has one of the programs lynx, netscape or Mosaic).  If
-  you find that after upgrading to Linux kernel 1.3 and saying Y here,
-  you still can't run any ELF binaries (they just crash), then you'll
-  have to install the newest ELF runtime libraries, including ld.so
-  (available via ftp (user: anonymous) from
+  solely in ELF format. You definitely want to say Y here. Information
+  about ELF is on the WWW at
+  http://www.sjc.ox.ac.uk/users/barlow/elf-howto.html (To browse the
+  WWW, you need to have access to a machine on the Internet that has
+  one of the programs lynx, netscape or Mosaic).  If you find that
+  after upgrading to Linux kernel 1.3 and saying Y here, you still
+  can't run any ELF binaries (they just crash), then you'll have to
+  install the newest ELF runtime libraries, including ld.so (available
+  via ftp (user: anonymous) from
   tsx-11.mit.edu:/pub/linux/packages/GCC). Also note that ELF binary
   support was broken in kernel versions 1.3.0 - 1.3.2. Either use a
   newer 1.3 kernel or one of the stable 1.2 versions. If you want to
@@ -450,13 +523,34 @@ CONFIG_BINFMT_AOUT
 Processor type
 CONFIG_M386
   This is the processor type of your CPU. It is used for optimizing
-  purposes. In order to compile a kernel that can run on all three CPU
-  types (albeit not optimally fast), you can specify "386" here.  If
-  you specify "486" or "Pentium", then the kernel will run on
-  both 486 and Pentium CPUs. In rare cases, it can make sense to
-  specify "Pentium" here even if running a 486: the kernel will be
-  smaller but slower.
-  
+  purposes. In order to compile a kernel that can run on all CPU types
+  (albeit not optimally fast), you can specify "386" here.  If you
+  specify "486" or "Pentium" or "PPro", then the kernel will run on
+  486 and Pentium (=586) and Pentium Pro (=686) CPUs. In rare cases,
+  it can make sense to specify "Pentium" even if running a 486: the
+  kernel will be smaller but slower.
+
+Compile the kernel into the ELF object format 
+CONFIG_ELF_KERNEL
+  ELF (Executable and Linkable Format) is a format for libraries and
+  executables used across different architectures and operating
+  systems. This option will cause the resulting kernel to be in ELF
+  format, which is generally desirable, so say Y. However, it only
+  works if your compiler and linker can produce ELF code.
+
+Is your ELF compiler an extra compiler
+CONFIG_EXTRA_ELF_COMPILER
+  If you have a linuxelf-gcc as opposed to linux-gcc, say Y, otherwise
+  N.
+
+Generate little endian code
+CONFIG_CPU_LITTLE_ENDIAN
+  If your compiler is mipsel-linux-gcc or mipsel-linuxelf-gcc (as
+  opposed to mips-linux-gcc or mips-linuxelf-gcc), say Y here,
+  otherwise N. Most MIPS machines use little-endian code, but it might
+  be necessary to run older Mips sytems, such as the Sony News and
+  MIPS RC3xxx in big endian mode.
+
 Enable loadable module support
 CONFIG_MODULES
   Kernel modules are small pieces of compiled code which can be 
@@ -469,13 +563,13 @@ CONFIG_MODULES
 
 Set version information on all symbols for modules
 CONFIG_MODVERSIONS
-  Usually, modules have to be recompiled whenever you
-  switch to a new kernel. Enabling this option allows you
-  to keep using the same modules even after compiling a new kernel;
-  this requires the program modprobe. All the software needed for
-  module support is in the modules package in
-  sunsite.unc.edu:/pub/Linux/kernel, available via ftp (user:
-  anonymous). NOTE1: if you say Y here but don't have the program
+  Usually, modules have to be recompiled whenever you switch to a new
+  kernel. Enabling this option allows you to keep using the same
+  modules even after compiling a new kernel; this requires the program
+  modprobe. All the software needed for module support is in the
+  modules package in sunsite.unc.edu:/pub/Linux/kernel, available via
+  ftp (user: anonymous) and to be extracted with "tar xzvf
+  filename". NOTE1: if you say Y here but don't have the program
   genksyms (which is also contained in the above mentioned modules
   package), then the building of your kernel will fail. NOTE2: if you
   say Y here, then you cannot say Y to the PPP driver, below; the only
@@ -488,7 +582,7 @@ CONFIG_KERNELD
   to be created as loadable modules, you also have the responsibility
   to load the corresponding module (via insmod/modprobe) before you
   use it.  If you select Y here, the kernel will take care of this
-  all by itself, together with a user level daemon, "kerneld".
+  all by itself, together with a user level daemon; "kerneld".
   Note that "kerneld" will also automatically unload all unused
   modules, so you don't have to use "rmmod" either.
   There are some other "kernel callouts" that will be available
@@ -745,21 +839,21 @@ CONFIG_SKB_LARGE
 
 The IPX protocol
 CONFIG_IPX
-  This is support for the Novell networking protocol, IPX. You need it
-  if you want to access Novell Netware servers by using the Linux
-  Novell client ncpfs (available via ftp (user: anonymous) from 
-  sunsite.unc.edu:/pub/Linux/system/Filesystem/) or from within the 
+  This is support for the Novell networking protocol, IPX, commonly
+  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
+  sunsite.unc.edu:/pub/Linux/system/Filesystems/) or from within the
   Linux DOS emulator dosemu (read the DOSEMU-HOWTO, available in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO). To turn your Linux box into
-  a fully featured Netware file server and IPX router, say Y here and
-  fetch lwared from
-  sunsite.unc.edu:/pub/Linux/system/Networking/daemons/. General
-  information about how to connect Linux, Windows machines and Macs is
-  on the WWW at http://eats.com/linux_mac_win.html (to browse the WWW,
-  you need to have access to a machine on the Internet that has one of
-  the programs lynx, netscape or Mosaic). This driver would enlarge
-  your kernel by about 5 kB. Unless you have Novell computers on your
-  local network, say N.
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO). In order to do the former,
+  you'll also have to say Y to "NCP filesystem support", below. To
+  turn your Linux box into a fully featured Netware file server and
+  IPX router, say Y here and fetch lwared from
+  sunsite.unc.edu:/pub/Linux/system/Network/daemons/. For more
+  information, read the IPX-HOWTO in
+  sunsite.unc.edu:/pub/Linux/docs/howto. The IPX driver would enlarge
+  your kernel by about 5 kB. Unless you want to integrate your Linux
+  box with a local Novell network, say N.
 
 Full internal IPX network
 CONFIG_IPX_INTERN
@@ -775,6 +869,7 @@ CONFIG_IPX_INTERN
   primary network is disabled. This might break existing applications,
   especially RIP/SAP daemons. A RIP/SAP daemon that works well with the
   full internal net can be found on linux01.gwdg.de:/pub/ncpfs.
+  If you don't know what you are doing, say N.
 
 Appletalk DDP
 CONFIG_ATALK
@@ -934,6 +1029,15 @@ CONFIG_SCSI_CONSTANTS
   understand if you enable this; it will enlarge your kernel by about
   12KB. If in doubt, say Y.
 
+AdvanSys SCSI support
+CONFIG_SCSI_ADVANSYS
+  This is a driver for all SCSI host adaptors manufactured by
+  AdvanSys. It is documented in the kernel source in
+  drivers/scsi/advansys.c. This driver is also available as a module (
+  = code which can be inserted in and removed from the running kernel
+  whenever you want). If you want to compile it as a module, say M
+  here and read Documentation/modules.txt.
+
 Adaptec AHA152X support
 CONFIG_SCSI_AHA152X
   This is support for an SCSI host adaptor. It is explained in section
@@ -980,14 +1084,14 @@ CONFIG_SCSI_AIC7XXX
 
 BusLogic SCSI support
 CONFIG_SCSI_BUSLOGIC
-  This is support for BusLogic MultiMaster SCSI Host Adaptors.  Consult
-  the documentation in drivers/scsi/README.BusLogic for more information.
-  BusLogic FlashPoint SCSI Host Adapters are not supported by this driver.
-  If this driver does not work correctly without modification, please
-  consult the author.  This driver may also be built as a module, but
-  only a single instance may be loaded.  You might also want to read
-  the SCSI-HOWTO, available via anonymous ftp from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  This is support for BusLogic MultiMaster SCSI Host Adaptors.
+  Consult the documentation in drivers/scsi/README.BusLogic for more
+  information.  BusLogic FlashPoint SCSI Host Adapters are not
+  supported by this driver.  If this driver does not work correctly
+  without modification, please consult the author.  This driver may
+  also be built as a module, but only a single instance may be loaded.
+  You might also want to read the SCSI-HOWTO, available via anonymous
+  ftp from sunsite.unc.edu:/pub/Linux/docs/HOWTO.
  
 EATA-DMA (DPT,NEC&ATT for ISA,EISA,PCI) support
 CONFIG_SCSI_EATA_DMA
@@ -1028,17 +1132,18 @@ CONFIG_SCSI_U14_34F
 Future Domain 16xx SCSI support
 CONFIG_SCSI_FUTURE_DOMAIN
   This is support for Future Domain's 16-bit SCSI host adaptors
-  (TMC-1660/1680, TMC-1650/1670, TMC-3260) and other adaptors based on the
-  Future Domain chipsets (Quantum ISA-200S, ISA-250MG; and at least one IBM
-  board).  It is explained in section 3.7 of the SCSI-HOWTO, available via
-  ftp (user: anonymous) at sunsite.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/fdomain.h. This driver is also available as a module ( =
-  code which can be inserted in and removed from the running kernel
-  whenever you want). If you want to compile it as a module, say M here and
-  read Documentation/modules.txt.
+  (TMC-1660/1680, TMC-1650/1670, TMC-3260) and other adaptors based on
+  the Future Domain chipsets (Quantum ISA-200S, ISA-250MG; and at
+  least one IBM board).  It is explained in section 3.7 of the
+  SCSI-HOWTO, available via ftp (user: anonymous) at
+  sunsite.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/fdomain.h. This driver is also available as a module (
+  = code which can be inserted in and removed from the running kernel
+  whenever you want). If you want to compile it as a module, say M
+  here and read Documentation/modules.txt.
 
-Generic NCR5380 SCSI support
+Generic NCR5380/53c400 SCSI support
 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
@@ -1050,6 +1155,22 @@ CONFIG_SCSI_GENERIC_NCR5380
   kernel whenever you want). If you want to compile it as a module,
   say M here and read Documentation/modules.txt.
  
+Enable NCR53c400 extensions
+CONFIG_SCSI_GENERIC_NCR53C400
+  This enables certain optimizations for the NCR53c400 scsi cards. You
+  might as well try it out. Note that this driver will only probe for
+  the Trantor T130B in its default configuration; you might have to
+  pass a command line option to the kernel at boot time if it doesn't
+  detect your card. See the file drivers/scsi/README.g_NCR5380 for
+  details. If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.
+
+NCR5380/53c400 mapping method (use Port for T130B)
+CONFIG_SCSI_G_NCR5380_PORT
+  The NCR5380 and NCR53c400 SCSI controllers come in two varieties:
+  port or memory mapped. You should know what you have. The most
+  common card, Trantor T130B, uses port mapped mode.
+
 NCR53c7,8xx SCSI support
 CONFIG_SCSI_NCR53C7xx
   This is the 53c7 and 8xx NCR family of SCSI controllers, not to be
@@ -1146,6 +1267,23 @@ CONFIG_SCSI_EATA
   running kernel whenever you want), say M here and read
   Documentation/modules.txt.
 
+NCR53c406a SCSI support
+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 sunsite.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), say M here
+  and read Documentation/modules.txt.
+
+AM53/79C974 PCI SCSI support
+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
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO, is for you.
+
 Network device support?
 CONFIG_NETDEVICES
   You can say N here in case you don't intend to connect to any other
@@ -1231,8 +1369,9 @@ CONFIG_SLIP_COMPRESSED
 
 Keepalive and linefill
 CONFIG_SLIP_SMART
-  Adds additional capabilities to the SLIP driver to support the RELCOM
-  line fill and keepalive monitoring. Ideal on poor quality analogue lines.
+  Adds additional capabilities to the SLIP driver to support the
+  RELCOM line fill and keepalive monitoring. Ideal on poor quality
+  analogue lines.
 
 PPP (point-to-point) support
 CONFIG_PPP
@@ -1275,6 +1414,9 @@ CONFIG_SCC
   and communicate with other computers.  If you want to use this, read
   Documentation/networking/z8530drv.txt and the HAM-HOWTO, available via
   ftp (user: anonymous) at sunsite.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),
+  say M here and read Documentation/modules.txt.
 
 PLIP (parallel port) support
 CONFIG_PLIP
@@ -1472,6 +1614,21 @@ CONFIG_EL3
   you may need to use the DOS setup disk to disable Plug & Play mode, and
   to select the default media type.
 
+3c590 series (592/595/597) "Vortex" support
+CONFIG_VORTEX
+  If you have a network (ethernet) card of this type, say Y and read
+  the Ethernet-HOWTO, available via ftp (user: anonymous) in
+  sunsite.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. If you want to compile this
+  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 as well as
+  Documentation/networking/net-modules.txt. If you plan to use more
+  than one network card under linux, read the
+  Multiple-Ethernet-mini-HOWTO, available from
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini
+
 Other ISA cards
 CONFIG_NET_ISA
   If your network (ethernet) card hasn't been mentioned yet and its
@@ -1629,13 +1786,12 @@ CONFIG_PI
 
 Gracilis PackeTwin support
 CONFIG_PT
-  This card is similar to the PI card (mentioned above).  It is used mainly
-  by amateur radio operators for packet radio.  You should have already 
-  said Y to "AX.25 support" as this card uses that protocol. 
-  More information about this driver can be found in the file 
-  drivers/net/README.pt. 
-  NOTE: The card is capable of DMA and full duplex but neither of these have
-  been coded in the driver as yet.
+  This card is similar to the PI card (mentioned above).  It is used
+  mainly by amateur radio operators for packet radio.  You should have
+  already said Y to "AX.25 support" as this card uses that protocol.
+  More information about this driver can be found in the file
+  drivers/net/README.pt.  NOTE: The card is capable of DMA and full
+  duplex but neither of these have been coded in the driver as yet.
 
 WaveLAN support
 CONFIG_WAVELAN
@@ -1790,12 +1946,10 @@ CONFIG_ZNET
 
 Pocket and portable adaptors
 CONFIG_NET_POCKET
-  Cute little network (ethernet) devices which attach to your parallel
-  port ("pocket adaptors"). If you have one of those, say Y and read
-  the Ethernet-HOWTO, available via ftp (user: anonymous) from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you plan to use more than
-  one network card under linux, read the Multiple-Ethernet-mini-HOWTO,
-  available from sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. If you
+  Cute little network (ethernet) devices which attach to the parallel
+  port ("pocket adaptors"), commonly used with laptops. If you have
+  one of those, say Y and read the Ethernet-HOWTO, available via ftp
+  (user: anonymous) from sunsite.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 extension cards
   used by all modern laptops), look in
@@ -1893,12 +2047,12 @@ CONFIG_CD_NO_IDESCSI
 Sony CDU31A/CDU33A CDROM support
 CONFIG_CDU31A
   These CDROM drives have a spring-pop-out caddyless drawer, and a
-  rectangular green LED centered beneath it.
-  NOTE: these CDROM drives will not be auto detected by the kernel at
-  boot time; you have to provide the interface address as an option to
-  the kernel as described in Documentation/cdrom/cdu31a or fill in your
+  rectangular green LED centered beneath it.  NOTE: these CDROM drives
+  will not be auto detected by the kernel at boot time; you have to
+  provide the interface address as an option to the kernel at boot
+  time as described in Documentation/cdrom/cdu31a or fill in your
   parameters into linux/drivers/cdrom/cdu31a.c. See the documentation
-  of your boot loader (lilo or loadlin) about how to pass options to 
+  of your boot loader (lilo or loadlin) about how to pass options to
   the kernel. The lilo procedure is also explained in the SCSI-HOWTO.
 
 Standard Mitsumi [no XA/Multisession] CDROM support
@@ -1928,25 +2082,27 @@ Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support
 CONFIG_SBPCD
   This driver supports most of the drives which use the Panasonic or
   SoundBlaster interface.
-  The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives (sometimes
-  labeled "Creative"), the CreativeLabs CD200, the Longshine LCS-7260,
-  the "IBM External ISA CDROM" (in fact a CR-56x model), the TEAC CD-55A
-  fall under this category. Some other "electrically compatible" drives
-  (Vertos, Genoa, some Funai models) are currently not supported; for the
-  Sanyo H94A drive currently a separate driver (asked later) is responsible.
-  Most drives have a uniquely shaped faceplate, with a caddyless motorized
-  drawer, but without external brand markings. The older CR-52x drives have
-  a caddy and manual loading/eject, but still no external markings.
-  The driver is able to do an extended auto-probing for interface addresses
-  and drive types; this can help to find facts in cases you are not sure,
-  but can consume some time during the boot process if none of the supported
-  drives gets found.
+  The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives
+  (sometimes labeled "Creative"), the CreativeLabs CD200, the
+  Longshine LCS-7260, the "IBM External ISA CDROM" (in fact a CR-56x
+  model), the TEAC CD-55A fall under this category. Some other
+  "electrically compatible" drives (Vertos, Genoa, some Funai models)
+  are currently not supported; for the Sanyo H94A drive currently a
+  separate driver (asked later) is responsible.  Most drives have a
+  uniquely shaped faceplate, with a caddyless motorized drawer, but
+  without external brand markings. The older CR-52x drives have a
+  caddy and manual loading/eject, but still no external markings.  The
+  driver is able to do an extended auto-probing for interface
+  addresses and drive types; this can help to find facts in cases you
+  are not sure, but can consume some time during the boot process if
+  none of the supported drives gets found.
   Once your drive got found, you should enter the reported parameters into
   linux/include/linux/sbpcd.h and set "DISTRIBUTION 0" there.
-  This driver can support up to four CDROM interface cards, and each card
-  can support up to four CDROM drives; if you say Y here, you will be asked
-  how many controllers you have. If compiled as a module, only one interface
-  card (but with up to four drives) is usable.
+  This driver can support up to four CDROM interface cards, and each
+  card can support up to four CDROM drives; if you say Y here, you
+  will be asked how many controllers you have. If compiled as a
+  module, only one interface card (but with up to four drives) is
+  usable.
 
 Matsushita/Panasonic, ... second CDROM controller support
 CONFIG_SBPCD2
@@ -1992,7 +2148,7 @@ CONFIG_SJCD
 
 Soft configurable cdrom interface card support
 CONFIG_CDI_INIT
-  If you want to include boot-time intialisation of any cdrom
+  If you want to include boot-time initialization of any cdrom
   interface card that is software configurable, say Y here.
   Currently only the ISP16/MAD16/Mozart cards are supported.
 
@@ -2003,15 +2159,19 @@ CONFIG_ISP16_CDI
   at boot time, please say Y. Boot time command line options (or
   'append=' options in /etc/lilo.conf) are:
                 isp16=<port>,<irq>,<dma>,<drive_type>
-  Here 'port','irq' and 'dma' are the base i/o address, irq number
-  and dma line assumed to be used by the attached cdrom drive. 'drive_type'
-  is the type of cdrom drive or its emulation mode. Valid values for
-  drive_type include: Sanyo, Panasonic (same as Sanyo), Sony and Mitsumi.
-  Default values are: port=0x340, irq=0, dma=0, drive_type=Sanyo.
+
+  Here 'port','irq' and 'dma' are the base i/o address, irq number and
+  dma line assumed to be used by the attached cdrom
+  drive. 'drive_type' is the type of cdrom drive or its emulation
+  mode. Valid values for drive_type include: Sanyo, Panasonic (same as
+  Sanyo), Sony and Mitsumi.  Default values are: port=0x340, irq=0,
+  dma=0, drive_type=Sanyo.
   The command line
                 isp16=noisp16
   will skip detection and configuration after all.
-  N.B. options are case sensitive.
+  N.B. options are case sensitive. 
+  Read Documentation/cdrom/isp16 for details. 
+
 
 Quota support
 CONFIG_QUOTA
@@ -2019,7 +2179,7 @@ CONFIG_QUOTA
   usage (also called diskquotas). Currently, it works only for the
   ext2 filesystem; you need the software available via ftp (user:
   anonymous) from
-  sunsite.unc.edu:/pub/Linux/systm/Admin/quota_acct.tar.gz in order to
+  sunsite.unc.edu:/pub/Linux/system/Admin/quota_acct.tar.gz in order to
   use it. Probably this is only useful for multi user systems. If
   unsure, say N.
 
@@ -2196,19 +2356,19 @@ CONFIG_ROOT_NFS
   some other computer over the net via NFS (presumably because your
   box doesn't have a harddisk), say Y here. You will then have to
   specify the directory that should be remotely mounted with the
-  "root" kernel command line option. See the documentation of your
-  boot loader (lilo or loadlin) about how to pass options to the
-  kernel. The lilo procedure is also explained in the SCSI-HOWTO,
-  available via ftp (user: anonymous) in
+  "root" kernel command line option at boot time. See the
+  documentation of your boot loader (lilo or loadlin) about how to
+  pass options to the kernel. The lilo procedure is also explained in
+  the SCSI-HOWTO, available via ftp (user: anonymous) in
   sunsite.unc.edu:/pub/Linux/docs/HOWTO.) Most people say N here.
 
 ISO9660 cdrom filesystem support
 CONFIG_ISO9660_FS
-  This is the standard filesystem used on CDROMs. It was previously known 
-  as "High Sierra Filesystem" and is called "hsfs" on other Unix systems. 
-  If you have a CDROM drive and want to do more with it than just listen to
-  audio CDs and watch its LEDs, say Y (and read the CDROM-HOWTO,
-  available via ftp (user: anonymous) from
+  This is the standard filesystem used on CDROMs. It was previously
+  known as "High Sierra Filesystem" and is called "hsfs" on other Unix
+  systems.  If you have a CDROM drive and want to do more with it than
+  just listen to audio CDs and watch its LEDs, say Y (and read the
+  CDROM-HOWTO, available via ftp (user: anonymous) from
   sunsite.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 inserted in and removed from the
@@ -2277,14 +2437,15 @@ CONFIG_SMB_FS
 NCP filesystem support (to mount NetWare volumes)
 CONFIG_NCP_FS
   NCP (NetWare Core Protocol) is a protocol that runs over IPX and is
-  used by NetWare clients to talk to file servers. Enabling this
-  allows you to mount NetWare file server volumes and access them just
-  like any other directory. To actually mount the filesystem, you need
-  a special mount program, available on sunsite.unc.edu via anonymous
-  ftp in /pub/Linux/system/Filesystem/ncpfs-xx.tgz. If you want to
-  compile this 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.
+  used by NetWare clients to talk to file servers. It is to IPX what
+  nfs is to tcp/ip, if that helps. Enabling this option allows you to
+  mount NetWare file server volumes and to access them just like any
+  other Unix directory. To actually mount the filesystem, you need a
+  special mount program, as described in the IPX-HOWTO on
+  sunsite.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), say M here and read
+  Documentation/modules.txt.
 
 Cyclades async mux support
 CONFIG_CYCLADES
@@ -2301,21 +2462,24 @@ CONFIG_STALDRV
   Stallion cards give you many serial ports. You would need something
   like this to connect more than two modems to your linux box, for
   instance in order to become a BBS. If you say Y here, you will be
-  asked for your specific card model in the next questions. If you
-  haven't heard about it, it's safe to say N.
+  asked for your specific card model in the next questions. Make sure
+  to read drivers/char/README.stallion in this case. If you have never
+  heard about all this, it's safe to say N.
  
 Stallion EasyIO or EC8/32 support 
 CONFIG_STALLION n
   If you have an EasyIO or EasyConnection 8/32 multiport Stallion
-  card, then this is for you; say Y.  If you want to compile this as a
+  card, then this is for you; say Y. Make sure to read
+  drivers/char/README.stallion. If you want to compile this 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.
 
 CONFIG_ISTALLION n
   If you have an EasyConnection 8/64, ONboard, Brumby or Stallion
-  serial multiport card, say Y here. To compile it as a module ( =
-  code which can be inserted in and removed from the running kernel
+  serial multiport card, say Y here. Make sure to read
+  drivers/char/README.stallion. To compile it 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.
 
 Parallel printer support
@@ -2493,6 +2657,35 @@ CONFIG_WATCHDOG
   after a lock-up. For details, read Documentation/watchdog.txt in the
   kernel source. If unsure, say N.
 
+Disable watchdog shutdown on close
+CONFIG_WATCHDOG_NOWAYOUT
+  The default watchdog behaviour is to stop the timer if the process
+  managing it closes the file. Its always remotely possible that this
+  process might get killed. In NOWAYOUT mode you cannot stop the watchdog
+  once its begun.
+
+WDT Watchdog timer
+CONFIG_WDT
+  Drivers for the WDT watchdog timer cards. These are hardware timer boards
+  that physically pull the power on and off to recover crashed machines.
+  Brutal but _very_ effective.
+
+WDT501 features
+CONFIG_WDT_501
+  Enable the onboard thermometer and voltage monitors on the extended (501)
+  card.
+
+Fan Tachometer
+CONFIG_WDT_501_FAN
+  Enable the Fan Tachometer on the WDT501. Only do this if you have a fan
+  tachometer actually set up.
+
+Software Watchdog
+CONFIG_SOFT_WATDHDOG
+  A software monitoring watchdog. This will fail to reboot your system from
+  some situations that the hardware watchdog will recover from. Equally its
+  a lot cheaper to install.
+
 Do CPU IDLE calls
 CONFIG_APM_CPU_IDLE
   Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.  On
@@ -2599,6 +2792,14 @@ CONFIG_PROFILE_SHIFT
 # LocalWords:  ICL EtherTeam ETH IDESCSI TXC dmesg httpd hlt sjc barlow dlp mtu
 # LocalWords:  thesphere TwoServers BOOTP DHCP ncpfs BPQETHER BPQ chipsets MG
 # LocalWords:  bsd comp Sparcstation le SunOS ie Gracilis PackeTwin PT pt LU FX
-# LocalWords:  FX TEAC SoundBlaster CR CreativeLabs LCS mS
+# LocalWords:  FX TEAC SoundBlaster CR CreativeLabs LCS mS ramdisk IDETAPE cmd
 # LocalWords:  Vertos Genoa Funai hsfs NCP NetWare tgz APM apm ioctls UltraLite
-# LocalWords:  TravelMate CDT LCD backlight VC
+# LocalWords:  TravelMate CDT LCD backlight VC RPC Mips Olivetty DECStation AXP
+# LocalWords:  PMAX MILO Alphas Multia Tseng linuxelf endian mipsel mips drv HT
+# LocalWords:  KERNELD kerneld callouts AdvanSys advansys diskquotas Admin WDT
+# LocalWords:  wdt hdb hdc bugfix SiS vlb Acculogic CSA DTC dtc Holtek ht QDI
+# LocalWords:  QD qd UMC umc ALI ali lena fnet fr homepage azstarnet axplinux
+# LocalWords:  Avanti XL AlphaStations Jensen DECpc AXPpci UDB Cabriolet MCA RC
+# LocalWords:  AlphaPC uwaterloo cpbeaure mca AOUT OUTput PPro sipx gwdg
+# LocalWords:  Keepalive linefill RELCOM keepalive analogue CDR conf CDI INIT
+# LocalWords:  OPTi isp irq noisp VFAT vfat NTFS
diff --git a/Documentation/filesystems/ncpfs.txt b/Documentation/filesystems/ncpfs.txt
new file mode 100644 (file)
index 0000000..0c60ab2
--- /dev/null
@@ -0,0 +1,11 @@
+ncpfs is a filesystem which understands the NCP protocol, designed by the
+Novell Corporation for their NetWare(tm) product. NCP is functionally
+similar to the NFS used in the tcp/ip community.
+To mount a Netware-Filesystem, you need a special mount program, which can
+be found in ncpfs package. Homesite for ncpfs is linux01.gwdg.de/pub/ncpfs,
+but sunsite and its many mirrors will have it as well.
+
+Related products are linware and mars_nwe, which will give Linux partial
+Netware Server functionality.
+Linware's home site is: klokan.sh.cvut.cz/pub/linux/linware,
+Mars_nwe can be found on linux01.gwdg.de/pub/ncpfs.
diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100644 (file)
index 0000000..60b65e1
--- /dev/null
@@ -0,0 +1,107 @@
+               Maintainers And Source Submission Procedures
+
+       In order to keep things easy for the maintainers please try to
+follow the guidelines given. Not all of these guidelines matter for every
+trivial patch so apply some common sense.
+
+1.     Always _test_ your changes however small on at least 4 or 5 people,
+preferably many more.
+
+2.     Try and release a few ALPHA test versions to the net. Announce them
+onto the kernel channel and await results. This is especially important
+for device drivers because often thats the only way you will find things
+like the fact version 3 firmware needs a magic fix you didnt know about, or
+some clown changed the chips on a board and not its name (Don't laugh look
+at the SMC etherpower for that).
+
+3.     Make sure your changes compile correctly in multiple configurations.
+
+4.     When you are happy with a change make it generally available for
+testing and await feedback. 
+
+5.     Make a patch available to the relevant maintainer in the list. Use
+'diff -u' to make the patch easy to merge. Be prepared to get your changes
+sent back with seemingly silly requests about formatting and variable names.
+These aren't as silly as they seem, one job the maintainers (and especially
+Linus) do is to keep things looking the same. Sometimes this means that
+the clever hack in your driver to get around a problem actual needs to
+become a generalised kernel feature ready for next time.
+       PLEASE try and include any credit lines you want added with the
+patch. It avoids people being missed off by mistake and makes it easier to
+know who wants adding and who doesn't.
+       PLEASE Document known bugs. If it doesnt work for everything or
+does something very odd once a month document it.
+
+6.     Make sure you have the right to send any changes you make. If you
+do changes at work you may find your employer owns the patch not you.
+
+7.     Happy hacking
+
+
+[This file is new: I've just put the existing network contacts in, other
+ people please add yourselves] -- AC
+
+               -----------------------------------
+
+Maintainers List (try to look for most precise areas first)
+
+P: Person
+M: Mail patches to
+L: Mailing list that is relevant to this area
+S: Status
+       Supported:      Someone is actually paid to look after this (wildly
+                       improbable).
+       Maintained:     Someone actually looks after it.
+       Odd Fixes:      It has a maintainer but they don't have time to do
+                       much other than throw the odd patch in. See below..
+       Orphan:         No current maintainer [but maybe you could take the 
+                       role as you write your new driver].
+       Obsolete:       Ex code. Something tagged obsolete generally means
+                       its been replaced by a better system and you should
+                       be using that.
+
+3C501 NETWORK DRIVER
+P:     Alan Cox
+M:     net-patches@lxorguk.ukuu.org.uk
+L:     linux-net@vger.rutgers.edu
+S:     Maintained
+
+APPLETALK NETWORK LAYER
+P:     Alan Cox & University Of Michigan
+M:     net-patches@lxorguk.ukuu.org.uk, Cc: netatalk@umich.edu
+L:     [Someone fill in the netatalk list here]
+S:     Maintained
+
+AX.25 NETWORK LAYER
+P:     Jon Naylor
+M:     jsn@cs.nott.ac.uk
+L:     linux-hams@vger.rutges.edu
+S:     Maintained
+
+IPX NETWORK LAYER
+P:     Alan Cox [for the moment]
+M:     net-patches@lxorguk.ukuu.org.uk
+L:     linux-ipx@vger.rutgers.edu [will change]
+S:     Maintained
+
+NETROM NETWORK LAYER
+P:     Jon Naylor
+M:     jsn@cs.nott.ac.uk
+L:     linux-hams@vger.rutges.edu
+S:     Maintained
+
+NETWORKING [GENERAL]:
+P:     Alan Cox
+M:     net-patches@lxorguk.ukuu.org.uk
+L:     linux-net@vger.rutgers.edu
+S:     Odd Fixes <-> Maintained subject to workloads
+
+SMP:
+P:     Alan Cox
+M:     smp-patches@lxorguk.ukuu.org.uk
+L:     linux-smp@vger.rutgers.edu
+S:     Maintained
+
+REST:
+P:     Linus Torvalds
+S:     Buried alive in email
index da9216f751f754c1a8a75c676da212f0f306259b..d2156289de2751b822a09c5f09a9a46bce76f264 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 67
+SUBLEVEL = 68
 
 ARCH = i386
 
index 6ed9a66074524087bb0650a0872f466462a8b20f..0d65535df6424dd862934b04446bb97b5952d9c1 100644 (file)
@@ -53,6 +53,10 @@ SWAP_DEV = 0
 ! ld86 requires an entry symbol. This may as well be the usual one.
 .globl _main
 _main:
+       nop
+       jmp     over_magic
+       .byte   0xF0
+over_magic:
 #if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
        int     3
 #endif
index b0d0a4784ae3f7c166f56104f7c3f9439ef9f12f..75b4de96a1a911fec71ca214d6da29342ec5acc1 100644 (file)
@@ -30,7 +30,6 @@ CONFIG_M586=y
 # Floppy, IDE, and other block devices
 #
 CONFIG_BLK_DEV_FD=y
-# CONFIG_BLK_DEV_RAM is not set
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -43,6 +42,8 @@ CONFIG_BLK_DEV_CMD640=y
 CONFIG_BLK_DEV_RZ1000=y
 # CONFIG_BLK_DEV_TRITON is not set
 # CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_XD is not set
 
 #
index 2ddf3868121c56be84c03bb29212ac871ea959ab..78c216e22ce79a3cc80748e863bbbf009430c711 100644 (file)
@@ -5,7 +5,6 @@ mainmenu_option next_comment
 comment 'Floppy, IDE, and other block devices'
 
 tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD
-tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
 bool 'Enhanced IDE/MFM/RLL disk/cdrom/tape support' CONFIG_BLK_DEV_IDE
 comment 'Please see drivers/block/README.ide for help/info on IDE drives'
 if [ "$CONFIG_BLK_DEV_IDE" = "n" ]; then
@@ -29,6 +28,10 @@ else
     bool '      ALI M1439/M1445 chipset support' CONFIG_BLK_DEV_ALI14XX
   fi
 fi
+
+tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
+tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
+
 if [ "$CONFIG_BLK_DEV_HD_IDE" = "y" -o "$CONFIG_BLK_DEV_HD_ONLY" = "y" ]; then
   define_bool CONFIG_BLK_DEV_HD y
 fi
index ccd48e9f833343b06f0b94a94d8c88be8a849ce4..33968fed957493611b230b88159220a7cb0174a5 100644 (file)
@@ -36,6 +36,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_BLK_DEV_LOOP),y)
+L_OBJS += loop.o
+else
+  ifeq ($(CONFIG_BLK_DEV_LOOP),m)
+  M_OBJS += loop.o
+  endif
+endif
+
 ifeq ($(CONFIG_BLK_DEV_HD),y)
 L_OBJS += hd.o
 endif
index df10f000314d2aa4d1cdcf399671b3345561b927..14250098b13229fa0ad5fc3668b62e4c38358688 100644 (file)
@@ -608,6 +608,9 @@ int blk_dev_init(void)
 #ifdef CONFIG_BLK_DEV_RAM
        rd_init();
 #endif
+#ifdef CONFIG_BLK_DEV_LOOP
+       loop_init();
+#endif
 #ifdef CONFIG_BLK_DEV_IDE
        ide_init();             /* this MUST preceed hd_init */
 #endif
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
new file mode 100644 (file)
index 0000000..cdbb979
--- /dev/null
@@ -0,0 +1,500 @@
+/*
+ *  linux/drivers/block/loop.c
+ *
+ *  Written by Theodore Ts'o, 3/29/93
+ * 
+ * Copyright 1993 by Theodore Ts'o.  Redistribution of this file is
+ * permitted under the GNU Public License.
+ *
+ * DES encryption plus some minor changes by Werner Almesberger, 30-MAY-1993
+ *
+ * Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994
+ *
+ * Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996
+ */
+
+#include <linux/module.h>
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <asm/segment.h>
+#include "loop.h"
+
+#ifdef DES_AVAILABLE
+#include "des.h"
+#endif
+
+#define DEFAULT_MAJOR_NR 28
+int loop_major = DEFAULT_MAJOR_NR;
+#define MAJOR_NR loop_major    /* not necessarily constant */
+
+#define DEVICE_NAME "loop"
+#define DEVICE_REQUEST do_lo_request
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+#define DEVICE_NO_RANDOM
+#define TIMEOUT_VALUE (6 * HZ)
+#include <linux/blk.h>
+
+#define MAX_LOOP 8
+static struct loop_device loop_dev[MAX_LOOP];
+static int loop_sizes[MAX_LOOP];
+
+/*
+ * Transfer functions
+ */
+static int transfer_none(struct loop_device *lo, int cmd, char *raw_buf,
+                 char *loop_buf, int size)
+{
+       if (cmd == READ)
+               memcpy(loop_buf, raw_buf, size);
+       else
+               memcpy(raw_buf, loop_buf, size);
+       return 0;
+}
+
+static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf,
+                char *loop_buf, int size)
+{
+       char    *in, *out, *key;
+       int     i, keysize;
+
+       if (cmd == READ) {
+               in = raw_buf;
+               out = loop_buf;
+       } else {
+               in = loop_buf;
+               out = raw_buf;
+       }
+       key = lo->lo_encrypt_key;
+       keysize = lo->lo_encrypt_key_size;
+       for (i=0; i < size; i++)
+               *out++ = *in++ ^ key[(i & 511) % keysize];
+       return 0;
+}
+
+#ifdef DES_AVAILABLE
+static int transfer_des(struct loop_device *lo, int cmd, char *raw_buf,
+                 char *loop_buf, int size)
+{
+       unsigned long tmp[2];
+       unsigned long x0,x1,p0,p1;
+
+       if (size & 7)
+               return -EINVAL;
+       x0 = lo->lo_des_init[0];
+       x1 = lo->lo_des_init[1];
+       while (size) {
+               if (cmd == READ) {
+                       tmp[0] = (p0 = ((unsigned long *) raw_buf)[0])^x0;
+                       tmp[1] = (p1 = ((unsigned long *) raw_buf)[1])^x1;
+                       des_ecb_encrypt((des_cblock *) tmp,(des_cblock *)
+                           loop_buf,lo->lo_des_key,DES_ENCRYPT);
+                       x0 = p0^((unsigned long *) loop_buf)[0];
+                       x1 = p1^((unsigned long *) loop_buf)[1];
+               }
+               else {
+                       p0 = ((unsigned long *) loop_buf)[0];
+                       p1 = ((unsigned long *) loop_buf)[1];
+                       des_ecb_encrypt((des_cblock *) loop_buf,(des_cblock *)
+                           raw_buf,lo->lo_des_key,DES_DECRYPT);
+                       ((unsigned long *) raw_buf)[0] ^= x0;
+                       ((unsigned long *) raw_buf)[1] ^= x1;
+                       x0 = p0^((unsigned long *) raw_buf)[0];
+                       x1 = p1^((unsigned long *) raw_buf)[1];
+               }
+               size -= 8;
+               raw_buf += 8;
+               loop_buf += 8;
+       }
+       return 0;
+}
+#endif
+
+static transfer_proc_t xfer_funcs[MAX_LOOP] = {
+       transfer_none,          /* LO_CRYPT_NONE */
+       transfer_xor,           /* LO_CRYPT_XOR */
+#ifdef DES_AVAILABLE
+       transfer_des,           /* LO_CRYPT_DES */
+#else
+       NULL,                   /* LO_CRYPT_DES */
+#endif
+       0                       /* LO_CRYPT_IDEA */
+};
+
+
+#define MAX_DISK_SIZE 1024*1024*1024
+
+
+static void figure_loop_size(struct loop_device *lo)
+{
+       int     size;
+
+       if (S_ISREG(lo->lo_inode->i_mode))
+               size = (lo->lo_inode->i_size - lo->lo_offset) / 1024;
+       else {
+               if (blk_size[MAJOR(lo->lo_device)])
+                       size = ((blk_size[MAJOR(lo->lo_device)]
+                                [MINOR(lo->lo_device)]) -
+                               (lo->lo_offset/1024));
+               else
+                       size = MAX_DISK_SIZE;
+       }
+       loop_sizes[lo->lo_number] = size;
+}
+
+static void do_lo_request(void)
+{
+       int     real_block, block, offset, len, blksize, size;
+       char    *dest_addr;
+       struct loop_device *lo;
+       struct buffer_head *bh;
+
+repeat:
+       INIT_REQUEST;
+       if (MINOR(CURRENT->rq_dev) >= MAX_LOOP)
+               goto error_out;
+       lo = &loop_dev[MINOR(CURRENT->rq_dev)];
+       if (!lo->lo_inode || !lo->transfer)
+               goto error_out;
+
+       blksize = BLOCK_SIZE;
+       if (blksize_size[MAJOR(lo->lo_device)]) {
+           blksize = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)];
+           if (!blksize)
+             blksize = BLOCK_SIZE;
+       }
+
+       dest_addr = CURRENT->buffer;
+       
+       if (blksize < 512) {
+               block = CURRENT->sector * (512/blksize);
+               offset = 0;
+       } else {
+               block = CURRENT->sector / (blksize >> 9);
+               offset = CURRENT->sector % (blksize >> 9);
+       }
+       block += lo->lo_offset / blksize;
+       offset += lo->lo_offset % blksize;
+       if (offset > blksize) {
+               block++;
+               offset -= blksize;
+       }
+       len = CURRENT->current_nr_sectors << 9;
+       if ((CURRENT->cmd != WRITE) && (CURRENT->cmd != READ)) {
+               printk("unknown loop device command (%d)?!?", CURRENT->cmd);
+               goto error_out;
+       }
+       while (len > 0) {
+               real_block = block;
+               if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
+                       real_block = bmap(lo->lo_inode, block);
+                       if (!real_block) {
+                               printk("loop: block %d not present\n", block);
+                               goto error_out;
+                       }
+               }
+               bh = getblk(lo->lo_device, real_block, blksize);
+               if (!bh) {
+                       printk("loop: device %s: getblk(-, %d, %d) returned NULL",
+                              kdevname(lo->lo_device),
+                              block, blksize);
+                       goto error_out;
+               }
+               if (!buffer_uptodate(bh) && ((CURRENT->cmd == READ) ||
+                                       (offset || (len < blksize)))) {
+                       ll_rw_block(READ, 1, &bh);
+                       wait_on_buffer(bh);
+                       if (!buffer_uptodate(bh)) {
+                               brelse(bh);
+                               goto error_out;
+                       }
+               }
+               size = blksize - offset;
+               if (size > len)
+                       size = len;
+               if ((lo->transfer)(lo, CURRENT->cmd, bh->b_data + offset,
+                                  dest_addr, size)) {
+                       printk("loop: transfer error block %d\n", block);
+                       brelse(bh);
+                       goto error_out;
+               }
+               if (CURRENT->cmd == WRITE) {
+                       set_bit(BH_Dirty, &bh->b_state);
+                       ll_rw_block(WRITE, 1, &bh);
+                       wait_on_buffer(bh);
+                       if (buffer_dirty(bh)) {
+                               brelse(bh);
+                               goto error_out;
+                       }
+               }
+               brelse(bh);
+               dest_addr += size;
+               len -= size;
+               offset = 0;
+               block++;
+       }
+       end_request(1);
+       goto repeat;
+error_out:
+       end_request(0);
+       goto repeat;
+}
+
+static int loop_set_fd(struct loop_device *lo, unsigned int arg)
+{
+       struct inode    *inode;
+       
+       if (arg >= NR_OPEN || !current->files->fd[arg])
+               return -EBADF;
+       if (lo->lo_inode)
+               return -EBUSY;
+       inode = current->files->fd[arg]->f_inode;
+       if (!inode) {
+               printk("loop_set_fd: NULL inode?!?\n");
+               return -EINVAL;
+       }
+       if (S_ISREG(inode->i_mode)) {
+               lo->lo_device = inode->i_dev;
+               lo->lo_flags |= LO_FLAGS_DO_BMAP;
+       } else if (S_ISBLK(inode->i_mode))
+                       lo->lo_device = inode->i_rdev;
+               else
+                       return -EINVAL;
+       lo->lo_inode = inode;
+       lo->lo_inode->i_count++;
+       lo->transfer = NULL;
+       figure_loop_size(lo);
+       return 0;
+}
+
+static int loop_clr_fd(struct loop_device *lo, kdev_t dev)
+{
+       if (!lo->lo_inode)
+               return -ENXIO;
+       if (lo->lo_refcnt > 1)
+               return -EBUSY;
+       lo->lo_inode->i_count--;
+       lo->lo_device = 0;
+       lo->lo_inode = NULL;
+       lo->lo_encrypt_type = 0;
+       lo->lo_offset = 0;
+       lo->lo_encrypt_key_size = 0;
+       memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
+       memset(lo->lo_name, 0, LO_NAME_SIZE);
+       invalidate_buffers(dev);
+       return 0;
+}
+
+static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
+{
+       struct loop_info info;
+
+       if (!lo->lo_inode)
+               return -ENXIO;
+       if (!arg)
+               return -EINVAL;
+       memcpy_fromfs(&info, arg, sizeof(info));
+       if (info.lo_encrypt_key_size > LO_KEY_SIZE)
+               return -EINVAL;
+       switch (info.lo_encrypt_type) {
+       case LO_CRYPT_NONE:
+               break;
+       case LO_CRYPT_XOR:
+               if (info.lo_encrypt_key_size < 0)
+                       return -EINVAL;
+               break;
+#ifdef DES_AVAILABLE
+       case LO_CRYPT_DES:
+               if (info.lo_encrypt_key_size != 8)
+                       return -EINVAL;
+               des_set_key((des_cblock *) lo->lo_encrypt_key,
+                  lo->lo_des_key);
+               memcpy(lo->lo_des_init,info.lo_init,8);
+               break;
+#endif
+       default:
+               return -EINVAL;
+       }
+       lo->lo_offset = info.lo_offset;
+       strncpy(lo->lo_name, info.lo_name, LO_NAME_SIZE);
+       lo->lo_encrypt_type = info.lo_encrypt_type;
+       lo->transfer = xfer_funcs[lo->lo_encrypt_type];
+       lo->lo_encrypt_key_size = info.lo_encrypt_key_size;
+       if (info.lo_encrypt_key_size)
+               memcpy(lo->lo_encrypt_key, info.lo_encrypt_key,
+                      info.lo_encrypt_key_size);
+       figure_loop_size(lo);
+       return 0;
+}
+
+static int loop_get_status(struct loop_device *lo, struct loop_info *arg)
+{
+       struct loop_info        info;
+       
+       if (!lo->lo_inode)
+               return -ENXIO;
+       if (!arg)
+               return -EINVAL;
+       memset(&info, 0, sizeof(info));
+       info.lo_number = lo->lo_number;
+       info.lo_device = kdev_t_to_nr(lo->lo_inode->i_dev);
+       info.lo_inode = lo->lo_inode->i_ino;
+       info.lo_rdevice = kdev_t_to_nr(lo->lo_device);
+       info.lo_offset = lo->lo_offset;
+       info.lo_flags = lo->lo_flags;
+       strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);
+       info.lo_encrypt_type = lo->lo_encrypt_type;
+       if (lo->lo_encrypt_key_size && suser()) {
+               info.lo_encrypt_key_size = lo->lo_encrypt_key_size;
+               memcpy(info.lo_encrypt_key, lo->lo_encrypt_key,
+                      lo->lo_encrypt_key_size);
+       }
+       memcpy_tofs(arg, &info, sizeof(info));
+       return 0;
+}
+
+static int lo_ioctl(struct inode * inode, struct file * file,
+       unsigned int cmd, unsigned long arg)
+{
+       struct loop_device *lo;
+       int dev, err;
+
+       if (!inode)
+               return -EINVAL;
+       if (MAJOR(inode->i_rdev) != loop_major) {
+               printk("lo_ioctl: pseudo-major != %d\n", loop_major);
+               return -ENODEV;
+       }
+       dev = MINOR(inode->i_rdev);
+       if (dev >= MAX_LOOP)
+               return -ENODEV;
+       lo = &loop_dev[dev];
+       switch (cmd) {
+       case LOOP_SET_FD:
+               return loop_set_fd(lo, arg);
+       case LOOP_CLR_FD:
+               return loop_clr_fd(lo, inode->i_rdev);
+       case LOOP_SET_STATUS:
+               return loop_set_status(lo, (struct loop_info *) arg);
+       case LOOP_GET_STATUS:
+               return loop_get_status(lo, (struct loop_info *) arg);
+       case BLKGETSIZE:   /* Return device size */
+               if (!lo->lo_inode)
+                       return -ENXIO;
+               if (!arg)  return -EINVAL;
+               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
+               if (err)
+                       return err;
+               put_fs_long(loop_sizes[lo->lo_number] << 1, (long *) arg);
+               return 0;
+               default:
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+static int lo_open(struct inode *inode, struct file *file)
+{
+       struct loop_device *lo;
+       int     dev;
+
+       if (!inode)
+               return -EINVAL;
+       if (MAJOR(inode->i_rdev) != loop_major) {
+               printk("lo_open: pseudo-major != %d\n", loop_major);
+               return -ENODEV;
+       }
+       dev = MINOR(inode->i_rdev);
+       if (dev >= MAX_LOOP)
+               return -ENODEV;
+       lo = &loop_dev[dev];
+       lo->lo_refcnt++;
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static void lo_release(struct inode *inode, struct file *file)
+{
+       struct loop_device *lo;
+       int     dev;
+
+       if (!inode)
+               return;
+       if (MAJOR(inode->i_rdev) != loop_major) {
+               printk("lo_release: pseudo-major != %d\n", loop_major);
+               return;
+       }
+       dev = MINOR(inode->i_rdev);
+       if (dev >= MAX_LOOP)
+               return;
+       sync_dev(inode->i_rdev);
+       lo = &loop_dev[dev];
+       if (lo->lo_refcnt <= 0)
+               printk("lo_release: refcount(%d) <= 0\n", lo->lo_refcnt);
+       else  {
+               lo->lo_refcnt--;
+               MOD_DEC_USE_COUNT;
+       }
+
+       return;
+}
+
+static struct file_operations lo_fops = {
+       NULL,                   /* lseek - default */
+       block_read,             /* read - general block-dev read */
+       block_write,            /* write - general block-dev write */
+       NULL,                   /* readdir - bad */
+       NULL,                   /* select */
+       lo_ioctl,               /* ioctl */
+       NULL,                   /* mmap */
+       lo_open,                /* open */
+       lo_release              /* release */
+};
+
+/*
+ * And now the modules code and kernel interface.
+ */
+#ifdef MODULE
+#define loop_init init_module
+#endif
+
+int
+loop_init( void ) {
+       int     i = (loop_major ? loop_major : DEFAULT_MAJOR_NR);
+
+       if (register_blkdev(i, "loop", &lo_fops) &&
+           (i = register_blkdev(0, "loop", &lo_fops)) <= 0) {
+               printk("Unable to get major number for loop device\n");
+               return -EIO;
+       }
+       loop_major = i;
+#ifdef MODULE
+       if (i != DEFAULT_MAJOR_NR)
+#endif
+         printk("loop: registered device at major %d\n",loop_major);
+
+       blk_dev[loop_major].request_fn = DEVICE_REQUEST;
+       for (i=0; i < MAX_LOOP; i++) {
+               memset(&loop_dev[i], 0, sizeof(struct loop_device));
+               loop_dev[i].lo_number = i;
+       }
+       memset(&loop_sizes, 0, sizeof(loop_sizes));
+       blk_size[loop_major] = loop_sizes;
+
+       return 0;
+}
+
+#ifdef MODULE
+void
+cleanup_module( void ) {
+  if (unregister_blkdev(loop_major, "loop") != 0)
+    printk("loop: cleanup_module failed\n");
+}
+#endif
diff --git a/drivers/block/loop.h b/drivers/block/loop.h
new file mode 100644 (file)
index 0000000..2c92d55
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef _LINUX_LOOP_H
+#define _LINUX_LOOP_H
+
+/*
+ * include/linux/loop.h
+ *
+ * Written by Theodore Ts'o, 3/29/93.
+ *
+ * Copyright 1993 by Theodore Ts'o.  Redistribution of this file is
+ * permitted under the GNU Public License.
+ */
+
+#define LO_NAME_SIZE   64
+#define LO_KEY_SIZE    32
+       
+struct loop_device {
+       int             lo_number;
+       struct inode    *lo_inode;
+       int             lo_refcnt;
+       kdev_t          lo_device;
+       int             lo_offset;
+       int             lo_encrypt_type;
+       int             lo_encrypt_key_size;
+       int             lo_flags;
+       int             (*transfer)(struct loop_device *, int cmd,
+                                   char *raw_buf, char *loop_buf, int size);
+       char            lo_name[LO_NAME_SIZE];
+       char            lo_encrypt_key[LO_KEY_SIZE];
+#ifdef DES_AVAILABLE
+       des_key_schedule lo_des_key;
+       unsigned long   lo_des_init[2];
+#endif
+};
+
+typedef        int (* transfer_proc_t)(struct loop_device *, int cmd,
+                               char *raw_buf, char *loop_buf, int size);
+
+/*
+ * Loop flags
+ */
+#define LO_FLAGS_DO_BMAP       0x00000001
+
+struct loop_info {
+       int             lo_number;      /* ioctl r/o */
+       dev_t           lo_device;      /* ioctl r/o */
+       unsigned long   lo_inode;       /* ioctl r/o */
+       dev_t           lo_rdevice;     /* ioctl r/o */
+       int             lo_offset;
+       int             lo_encrypt_type;
+       int             lo_encrypt_key_size;    /* ioctl w/o */
+       int             lo_flags;       /* ioctl r/o */
+       char            lo_name[LO_NAME_SIZE];
+       unsigned char   lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+       unsigned long   lo_init[2];
+       char            reserved[4];
+};
+
+/*
+ * Loop encryption types --- LO_CRYPT_IDEA isn't supported yet
+ */
+
+#define LO_CRYPT_NONE  0
+#define LO_CRYPT_XOR   1
+#define LO_CRYPT_DES   2
+#define LO_CRYPT_IDEA  5
+#define MAX_LO_CRYPT   4
+
+/*
+ * IOCTL commands --- we will commandeer 0x4C ('L')
+ */
+
+#define LOOP_SET_FD    0x4C00
+#define LOOP_CLR_FD    0x4C01
+#define LOOP_SET_STATUS        0x4C02
+#define LOOP_GET_STATUS        0x4C03
+
+#endif
index 21fc36ab8863781a93081c2345fad25116039802..b7d3751e2d19422e11f79e19bae1c9951e449ed7 100644 (file)
@@ -13,7 +13,7 @@ fi
 tristate 'Parallel printer support' CONFIG_PRINTER
 tristate 'Logitech busmouse support' CONFIG_BUSMOUSE
 tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
-if [ "$CONFIG_PSMOUSE" = "y" ]; then
+if [ "$CONFIG_PSMOUSE" != "n" ]; then
   bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
 fi
 tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE
@@ -39,6 +39,7 @@ if [ "$CONFIG_APM" = "y" ]; then
 fi
 bool 'Watchdog Timer Support'  CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
+  bool '    Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
   tristate '   WDT Watchdog timer' CONFIG_WDT
   if [ "$CONFIG_WDT" = "y" ]; then
      bool '       WDT501 features' CONFIG_WDT_501
index 29b9eb8f788c349a1e881de1193a1167056ae952..188cf2f24901fd0b33e97531b2347d4e1e12bfec 100644 (file)
  *     driver this won't always recover a failed machine.
  */
  
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/mouse.h>
+
 #define WATCHDOG_MINOR 130
 #define TIMER_MARGIN   (60*HZ)         /* Allow 1 minute */
 
@@ -68,7 +69,9 @@ static void softdog_release(struct inode *inode, struct file *file)
        /*
         *      Shut off the timer.
         */
+#ifndef CONFIG_WATCHDOG_NOWAYOUT        
        del_timer(&watchdog_ticktock);
+#endif 
        timer_alive=0;
 }
 
index 3ddaf0166583ec7bb3dacec92fbca3d916e02e91..7f2b5777d24a2123855255b640d67dcc6bd2fad2 100644 (file)
@@ -187,8 +187,10 @@ static void wdt_release(struct inode *inode, struct file *file)
 {
        if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
        {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT       
                inb_p(WDT_DC);          /* Disable counters */
                wdt_ctr_load(2,0);      /* 0 length reset pulses now */
+#endif         
                wdt_is_open=0;
        }
        MOD_DEC_USE_COUNT;
index a766060b138a64db60a00dbacbfa70ab6bdd122f..39bf6f521fc134d4993c906d7ef6e172b55a8444 100644 (file)
@@ -36,10 +36,10 @@ L_OBJS += sk_g16.o
 endif
 
 ifeq ($(CONFIG_NET_IPIP),y)
-L_OBJS += tunnel.o
+L_OBJS += new_tunnel.o
 else
   ifeq ($(CONFIG_NET_IPIP),m)
-  M_OBJS += tunnel.o
+  M_OBJS += new_tunnel.o
   endif
 endif
 
diff --git a/drivers/net/new_tunnel.c b/drivers/net/new_tunnel.c
new file mode 100644 (file)
index 0000000..4a164cf
--- /dev/null
@@ -0,0 +1,426 @@
+/* tunnel.c: an IP tunnel driver
+
+       The purpose of this driver is to provide an IP tunnel through
+       which you can tunnel network traffic transparently across subnets.
+
+       This was written by looking at Nick Holloway's dummy driver
+       Thanks for the great code!
+
+               -Sam Lantinga   (slouken@cs.ucdavis.edu)  02/01/95
+               
+       Minor tweaks:
+               Cleaned up the code a little and added some pre-1.3.0 tweaks.
+               dev->hard_header/hard_header_len changed to use no headers.
+               Comments/bracketing tweaked.
+               Made the tunnels use dev->name not tunnel: when error reporting.
+               Added tx_dropped stat
+               
+               -Alan Cox       (Alan.Cox@linux.org) 21 March 95
+
+       Reworked:
+               Changed to tunnel to destination gateway instead of pointopoint
+               Almost completely rewritten
+               Note:  There is currently no firewall or ICMP handling done.
+
+               -Sam Lantinga   (slouken@cs.ucdavis.edu) 02/13/96
+               
+       Note:
+               The old driver is in tunnel.c if you have funnies with the
+               new one.
+*/
+
+/* Things I wish I had known when writing the tunnel driver:
+
+       When the tunnel_xmit() function is called, the skb contains the
+       packet to be sent (plus a great deal of extra info), and dev
+       contains the tunnel device that _we_ are.
+
+       When we are passed a packet, we are expected to fill in the
+       source address with our source IP address.
+
+       What is the proper way to allocate, copy and free a buffer?
+       After you allocate it, it is a "0 length" chunk of memory
+       starting at zero.  If you want to add headers to the buffer
+       later, you'll have to call "skb_reserve(skb, amount)" with
+       the amount of memory you want reserved.  Then, you call
+       "skb_put(skb, amount)" with the amount of space you want in
+       the buffer.  skb_put() returns a pointer to the top (#0) of
+       that buffer.  skb->len is set to the amount of space you have
+       "allocated" with skb_put().  You can then write up to skb->len
+       bytes to that buffer.  If you need more, you can call skb_put()
+       again with the additional amount of space you need.  You can
+       find out how much more space you can allocate by calling 
+       "skb_tailroom(skb)".
+       Now, to add header space, call "skb_push(skb, header_len)".
+       This creates space at the beginning of the buffer and returns
+       a pointer to this new space.  If later you need to strip a
+       header from a buffer, call "skb_pull(skb, header_len)".
+       skb_headroom() will return how much space is left at the top
+       of the buffer (before the main data).  Remember, this headroom
+       space must be reserved before the skb_put() function is called.
+*/
+
+#include <linux/module.h>
+
+/* Only two headers!! :-) */
+#include <net/ip.h>
+#include <linux/if_arp.h>
+
+
+/*#define TUNNEL_DEBUG*/
+
+/* 
+ *     Our header is a simple IP packet with no options
+ */
+#define tunnel_hlen    sizeof(struct iphdr)
+
+/*
+ *     Okay, this needs to be high enough that we can fit a "standard"
+ *     ethernet header and an IP tunnel header into the outgoing packet.
+ *     [36 bytes]
+ */
+#define TUNL_HLEN      (((ETH_HLEN+15)&~15)+tunl_hlen)
+
+
+#ifdef MODULE
+static int tunnel_open(struct device *dev)
+{
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static int tunnel_close(struct device *dev)
+{
+       MOD_DEC_USE_COUNT;
+       return 0;
+}
+
+#endif
+
+#ifdef TUNNEL_DEBUG
+void print_ip(struct iphdr *ip)
+{
+       unsigned char *ipaddr;
+
+       printk("IP packet:\n");
+       printk("--- header len = %d\n", ip->ihl*4);
+       printk("--- ip version: %d\n", ip->version);
+       printk("--- ip protocol: %d\n", ip->protocol);
+       ipaddr=(unsigned char *)&ip->saddr;
+       printk("--- source address: %u.%u.%u.%u\n", 
+                       *ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
+       ipaddr=(unsigned char *)&ip->daddr;
+       printk("--- destination address: %u.%u.%u.%u\n", 
+                       *ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
+       printk("--- total packet len: %d\n", ntohs(ip->tot_len));
+}
+#endif
+
+/*
+ *     This function assumes it is being called from dev_queue_xmit()
+ *     and that skb is filled properly by that function.
+ */
+
+static int tunnel_xmit(struct sk_buff *skb, struct device *dev)
+{
+       struct enet_statistics *stats;          /* This device's statistics */
+       struct rtable *rt;                      /* Route to the other host */
+       struct device *tdev;                    /* Device to other host */
+       struct iphdr  *iph;                     /* Our new IP header */
+       __u32          target;                  /* The other host's IP address */
+       int      max_headroom;                  /* The extra header space needed */
+
+       /*
+        *      Return if there is nothing to do.  (Does this ever happen?)
+        */
+       if (skb == NULL || dev == NULL) {
+#ifdef TUNNEL_DEBUG
+               printk ( KERN_INFO "tunnel: Nothing to do!\n" );
+#endif
+               return 0;
+       }
+
+       /* 
+        *      Make sure we are not busy (check lock variable) 
+        */
+        
+       stats = (struct enet_statistics *)dev->priv;
+       cli();
+       if (dev->tbusy != 0) 
+       {
+               sti();
+               stats->tx_errors++;
+               return(1);
+       }
+       dev->tbusy = 1;
+       sti();
+  
+       /*printk("-");*/
+       /*
+        *  First things first.  Look up the destination address in the 
+        *  routing tables
+        */
+       iph = (struct iphdr *) skb->data;
+       if ((rt = ip_rt_route(iph->daddr, 0)) == NULL)
+       { 
+               /* No route to host */
+               /* Where did the packet come from? */
+               /*icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);*/
+               printk ( KERN_INFO "%s: Packet with no route!\n", dev->name );
+               dev->tbusy=0;
+               stats->tx_errors++;
+               return(1);
+       }
+
+       if (!(rt->rt_flags & RTF_GATEWAY))
+       { 
+               /* No gateway to tunnel through? */
+               /* Where did the packet come from? */
+               /*icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);*/
+               printk ( KERN_INFO "%s: Packet with no target gateway!\n", dev->name);
+               ip_rt_put(rt);
+               dev->tbusy=0;
+               stats->tx_errors++;
+               return(1);
+       }
+       target = rt->rt_gateway;
+       ip_rt_put(rt);
+
+       if ((rt = ip_rt_route(target, 0)) == NULL)
+       { 
+               /* No route to host */
+               /* Where did the packet come from? */
+               /*icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);*/
+               printk ( KERN_INFO "%s: Can't reach target gateway!\n", dev->name);
+               dev->tbusy=0;
+               stats->tx_errors++;
+               return(1);
+       }
+       tdev = rt->rt_dev;
+
+       if (tdev == dev)
+       { 
+               /* Tunnel to ourselves?  -- I don't think so. */
+               printk ( KERN_INFO "%s: Packet targetted at myself!\n" ,dev->name);
+               ip_rt_put(rt);
+               dev->tbusy=0;
+               stats->tx_errors++;
+               return(1);
+       }
+
+#ifdef TUNNEL_DEBUG
+       printk("Old IP Header....\n");
+       print_ip(iph);
+#endif
+
+       /*
+        * Okay, now see if we can stuff it in the buffer as-is.
+        */
+       max_headroom = ((tunnel_hlen+tdev->hard_header_len+15)&~15);
+#ifdef TUNNEL_DEBUG
+printk("Room left at head: %d\n", skb_headroom(skb));
+printk("Room left at tail: %d\n", skb_tailroom(skb));
+printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
+#endif
+       if (skb_headroom(skb) >= max_headroom) {
+               skb->h.iph = (struct iphdr *) skb_push(skb, tunnel_hlen);
+       } else {
+               struct sk_buff *new_skb;
+
+               if ( !(new_skb = dev_alloc_skb(skb->len+max_headroom)) ) 
+               {
+                       printk( KERN_INFO "%s: Out of memory, dropped packet\n",
+                               dev->name);
+                       ip_rt_put(rt);
+                       dev->tbusy = 0;
+                       stats->tx_dropped++;
+                       return(1);
+               }
+               new_skb->free = 1;
+
+               /*
+                * Reserve space for our header
+                */
+               skb_reserve(new_skb, tunnel_hlen);
+               new_skb->h.iph = (struct iphdr *) skb_push(new_skb, tunnel_hlen);
+               /*
+                * Copy the old packet to the new buffer.
+                * Note that new_skb->h.iph is our (tunnel driver's) header
+                * and new_skb->ip_hdr is the IP header of the old packet.
+                */
+               new_skb->ip_hdr = (struct iphdr *) skb_put(new_skb, skb->len);
+               memcpy(new_skb->ip_hdr, skb->data, skb->len);
+               /* Is this necessary? */
+               memcpy(new_skb->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
+
+               /* Free the old packet, we no longer need it */
+               kfree_skb(skb, FREE_WRITE);
+               skb = new_skb;
+       }
+
+       /*
+        *      Push down and install the IPIP header.
+        */
+       iph = skb->h.iph;
+       iph->version    =       4;
+       iph->tos                =       skb->ip_hdr->tos;
+       iph->ttl                =       skb->ip_hdr->ttl;
+       iph->frag_off           =       0;
+       iph->daddr              =       target;
+       iph->saddr              =       tdev->pa_addr;
+       iph->protocol           =       IPPROTO_IPIP;
+       iph->ihl                =       5;
+       iph->tot_len            =       htons(skb->len);
+       iph->id                 =       htons(ip_id_count++);   /* Race condition here? */
+       ip_send_check(iph);
+       skb->ip_hdr = skb->h.iph;
+
+#ifdef TUNNEL_DEBUG
+       printk("New IP Header....\n");
+       print_ip(iph);
+#endif
+
+       /*
+        *      Send the packet on its way!
+        *      Note that dev_queue_xmit() will eventually free the skb.
+        *      If ip_forward() made a copy, it will return 1 so we can free.
+        */
+
+       if (ip_forward(skb, dev, 0, target) == 1)
+               kfree_skb(skb, FREE_WRITE);
+
+       /*
+        *      Clean up:  We're done with the route and the packet
+        */
+        
+       ip_rt_put(rt);
+#ifdef TUNNEL_DEBUG
+       printk("Packet sent through tunnel interface!\n");
+#endif
+/*printk(">");*/
+       /* Record statistics and return */
+       stats->tx_packets++;
+       dev->tbusy=0;
+       return 0;
+}
+
+static struct enet_statistics *
+tunnel_get_stats(struct device *dev)
+{
+       return((struct enet_statistics*) dev->priv);
+}
+
+/*
+ *     Called when a new tunnel device is initialized.
+ *     The new tunnel device structure is passed to us.
+ */
+int tunnel_init(struct device *dev)
+{
+       int i;
+
+       /* Oh, just say we're here, in case anyone cares */
+       static int tun_msg=0;
+       if(!tun_msg)
+       {
+               printk ( KERN_INFO "tunnel: version v0.2b\n" );
+               tun_msg=1;
+       }
+
+       /* Add our tunnel functions to the device */
+#ifdef MODULE
+       dev->open               = tunnel_open;
+       dev->stop               = tunnel_close;
+#endif
+       dev->hard_start_xmit    = tunnel_xmit;
+       dev->get_stats          = tunnel_get_stats;
+       dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
+       if (dev->priv == NULL)
+               return -ENOMEM;
+       memset(dev->priv, 0, sizeof(struct enet_statistics));
+
+       /* Initialize the tunnel device structure */
+       for (i = 0; i < DEV_NUMBUFFS; i++)
+               skb_queue_head_init(&dev->buffs[i]);
+
+       dev->hard_header        = NULL;
+       dev->rebuild_header     = NULL;
+       dev->set_mac_address    = NULL;
+       dev->header_cache_bind  = NULL;
+       dev->header_cache_update= NULL;
+
+       dev->type                               = ARPHRD_TUNNEL;
+       dev->hard_header_len    = (tunnel_hlen+ETH_HLEN);
+       dev->mtu                = 1500-tunnel_hlen;     /* eth_mtu */
+       dev->addr_len           = 0;            /* Is this only for ARP? */
+       dev->tx_queue_len       = 2;            /* Small queue */
+                                                                                       it should all run through */
+       memset(dev->broadcast,0xFF, ETH_ALEN);
+
+       /* New-style flags. */
+       dev->flags              = IFF_NOARP;    /* Don't use ARP on this device */
+                                               /* No broadcasting through a tunnel */
+       dev->family             = AF_INET;
+       dev->pa_addr            = 0;
+       dev->pa_brdaddr         = 0;
+       dev->pa_mask            = 0;
+       dev->pa_alen            = 4;
+
+       /* We're done.  Have I forgotten anything? */
+       return 0;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/*  Module specific interface                                      */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#ifdef MODULE
+
+static int tunnel_probe(struct device *dev)
+{
+       tunnel_init(dev);
+       return 0;
+}
+
+static struct device dev_tunnel = {
+       "tunl0\0   ", 
+       0, 0, 0, 0,
+       0x0, 0,
+       0, 0, 0, NULL, tunnel_probe };
+
+int init_module(void)
+{
+       /* Find a name for this unit */
+       int ct= 1;
+       
+       while(dev_get(dev_tunnel.name)!=NULL && ct<100)
+       {
+               sprintf(dev_tunnel.name,"tunl%d",ct);
+               ct++;
+       }
+       
+#ifdef TUNNEL_DEBUG
+       printk("tunnel: registering device %s\n", dev_tunnel.name);
+#endif
+       if (register_netdev(&dev_tunnel) != 0)
+               return -EIO;
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       unregister_netdev(&dev_tunnel);
+       kfree_s(dev_tunnel.priv,sizeof(struct enet_statistics));
+       dev_tunnel.priv=NULL;
+}
+#endif /* MODULE */
+
+
+
+
+
+
+
index 35d6f59f87a51f8291470b93e38f8b167859ac8b..03846d02051f885f4df748610207bc6901ab7ed2 100644 (file)
@@ -106,6 +106,8 @@ struct pci_dev_info dev_info[] = {
        DEVICE( OPTI,           OPTI_82C558,    "82C558"),
        DEVICE( OPTI,           OPTI_82C621,    "82C621"),
        DEVICE( OPTI,           OPTI_82C822,    "82C822"),
+       DEVICE( SGS,            SGS_2000,       "STG 2000X"),
+       DEVICE( SGS,            SGS_1764,       "STG 1764X"),
        DEVICE( BUSLOGIC,       BUSLOGIC_946C_2,"BT-946C"),
        DEVICE( BUSLOGIC,       BUSLOGIC_946C,  "BT-946C"),
        DEVICE( BUSLOGIC,       BUSLOGIC_930,   "BT-930"),
@@ -151,6 +153,7 @@ struct pci_dev_info dev_info[] = {
        DEVICE( ASP,            ASP_ABP940,     "ABP940"),
        DEVICE( IMS,            IMS_8849,       "8849"),
        DEVICE( TEKRAM2,        TEKRAM2_690c,   "DC690c"),
+       DEVICE( AMCC,           AMCC_MYRINET,   "Myrinet PCI (M2-PCI-32)"),
        DEVICE( INTERG,         INTERG_1680,    "IGA-1680"),
        DEVICE( REALTEK,        REALTEK_8029,   "8029"),
        DEVICE( INIT,           INIT_320P,      "320 P"),
@@ -171,6 +174,10 @@ struct pci_dev_info dev_info[] = {
        DEVICE( ZEITNET,        ZEITNET_1225,   "1225"),
        DEVICE( SPECIALIX,      SPECIALIX_XIO,  "XIO/SIO host"),
        DEVICE( SPECIALIX,      SPECIALIX_RIO,  "RIO host"),
+       DEVICE( RP,             RP8OCTA,        "RocketPort 8 Oct"),
+       DEVICE( RP,             RP8INTF,        "RocketPort 8 Intf"),
+       DEVICE( RP,             RP16INTF,       "RocketPort 16 Intf"),
+       DEVICE( RP,             RP32INTF,       "RocketPort 32 Intf"),
        DEVICE( CYCLADES,       CYCLADES_Y,     "Cyclome-Y"),
        DEVICE( SYMPHONY,       SYMPHONY_101,   "82C101"),
        DEVICE( TEKRAM,         TEKRAM_DC290,   "DC-290"),
@@ -464,6 +471,7 @@ const char *pci_strvendor(unsigned int vendor)
              case PCI_VENDOR_ID_MUTECH:        return "Mutech";
              case PCI_VENDOR_ID_ZEITNET:       return "ZeitNet";
              case PCI_VENDOR_ID_SPECIALIX:     return "Specialix";
+             case PCI_VENDOR_ID_RP:            return "Comtrol";
              case PCI_VENDOR_ID_CYCLADES:      return "Cyclades";
              case PCI_VENDOR_ID_SYMPHONY:      return "Symphony";
              case PCI_VENDOR_ID_TEKRAM:        return "Tekram";
index ea6118fb05e9b2ff968cefc6072e3b2f3868f168..c7449b20701545cc4f3272ff25f095085a61ad6c 100644 (file)
@@ -234,12 +234,14 @@ static struct dev_info device_list[] =
 {"MAXTOR","MXT-1240S","I1.2", BLIST_NOLUN},     /* Locks up when LUN>0 polled */
 {"MAXTOR","XT-4170S","B5A", BLIST_NOLUN},       /* Locks-up sometimes when LUN>0 polled. */
 {"MAXTOR","XT-8760S","B7B", BLIST_NOLUN},       /* guess what? */
+{"MEDIAVIS","RENO CD-ROMX2A","2.03",BLIST_NOLUN},/*Responds to all lun */
 {"NEC","CD-ROM DRIVE:841","1.0", BLIST_NOLUN},  /* Locks-up when LUN>0 polled. */
 {"RODIME","RO3000S","2.33", BLIST_NOLUN},       /* Locks up if polled for lun != 0 */
 {"SEAGATE", "ST157N", "\004|j", BLIST_NOLUN},   /* causes failed REQUEST SENSE on lun 1 
                                                 * for aha152x controller, which causes 
                                                 * SCSI code to reset bus.*/
 {"SEAGATE", "ST296","921", BLIST_NOLUN},        /* Responds to all lun */
+{"SEAGATE","ST1581","6538",BLIST_NOLUN},       /* Responds to all lun */
 {"SONY","CD-ROM CDU-541","4.3d", BLIST_NOLUN},
 {"SONY","CD-ROM CDU-55S","1.0i", BLIST_NOLUN},
 {"SONY","CD-ROM CDU-561","1.7x", BLIST_NOLUN},
index 9dd303cf2842d22accb883d4fe9464ee1acf4153..f94d5fb69e550d7d3c8248413d2d0326a154510d 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -290,7 +290,7 @@ static int count(char ** argv)
 unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
                unsigned long p, int from_kmem)
 {
-       char *tmp, *pag = NULL;
+       char *tmp, *tmp1, *pag = NULL;
        int len, offset = 0;
        unsigned long old_fs, new_fs;
 
@@ -303,14 +303,12 @@ unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
        while (argc-- > 0) {
                if (from_kmem == 1)
                        set_fs(new_fs);
-               if (!(tmp = get_user(argv+argc)))
+               if (!(tmp1 = tmp = get_user(argv+argc)))
                        panic("VFS: argc is wrong");
                if (from_kmem == 1)
                        set_fs(old_fs);
-               len=0;          /* remember zero-padding */
-               do {
-                       len++;
-               } while (get_user(tmp++));
+               while (get_user(tmp++));
+               len = tmp - tmp1;
                if (p < len) {  /* this shouldn't happen - 128kB */
                        set_fs(old_fs);
                        return 0;
@@ -329,7 +327,16 @@ unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
                                        set_fs(new_fs);
 
                        }
-                       *(pag + offset) = get_user(tmp);
+                       if (len == 0 || offset == 0)
+                         *(pag + offset) = get_user(tmp);
+                       else {
+                         int bytes_to_copy = (len > offset) ? offset : len;
+                         tmp -= bytes_to_copy;
+                         p -= bytes_to_copy;
+                         offset -= bytes_to_copy;
+                         len -= bytes_to_copy;
+                         memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
+                       }
                }
        }
        if (from_kmem==2)
index db3ec080ec2edbad3251506276b61182f4488341..856f15aac016297b9483e64d23bc826f185caf6f 100644 (file)
@@ -68,13 +68,14 @@ void fat_put_super(struct super_block *sb)
 
 static int parse_options(char *options,char *check,char *conversion,uid_t *uid,
     gid_t *gid,int *umask,int *debug,int *fat,int *quiet,
-       int *blksize, char *dotsOK, char *sys_immutable)
+       int *blksize, char *dotsOK, char *sys_immutable, char *showexec)
 {
        char *this_char,*value;
 
        *check = 'n';
        *conversion = 'b';
        *dotsOK = 0;
+       *showexec = 0;
        *uid = current->uid;
        *gid = current->gid;
        *umask = current->fs->umask;
@@ -105,6 +106,9 @@ static int parse_options(char *options,char *check,char *conversion,uid_t *uid,
                else if (!strcmp(this_char,"nodots")) {
                  *dotsOK = 0;
                }
+               else if (!strcmp(this_char,"showexec")) {
+                 *showexec = 1;
+               }
                else if (!strcmp(this_char,"dotsOK") && value) {
                        if (!strcmp(value,"yes")) *dotsOK = 1;
                        else if (!strcmp(value,"no")) *dotsOK = 0;
@@ -173,7 +177,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
        struct msdos_boot_sector *b;
        int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;
        int debug,error,fat,quiet;
-       char check,conversion,dotsOK,sys_immutable;
+       char check,conversion,dotsOK,sys_immutable,showexec;
        uid_t uid;
        gid_t gid;
        int umask;
@@ -187,7 +191,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
                }
        }
        if (!parse_options((char *) data,&check,&conversion,&uid,&gid,&umask,
-           &debug,&fat,&quiet,&blksize,&dotsOK,&sys_immutable)
+           &debug,&fat,&quiet,&blksize,&dotsOK,&sys_immutable,&showexec)
                || (blksize != 512 && blksize != 1024)) {
                sb->s_dev = 0;
                MOD_DEC_USE_COUNT;
@@ -299,6 +303,7 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
        MSDOS_SB(sb)->fs_umask = umask;
        MSDOS_SB(sb)->quiet = quiet;
        MSDOS_SB(sb)->dotsOK = dotsOK;
+       MSDOS_SB(sb)->showexec = showexec;
        MSDOS_SB(sb)->sys_immutable = sys_immutable;
        MSDOS_SB(sb)->vfat = 0;   /* vfat_read_super sets this */
        MSDOS_SB(sb)->umsdos = 0; /* umsdos_read_super will set this */
@@ -433,7 +438,8 @@ void fat_read_inode(struct inode *inode, struct inode_operations *fs_dir_inode_o
                        }
        } else { /* not a directory */
                inode->i_mode = MSDOS_MKMODE(raw_entry->attr,
-                   ((IS_NOEXEC(inode) || !is_exec(raw_entry->ext))
+                   ((IS_NOEXEC(inode) || (MSDOS_SB(inode->i_sb)->showexec &&
+                                               !is_exec(raw_entry->ext)))
                        ? S_IRUGO|S_IWUGO : S_IRWXUGO)
                    & ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFREG;
                inode->i_op = (sb->s_blocksize == 1024)
index 7e8794259b841acf18142712d1316d53342057ea..9435fffaf328b24ad18fb305ba239150764bee0b 100644 (file)
@@ -151,7 +151,7 @@ void clear_inode(struct inode * inode)
 {
        struct wait_queue * wait;
 
-       invalidate_inode_pages(inode, 0);
+       truncate_inode_pages(inode, 0);
        wait_on_inode(inode);
        if (IS_WRITABLE(inode)) {
                if (inode->i_sb && inode->i_sb->dq_op)
index 19c00fb7307e130fd3339f7f0e486995594755f7..be43c491b1804dc6f0813c3c34c9312539c2789f 100644 (file)
@@ -11,6 +11,10 @@ O_TARGET := ncpfs.o
 O_OBJS   := dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o
 M_OBJS   := $(O_TARGET)
 
+# If you want debugging output, please uncomment the following line
+
+# EXTRA_CFLAGS += -DDEBUG_NCP=1
+
 include $(TOPDIR)/Rules.make
 
 ncplib_kernel.o: ncplib_kernel.c ncplib_kernel.h
index 3aa31ca08543e68a8751e3df80d0536468c2886f..272afc31d8b56b07ae17e5dd06e4921bf50738c6 100644 (file)
@@ -96,7 +96,7 @@ static struct file_operations ncp_dir_operations = {
        NULL,                   /* write - bad */
        ncp_readdir,            /* readdir */
        NULL,                   /* select - default */
-       ncp_ioctl,              /* ioctl - default */
+       ncp_ioctl,              /* ioctl */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
        NULL,                   /* no special release code */
@@ -159,6 +159,11 @@ ncp_readdir(struct inode *inode, struct file *filp,
                return -EBADF;
        }
 
+       if (!ncp_conn_valid(NCP_SERVER(inode)))
+       {
+               return -EIO;
+       }
+
        if (c_entry == NULL) 
        {
                i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE;
@@ -640,6 +645,11 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
                iput(dir);
                return -ENOENT;
        }
+       if (!ncp_conn_valid(NCP_SERVER(dir)))
+       {
+               iput(dir);
+               return -EIO;
+       }
 
         DDPRINTK("ncp_lookup: %s, len %d\n", __name, len);
 
@@ -772,6 +782,11 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
                iput(dir);
                return -ENOENT;
        }
+       if (!ncp_conn_valid(NCP_SERVER(dir)))
+       {
+               iput(dir);
+               return -EIO;
+       }
 
        strncpy(_name, name, len);
        _name[len] = '\0';
@@ -779,7 +794,8 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
 
        if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
                                           NCP_ISTRUCT(dir), _name,
-                                          OC_MODE_CREATE|OC_MODE_OPEN,
+                                          OC_MODE_CREATE|OC_MODE_OPEN|
+                                          OC_MODE_REPLACE,
                                           0, AR_READ|AR_WRITE,
                                           &finfo) != 0)
        {
@@ -828,6 +844,11 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
                iput(dir);
                return -ENOENT;
        }
+       if (!ncp_conn_valid(NCP_SERVER(dir)))
+       {
+               iput(dir);
+               return -EIO;
+       }
 
        if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
                                           NCP_ISTRUCT(dir), _name,
@@ -858,8 +879,14 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
                iput(dir);
                return -ENOENT;
        }
+       if (!ncp_conn_valid(NCP_SERVER(dir)))
+       {
+               iput(dir);
+               return -EIO;
+       }
         if (ncp_find_inode(dir, name) != NULL)
        {
+               iput(dir);
                 error = -EBUSY;
         }
        else
@@ -877,7 +904,7 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
                }
                else
                {
-                       error = -EINVAL;
+                       error = -EACCES;
                }
         }
        iput(dir);
@@ -896,8 +923,14 @@ ncp_unlink(struct inode *dir, const char *name, int len)
                iput(dir);
                return -ENOENT;
        }
+       if (!ncp_conn_valid(NCP_SERVER(dir)))
+       {
+               iput(dir);
+               return -EIO;
+       }
         if (ncp_find_inode(dir, name) != NULL)
        {
+               iput(dir);
                 error = -EBUSY;
         }
        else
@@ -914,7 +947,7 @@ ncp_unlink(struct inode *dir, const char *name, int len)
                }
                else
                {
-                       error = -EINVAL;
+                       error = -EACCES;
                }
         }
        iput(dir);
@@ -936,6 +969,12 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
                 goto finished;
        }
 
+       if (!ncp_conn_valid(NCP_SERVER(old_dir)))
+       {
+               res = -EIO;
+               goto finished;
+       }
+
        if (!new_dir || !S_ISDIR(new_dir->i_mode))
        {
                printk("ncp_rename: new inode is NULL or not a directory\n");
index e068e4c3c103d43e160f1714f9d3938cd16bdf84..e036b16518ccd555b19fbdd8fe8e3c7b5bed6f90 100644 (file)
@@ -93,6 +93,10 @@ ncp_file_read(struct inode *inode, struct file *file, char *buf, int count)
                DPRINTK("ncp_file_read: inode = NULL\n");
                return -EINVAL;
        }
+       if (!ncp_conn_valid(NCP_SERVER(inode)))
+       {
+               return -EIO;
+       }
 
        if (!S_ISREG(inode->i_mode))
        {
@@ -172,6 +176,10 @@ ncp_file_write(struct inode *inode, struct file *file, const char *buf,
                DPRINTK("ncp_file_write: inode = NULL\n");
                return -EINVAL;
        }
+       if (!ncp_conn_valid(NCP_SERVER(inode)))
+       {
+               return -EIO;
+       }
 
        if (!S_ISREG(inode->i_mode))
        {
index e86c78ca05e2905633fb3d17185b45599bcb0c11..9a86eec057f043becc0e40afdbedc37e12ffb142 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/config.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
@@ -20,6 +21,9 @@
 #include <linux/locks.h>
 #include <linux/fcntl.h>
 #include <linux/malloc.h>
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
 #include "ncplib_kernel.h"
 
 extern int close_fp(struct file *filp);
@@ -182,6 +186,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
         struct ncp_server *server;
        struct file *ncp_filp;
        struct file *wdog_filp;
+       struct file *msg_filp;
        kdev_t dev = sb->s_dev;
        int error;
 
@@ -197,6 +202,8 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
                printk("ncp warning: mount version %s than kernel\n",
                       (data->version < NCP_MOUNT_VERSION) ?
                        "older" : "newer");
+               sb->s_dev = 0;
+               return NULL;
        }
 
        if (   (data->ncp_fd >= NR_OPEN)
@@ -217,6 +224,15 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
                return NULL;
        }
 
+       if (   (data->message_fd >= NR_OPEN)
+           || ((msg_filp = current->files->fd[data->message_fd]) == NULL)
+           || (!S_ISSOCK(msg_filp->f_inode->i_mode)))
+       {
+               printk("ncp_read_super: invalid wdog socket\n");
+               sb->s_dev = 0;
+               return NULL;
+       }
+
         /* We must malloc our own super-block info */
         server = (struct ncp_server *)ncp_kmalloc(sizeof(struct ncp_server),
                                                    GFP_KERNEL);
@@ -229,6 +245,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
 
        ncp_filp->f_count += 1;
        wdog_filp->f_count += 1;
+       msg_filp->f_count += 1;
 
        lock_super(sb);
 
@@ -242,10 +259,12 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
 
        server->ncp_filp    = ncp_filp;
        server->wdog_filp   = wdog_filp;
+       server->msg_filp    = msg_filp;
        server->lock        = 0;
        server->wait        = NULL;
         server->packet      = NULL;
        server->buffer_size = 0;
+       server->conn_status = 0;
 
         server->m = *data;
        server->m.file_mode = (server->m.file_mode &
@@ -253,6 +272,9 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
        server->m.dir_mode  = (server->m.dir_mode &
                               (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
 
+       /* protect against invalid mount points */
+       server->m.mount_point[sizeof(server->m.mount_point)-1] = '\0';
+
        server->packet_size = NCP_PACKET_SIZE;
        server->packet      = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
 
@@ -278,6 +300,15 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
                goto fail;
        }
 
+       if (ncp_catch_message(server) != 0)
+       {
+               printk("ncp_read_super: Could not catch messages\n");
+               ncp_dont_catch_watchdog(server);
+               error = -EINVAL;
+               unlock_super(sb);
+               goto fail;
+       }
+
        ncp_lock_server(server);
        error = ncp_connect(server);
        ncp_unlock_server(server);
@@ -324,6 +355,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
  fail:
        ncp_filp->f_count -= 1;
        wdog_filp->f_count -= 1;
+       msg_filp->f_count -= 1;
         ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
         return NULL;
 }
@@ -343,6 +375,7 @@ ncp_put_super(struct super_block *sb)
 
        ncp_dont_catch_watchdog(server);
        close_fp(server->wdog_filp);
+       close_fp(server->msg_filp);
 
         ncp_free_all_inodes(server);
 
@@ -357,6 +390,32 @@ ncp_put_super(struct super_block *sb)
         MOD_DEC_USE_COUNT;
 }
 
+/* This routine is called from an interrupt in ncp_msg_data_ready. So
+ * we have to be careful NOT to sleep here! */
+void
+ncp_trigger_message(struct ncp_server *server)
+{
+       char command[ sizeof(server->m.mount_point)
+                    + sizeof(NCP_MSG_COMMAND) + 2];
+
+       if (server == NULL)
+       {
+               printk("ncp_trigger_message: invalid server!\n");
+               return;
+       }
+
+       DPRINTK("ncp_trigger_message: on %s\n",
+               server->m.mount_point);
+
+#ifdef CONFIG_KERNELD
+       strcpy(command, NCP_MSG_COMMAND);
+       strcat(command, " ");
+       strcat(command, server->m.mount_point);
+       DPRINTK("ksystem: %s\n", command);
+       ksystem(command, KERNELD_NOWAIT);
+#endif
+}
+
 static void 
 ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
 {
@@ -386,6 +445,11 @@ ncp_notify_change(struct inode *inode, struct iattr *attr)
        int info_mask;
        struct nw_modify_dos_info info;
 
+       if (!ncp_conn_valid(NCP_SERVER(inode)))
+       {
+               return -EIO;
+       }
+
        if ((result = inode_change_ok(inode, attr)) < 0)
                return result;
 
@@ -493,6 +557,7 @@ int init_ncp_fs(void)
 }
 
 #ifdef MODULE
+int
 init_module( void)
 {
        int status;
index d9489812d4649724551412403e4080e77616daf9..3e8e08fba51f908a7bf1d573ea3271a996274d33 100644 (file)
@@ -133,6 +133,11 @@ ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
 {
         DPRINTK("ncp_mmap: called\n");
 
+       if (!ncp_conn_valid(NCP_SERVER(inode)))
+       {
+               return -EIO;
+       }
+
         /* only PAGE_COW or read-only supported now */
        if (vma->vm_flags & VM_SHARED)  
                return -EINVAL;
index 782ed56bb2476a316216868d79b17b19d1a741e6..fe779b92f610a97725be3d0742e26a64c85742ae 100644 (file)
@@ -411,12 +411,18 @@ ncp_open_create_file_or_subdir(struct ncp_server *server,
                               struct nw_file_info *target)
 {
        int result;
+       __u16 search_attribs = 0x0006;
+
+       if ((create_attributes & aDIR) != 0)
+       {
+               search_attribs |= 0x8000;
+       }
 
        ncp_init_request(server);
        ncp_add_byte(server, 1); /* subfunction */
        ncp_add_byte(server, 0); /* dos name space */
        ncp_add_byte(server, open_create_mode);
-       ncp_add_word(server, 0x8006);
+       ncp_add_word(server, search_attribs);
        ncp_add_dword(server, RIM_ALL);
        ncp_add_dword(server, create_attributes);
        /* The desired acc rights seem to be the inherited rights mask
index 6fffbcf892d1d1ed5ec7ab0ddfd688d9de8f7f98..4e398d5c65baa69923cffa2ae01002e707737739 100644 (file)
@@ -93,13 +93,8 @@ ncp_wdog_data_ready(struct sock *sk, int len)
                    /* How to check connection number here? */
                    )
                {
-                       /* Error, throw away the complete packet */
-                       _recvfrom(sock, (void *)packet_buf, 2, 1, 0,
-                                 &sender, &addr_len);
-
                        printk("ncpfs: got strange packet on watchdog "
                               "socket\n");
-                       
                }
                else
                {
@@ -123,7 +118,6 @@ ncp_wdog_data_ready(struct sock *sk, int len)
        }
 }
 
-
 int
 ncp_catch_watchdog(struct ncp_server *server)
 {
@@ -146,7 +140,7 @@ ncp_catch_watchdog(struct ncp_server *server)
 
         if (sock->type != SOCK_DGRAM)
        {
-                printk("ncp_catch_watchdog: did not get SOCK_STREAM\n");
+                printk("ncp_catch_watchdog: did not get SOCK_DGRAM\n");
                 server->data_ready = NULL;
                 return -EINVAL;
         }
@@ -160,7 +154,7 @@ ncp_catch_watchdog(struct ncp_server *server)
                 return -EINVAL;
         }
 
-        DDPRINTK("ncp_catch_watchdog.: sk->d_r = %x, server->d_r = %x\n",
+        DDPRINTK("ncp_catch_watchdog: sk->d_r = %x, server->d_r = %x\n",
                  (unsigned int)(sk->data_ready),
                  (unsigned int)(server->data_ready));
 
@@ -198,11 +192,11 @@ ncp_dont_catch_watchdog(struct ncp_server *server)
 
         if (sock->type != SOCK_DGRAM)
        {
-                printk("ncp_dont_catch_watchdog: did not get SOCK_STREAM\n");
+                printk("ncp_dont_catch_watchdog: did not get SOCK_DGRAM\n");
                 return -EINVAL;
         }
 
-        sk   = (struct sock *)(sock->data);
+        sk = (struct sock *)(sock->data);
 
         if (sk == NULL)
        {
@@ -234,8 +228,88 @@ ncp_dont_catch_watchdog(struct ncp_server *server)
         return 0;
 }
 
+static void
+ncp_msg_data_ready(struct sock *sk, int len)
+{
+       struct socket *sock = sk->socket;
+
+       if (!sk->dead)
+       {
+               unsigned char packet_buf[2];
+               struct sockaddr_ipx sender;
+               int addr_len = sizeof(struct sockaddr_ipx);
+               int result;
+               unsigned short fs;
+
+               fs = get_fs();
+               set_fs(get_ds());
+
+               result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0,
+                                  &sender, &addr_len);
+
+               DPRINTK("ncpfs: got message of size %d from:\n", result);
+               DPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X,"
+                       " conn:%02X,type:%c\n",
+                       htonl(sender.sipx_network),
+                       sender.sipx_node[0], sender.sipx_node[1],
+                       sender.sipx_node[2], sender.sipx_node[3],
+                       sender.sipx_node[4], sender.sipx_node[5],
+                       ntohs(sender.sipx_port),
+                       packet_buf[0], packet_buf[1]);
+
+               ncp_trigger_message(sk->ipx_ncp_server);
+
+               set_fs(fs);
+       }
+}
+
+int
+ncp_catch_message(struct ncp_server *server)
+{
+        struct file   *file;
+        struct inode  *inode;
+        struct socket *sock;
+        struct sock   *sk;
+
+        if (   (server == NULL)
+            || ((file  = server->msg_filp) == NULL)
+            || ((inode = file->f_inode) == NULL)
+            || (!S_ISSOCK(inode->i_mode)))
+       {
+                printk("ncp_catch_message: did not get valid server!\n");
+                return -EINVAL;
+        }
+
+        sock = &(inode->u.socket_i);
+
+        if (sock->type != SOCK_DGRAM)
+       {
+                printk("ncp_catch_message: did not get SOCK_DGRAM\n");
+                return -EINVAL;
+        }
+
+        sk = (struct sock *)(sock->data);
+
+        if (sk == NULL)
+       {
+                printk("ncp_catch_message: sk == NULL");
+                return -EINVAL;
+        }
+
+        DDPRINTK("ncp_catch_message: sk->d_r = %x\n",
+                 (unsigned int)(sk->data_ready));
 
+        if (sk->data_ready == ncp_msg_data_ready)
+       {
+                printk("ncp_catch_message: already done\n");
+                return -EINVAL;
+        }
 
+        sk->data_ready = ncp_msg_data_ready;
+       sk->ipx_ncp_server = server;
+        return 0;
+}
+                
 #define NCP_SLACK_SPACE 1024
 
 #define _S(nr) (1<<((nr)-1))
@@ -474,13 +548,30 @@ do_ncp_rpc_call(struct ncp_server *server, int size)
 static int
 ncp_do_request(struct ncp_server *server, int size)
 {
+       int result;
+
        if (server->lock == 0)
        {
                printk("ncpfs: Server not locked!\n");
                return -EIO;
        }
 
-       return do_ncp_rpc_call(server, size);
+       if (!ncp_conn_valid(server))
+       {
+               return -EIO;
+       }
+
+       result = do_ncp_rpc_call(server, size);
+
+       DDPRINTK("do_ncp_rpc_call returned %d\n", result);
+
+       if (result < 0)
+       {
+               /* There was a problem with I/O, so the connections is
+                 * no longer usable. */
+               ncp_invalidate_conn(server);
+       }
+       return result;
 }
 
 /* ncp_do_request assures that at least a complete reply header is
index 59c740d6632555bcb53643721c54111526de7276..d1eca88845d73cc0c374c25e768fad2720569ec4 100644 (file)
@@ -81,7 +81,7 @@ static inline void revalidate_inode(struct nfs_server * server, struct inode * i
                        return;
                NFS_OLDMTIME(inode) = fattr.mtime.seconds;
        }
-       invalidate_inode_pages(inode, 0);
+       invalidate_inode_pages(inode);
 }
 
 
@@ -118,18 +118,15 @@ static inline void do_read_nfs(struct inode * inode, char * buf, unsigned long p
                result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode), 
                        pos, rsize, buf, &fattr);
                if (result < 0)
-                       goto partial;
+                       break;
                refresh = 1;
-               count -= rsize;
-               pos += rsize;
-               buf += rsize;
+               count -= result;
+               pos += result;
+               buf += result;
                if (result < rsize)
-                       goto partial;
+                       break;
        } while (count);
-       nfs_refresh_inode(inode, &fattr);
-       return;
 
-partial:
        memset(buf, 0, count);
        if (refresh)
                nfs_refresh_inode(inode, &fattr);
index 9d04e72b1c40a9c85826db7df452da64c61e2b2a..aa13b7845a91e63f0c54d812602c2a718715a468 100644 (file)
@@ -272,14 +272,34 @@ static int get_uptime(char * buffer)
 static int get_meminfo(char * buffer)
 {
        struct sysinfo i;
+       int len;
 
        si_meminfo(&i);
        si_swapinfo(&i);
-       return sprintf(buffer, "        total:    used:    free:  shared: buffers:  cached:\n"
+       len = sprintf(buffer, "        total:    used:    free:  shared: buffers:  cached:\n"
                "Mem:  %8lu %8lu %8lu %8lu %8lu %8lu\n"
                "Swap: %8lu %8lu %8lu\n",
                i.totalram, i.totalram-i.freeram, i.freeram, i.sharedram, i.bufferram, page_cache_size*PAGE_SIZE,
                i.totalswap, i.totalswap-i.freeswap, i.freeswap);
+       /*
+        * Tagged format, for easy grepping and expansion. The above will go away
+        * eventually, once the tools have been updated.
+        */
+       return len + sprintf(buffer+len,
+               "MemTotal:  %8lu kB\n"
+               "MemFree:   %8lu kB\n"
+               "MemShared: %8lu kB\n"
+               "Buffers:   %8lu kB\n"
+               "Cached:    %8lu kB\n"
+               "SwapTotal: %8lu kB\n"
+               "SwapFree:  %8lu kB\n",
+               i.totalram >> 10,
+               i.freeram >> 10,
+               i.sharedram >> 10,
+               i.bufferram >> 10,
+               page_cache_size << (PAGE_SHIFT - 10),
+               i.totalswap >> 10,
+               i.freeswap >> 10);
 }
 
 static int get_version(char * buffer)
@@ -452,6 +472,164 @@ static unsigned long get_wchan(struct task_struct *p)
 # define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
 #endif
 
+/* Gcc optimizes away "strlen(x)" for constant x */
+#define ADDBUF(buffer, string) \
+do { memcpy(buffer, string, strlen(string)); \
+     buffer += strlen(string); } while (0)
+
+static inline char * task_name(struct task_struct *p, char * buf)
+{
+       int i;
+       char * name;
+
+       ADDBUF(buf, "Name:\t");
+       name = p->comm;
+       i = sizeof(p->comm);
+       do {
+               unsigned char c = *name;
+               name++;
+               i--;
+               *buf = c;
+               if (!c)
+                       break;
+               if (c == '\\') {
+                       buf[1] = c;
+                       buf += 2;
+                       continue;
+               }
+               if (c == '\n') {
+                       buf[0] = '\\';
+                       buf[1] = 'n';
+                       buf += 2;
+                       continue;
+               }
+               buf++;
+       } while (i);
+       *buf = '\n';
+       return buf+1;
+}
+
+static inline char * task_state(struct task_struct *p, char *buffer)
+{
+#define NR_STATES (sizeof(states)/sizeof(const char *))
+       unsigned int n = p->state;
+       static const char * states[] = {
+               "R (running)",
+               "S (sleeping)",
+               "D (disk sleep)",
+               "Z (zombie)",
+               "T (stopped)",
+               "W (paging)",
+               ". Huh?"
+       };
+
+       if (n >= NR_STATES)
+               n = NR_STATES-1;
+
+       buffer += sprintf(buffer,
+               "State:\t%s\n"
+               "Pid:\t%d\n"
+               "PPid:\t%d\n"
+               "Uid:\t%d\t%d\t%d\t%d\n"
+               "Gid:\t%d\t%d\t%d\t%d\n",
+               states[n],
+               p->pid, p->p_pptr->pid,
+               p->uid, p->euid, p->suid, p->fsuid,
+               p->gid, p->egid, p->sgid, p->fsgid);
+       return buffer;
+}
+
+static inline char * task_mem(struct task_struct *p, char *buffer)
+{
+       struct mm_struct * mm = p->mm;
+
+       if (mm && mm != &init_mm) {
+               struct vm_area_struct * vma = mm->mmap;
+               unsigned long data = 0, stack = 0;
+               unsigned long exec = 0, lib = 0;
+
+               for (vma = mm->mmap; vma; vma = vma->vm_next) {
+                       unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
+                       if (!vma->vm_inode) {
+                               data += len;
+                               if (vma->vm_flags & VM_GROWSDOWN)
+                                       stack += len;
+                               continue;
+                       }
+                       if (vma->vm_flags & VM_WRITE)
+                               continue;
+                       if (vma->vm_flags & VM_EXEC) {
+                               exec += len;
+                               if (vma->vm_flags & VM_EXECUTABLE)
+                                       continue;
+                               lib += len;
+                       }
+               }       
+               buffer += sprintf(buffer,
+                       "VmSize:\t%8lu kB\n"
+                       "VmLck:\t%8lu kB\n"
+                       "VmRSS:\t%8lu kB\n"
+                       "VmData:\t%8lu kB\n"
+                       "VmStk:\t%8lu kB\n"
+                       "VmExe:\t%8lu kB\n"
+                       "VmLib:\t%8lu kB\n",
+                       mm->total_vm << (PAGE_SHIFT-10),
+                       mm->locked_vm << (PAGE_SHIFT-10),
+                       mm->rss << (PAGE_SHIFT-10),
+                       data - stack, stack,
+                       exec - lib, lib);
+       }
+       return buffer;
+}
+
+static inline char * task_sig(struct task_struct *p, char *buffer)
+{
+       buffer += sprintf(buffer,
+               "SigPnd:\t%08lx\n"
+               "SigBlk:\t%08lx\n",
+               p->signal, p->blocked);
+       if (p->sig) {
+               struct sigaction * action = p->sig->action;
+               unsigned long sig_ign = 0, sig_caught = 0;
+               unsigned long bit = 1;
+               int i;
+
+               for (i = 0; i < 32; i++) {
+                       switch((unsigned long) action->sa_handler) {
+                               case 0:
+                                       break;
+                               case 1:
+                                       sig_ign |= bit;
+                                       break;
+                               default:
+                                       sig_caught |= bit;
+                       }
+                       bit <<= 1;
+                       action++;
+               }
+               
+               buffer += sprintf(buffer,
+                       "SigIgn:\t%08lx\n"
+                       "SigCgt:\t%08lx\n",
+                       sig_ign, sig_caught);
+       }
+       return buffer;
+}
+
+static int get_status(int pid, char * buffer)
+{
+       char * orig = buffer;
+       struct task_struct ** p = get_task(pid), *tsk;
+
+       if (!p || (tsk = *p) == NULL)
+               return 0;
+       buffer = task_name(tsk, buffer);
+       buffer = task_state(tsk, buffer);
+       buffer = task_mem(tsk, buffer);
+       buffer = task_sig(tsk, buffer);
+       return buffer - orig;
+}
+
 static int get_stat(int pid, char * buffer)
 {
        struct task_struct ** p = get_task(pid), *tsk;
@@ -857,6 +1035,8 @@ static int get_root_array(char * page, int type, char **start, off_t offset, int
 static int get_process_array(char * page, int pid, int type)
 {
        switch (type) {
+               case PROC_PID_STATUS:
+                       return get_status(pid, page);
                case PROC_PID_ENVIRON:
                        return get_env(pid, page);
                case PROC_PID_CMDLINE:
index c28cd56d56d7e293c10e22703a219550614ecd02..a2a933f78844722a0eb44537b2f90926dcb04bed 100644 (file)
@@ -82,6 +82,12 @@ struct proc_dir_entry proc_pid = {
 
 void proc_base_init(void)
 {
+       proc_register(&proc_pid, &(struct proc_dir_entry) {
+               PROC_PID_STATUS, 6, "status",
+               S_IFREG | S_IRUGO, 1, 0, 0,
+               0, &proc_array_inode_operations,
+               NULL, proc_pid_fill_inode,
+       });
        proc_register(&proc_pid, &(struct proc_dir_entry) {
                PROC_PID_MEM, 3, "mem",
                S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0,
index f10768a8829c278e6cd2120617afd13aec4469e8..99b2712ec49b3600ce4dff55a3ce490655605b15 100644 (file)
@@ -222,6 +222,7 @@ void proc_read_inode(struct inode * inode)
                        inode->i_op = &proc_array_inode_operations;
                        return;
                case PROC_PID_CMDLINE:
+               case PROC_PID_STATUS:
                case PROC_PID_STAT:
                case PROC_PID_STATM:
                        inode->i_mode = S_IFREG | S_IRUGO;
index ed2fb5ef30f356b7cc8f73c5cd11946feb13fd8b..a4af92b215da0615cd9e307d80986c85d31bd931 100644 (file)
@@ -546,7 +546,7 @@ extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag)
 
 extern int check_disk_change(kdev_t dev);
 extern void invalidate_inodes(kdev_t dev);
-extern void invalidate_inode_pages(struct inode *, unsigned long);
+extern void invalidate_inode_pages(struct inode *);
 extern void invalidate_buffers(kdev_t dev);
 extern int floppy_is_wp(int minor);
 extern void sync_inodes(kdev_t dev);
index b1ecd0750288466db113940cf619df58952a469d..a20cbe8ee425bce45beed1a4e2b0b7d460c3183e 100644 (file)
@@ -2,7 +2,7 @@
 #ifndef _LINUX_INTERRUPT_H
 #define _LINUX_INTERRUPT_H
 
-#include <linux/linkage.h>
+#include <linux/kernel.h>
 #include <asm/bitops.h>
 
 struct bh_struct {
@@ -49,10 +49,12 @@ extern inline void enable_bh(int nr)
 extern inline void start_bh_atomic(void)
 {
        intr_count++;
+       barrier();
 }
 
 extern inline void end_bh_atomic(void)
 {
+       barrier();
        intr_count--;
 }
 
index 26dd68ef4a130e280dbe91899b8694bd97a3f7dc..74ecd8140c7ca05fe6f4e3d43289c9135ee7086a 100644 (file)
@@ -10,6 +10,9 @@
 #include <stdarg.h>
 #include <linux/linkage.h>
 
+/* Optimization barrier */
+#define barrier() __asm__("": : :"memory")
+
 #define INT_MAX                ((int)(~0U>>1))
 #define UINT_MAX       (~0U)
 #define LONG_MAX       ((long)(~0UL>>1))
index 2001acc19881a3c9d697a0a9a6988c9cc324a1f1..d024f7dfbcd39029f5f746c7f4e72157de6e678a 100644 (file)
@@ -223,6 +223,7 @@ extern unsigned long get_unmapped_area(unsigned long, unsigned long);
 /* filemap.c */
 extern unsigned long page_unuse(unsigned long);
 extern int shrink_mmap(int, unsigned long);
+extern void truncate_inode_pages(struct inode *, unsigned long);
 
 #define GFP_BUFFER     0x00
 #define GFP_ATOMIC     0x01
index 8eac5a077214f8eb510fac18a8c5306eac425f34..ea9214566de0094b48312b2e7f9a5899b82e8dc5 100644 (file)
@@ -23,6 +23,7 @@ struct msdos_sb_info {
        int prev_free; /* previously returned free cluster number */
        int free_clusters; /* -1 if undefined */
        char dotsOK;
+       char showexec; /* 1 = only set x bit for com/exe/bat */
        char sys_immutable; /* system files are immutable */
        int vfat; /* 0=no vfat long filename support, 1=vfat support */
        int umsdos; /* 1 if mounted by umsdos, 0 if not */
index 1d8235b17117f38697927c75515ca522d7ce8345..d53cd7f2cceeb0e3e685016c3d3d7b88ef009161 100644 (file)
@@ -54,6 +54,8 @@ struct ncp_fs_info {
 #define NCP_MAXPATHLEN 255
 #define NCP_MAXNAMELEN 14
 
+#define NCP_MSG_COMMAND "/sbin/nwmsg"
+
 #ifdef __KERNEL__
 
 /* The readdir cache size controls how many directory entries are
@@ -145,6 +147,7 @@ struct super_block *ncp_read_super(struct super_block *sb,
 extern int init_ncp_fs(void);
 void ncp_invalidate_connection(struct ncp_server *server);
 int ncp_conn_is_valid(struct ncp_server *server);
+void ncp_trigger_message(struct ncp_server *server);
 
 /* linux/fs/ncpfs/sock.c */
 int ncp_request(struct ncp_server *server, int function);
@@ -152,6 +155,7 @@ int ncp_connect(struct ncp_server *server);
 int ncp_disconnect(struct ncp_server *server);
 int ncp_catch_watchdog(struct ncp_server *server);
 int ncp_dont_catch_watchdog(struct ncp_server *server);
+int ncp_catch_message(struct ncp_server *server);
 void ncp_lock_server(struct ncp_server *server);
 void ncp_unlock_server(struct ncp_server *server);
 
index fc5e9553ee5b33474e1f3f9cc68e6e921449a8bd..0a5497e369ae466e497640d6f8f423e3b9559f42 100644 (file)
@@ -22,8 +22,8 @@ struct ncp_server {
                                    it completely. */
 
        struct file *ncp_filp;  /* File pointer to ncp socket */
-
        struct file *wdog_filp; /* File pointer to wdog socket */
+       struct file *msg_filp;  /* File pointer to message socket */
        void *data_ready;       /* The wdog socket gets a new
                                   data_ready callback. We store the
                                   old one for checking purposes and
@@ -35,7 +35,8 @@ struct ncp_server {
 
        u8         completion;  /* Status message from server */
        u8         conn_status; /* Bit 4 = 1 ==> Server going down, no
-                                  requests allowed anymore */
+                                  requests allowed anymore.
+                                  Bit 0 = 1 ==> Server is down. */
 
        int        buffer_size; /* Negotiated bufsize */
 
@@ -56,6 +57,18 @@ struct ncp_server {
        char       root_path;   /* '\0' */
 };
 
+static inline int
+ncp_conn_valid(struct ncp_server *server)
+{
+       return ((server->conn_status & 0x11) == 0);
+}
+
+static inline void
+ncp_invalidate_conn(struct ncp_server *server)
+{
+       server->conn_status |= 0x01;
+}
+
 #endif /* __KERNEL__ */
 
 #endif
index 83007befb5c54e2bcf9d72fe4c949893e0e72fea..39d11b7d7d14f23e063690376b8df60d2edc8834 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/ncp.h>
 #include <linux/ncp_fs_i.h>
 
-#define NCP_MOUNT_VERSION 1
+#define NCP_MOUNT_VERSION 2
 
 #define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN)
 #define NCP_PASSWORD_LEN 20
@@ -30,10 +30,10 @@ struct ncp_mount_data {
         uid_t mounted_uid;      /* Who may umount() this filesystem? */
 
        struct sockaddr_ipx serv_addr;
-       unsigned char server_name[49];
+       unsigned char server_name[NCP_BINDERY_NAME_LEN];
 
-       unsigned char username[NCP_USERNAME_LEN+1];
-       unsigned char password[NCP_PASSWORD_LEN+1];
+       unsigned char mount_point[PATH_MAX+1];
+       unsigned char mounted_vol[NCP_VOLNAME_LEN+1];
 
        unsigned int time_out;  /* How long should I wait after
                                   sending a NCP request? */
index e6a69dd3db0825098c8e321f55eff97319292117..56daca14ea6b3b406d341a3b79e1925cd27d29b4 100644 (file)
 #define MAX_ADDR_LEN   7
 #ifndef CONFIG_AX25
 #ifndef CONFIG_TR
+#ifndef CONFIG_NET_IPIP
 #define MAX_HEADER     32              /* We really need about 18 worst case .. so 32 is aligned */
 #else
+#define MAX_HEADER     48              /* We need to allow for having tunnel headers */
+#endif  /* IPIP */
+#else
 #define MAX_HEADER     48              /* Token Ring header needs 40 bytes ... 48 is aligned */ 
-#endif
+#endif /* TR */
 #else
 #define MAX_HEADER     96              /* AX.25 + NetROM */
-#endif
+#endif /* AX25 */
 
 #define IS_MYADDR      1               /* address is (one of) our own  */
 #define IS_LOOPBACK    2               /* address is for LOOPBACK      */
index ff7c14ca1c43958642d683ed0b64c9174d9b4719..9e059501fd4fe4460081e3e0c2d280486f5565c4 100644 (file)
 #define PCI_DEVICE_ID_OPTI_82C822      0xc822
 
 #define PCI_VENDOR_ID_SGS              0x104a
+#define PCI_DEVICE_ID_SGS_2000         0x0008
+#define PCI_DEVICE_ID_SGS_1764         0x0009
 
 #define PCI_VENDOR_ID_BUSLOGIC         0x104B
 #define PCI_DEVICE_ID_BUSLOGIC_946C_2  0x0140
 #define PCI_DEVICE_ID_TEKRAM2_690c     0x690c
 
 #define PCI_VENDOR_ID_AMCC             0x10e8
+#define PCI_DEVICE_ID_AMCC_MYRINET     0x8043
 
 #define PCI_VENDOR_ID_INTERG           0x10ea
 #define PCI_DEVICE_ID_INTERG_1680      0x1680
 #define PCI_DEVICE_ID_SPECIALIX_XIO    0x4000
 #define PCI_DEVICE_ID_SPECIALIX_RIO    0x8000
 
+#define PCI_VENDOR_ID_RP               0x11fe
+#define PCI_DEVICE_ID_RP8OCTA          0x0001
+#define PCI_DEVICE_ID_RP8INTF          0x0002
+#define PCI_DEVICE_ID_RP16INTF         0x0003
+#define PCI_DEVICE_ID_RP32INTF         0x0004
+
 #define PCI_VENDOR_ID_CYCLADES         0x120e
 #define PCI_DEVICE_ID_CYCLADES_Y       0x0100
 
index 9d702e4860c70830974dd63a8f98320cd3e5aa15..cc674c9b9130ce8dba1d8da2dfc3c014f04aea29 100644 (file)
@@ -46,6 +46,7 @@ enum root_directory_inos {
 
 enum pid_directory_inos {
        PROC_PID_INO = 2,
+       PROC_PID_STATUS,
        PROC_PID_MEM,
        PROC_PID_CWD,
        PROC_PID_ROOT,
index b220fa62bdc67912d29815ab7845dc5e2f1df863..fa6977d99a3f2ee2d67e386c87fe8f553d5536cc 100644 (file)
@@ -185,7 +185,7 @@ struct scc_stat {
 };
 
 
-struct scc_modem{
+struct scc_modem {
        long speed;             /* Line speed, bps */
        char clocksrc;          /* 0 = DPLL, 1 = external, 2 = divider */
        char nrz;               /* NRZ instead of NRZI */       
index 7f5fecf88ab4de3ad8081f8c81d628f107b543d7..7eceb1f8dd474c93acb1d7fa33569f86b40f6381 100644 (file)
@@ -104,8 +104,6 @@ struct sched_param {
 
 #ifdef __KERNEL__
 
-#define barrier() __asm__("": : :"memory")
-
 extern void sched_init(void);
 extern void show_state(void);
 extern void trap_init(void);
index edfbc508b3a02971e14200a3a14b685d5b605637..45967cb191e653663c1a1a4ebd2cc85efd58cf6b 100644 (file)
@@ -203,6 +203,7 @@ extern int  ax25_rt_get_info(char *, char **, off_t, int, int);
 extern int  ax25_cs_get_info(char *, char **, off_t, int, int);
 extern int  ax25_rt_autobind(ax25_cb *, ax25_address *);
 extern void ax25_rt_build_path(ax25_cb *, ax25_address *);
+extern void ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *);
 extern void ax25_rt_device_down(struct device *);
 extern int  ax25_rt_ioctl(unsigned int, void *);
 extern void ax25_ip_mode_set(ax25_address *, struct device *, char);
index 1b52a0da73610fef2e356c219fa56e082283895f..dc7a4a90ac753d923783f4d56caf9fb04e7c8f23 100644 (file)
@@ -197,6 +197,12 @@ struct sock
        ipx_address             ipx_dest_addr;
        ipx_interface           *ipx_intrfc;
        unsigned short          ipx_port;
+
+/* To handle asynchronous messages from the NetWare server, we have to
+ * know the connection this socket belongs to. Sorry to blow up this
+ * structure even more. */
+       struct ncp_server       *ipx_ncp_server;
+
 #ifdef CONFIG_IPX_INTERN
        unsigned char           ipx_node[IPX_NODE_LEN];
 #endif
index 34c03a8d2530f22d7934e45912564908bc2263e2..3708eff49182156ce0f12f2b77ce0fb9f7ec5ab5 100644 (file)
@@ -180,6 +180,7 @@ struct symbol_table symbol_table = {
        X(check_disk_change),
        X(invalidate_buffers),
        X(invalidate_inodes),
+       X(invalidate_inode_pages),
        X(fsync_dev),
        X(permission),
        X(inode_setattr),
@@ -192,6 +193,7 @@ struct symbol_table symbol_table = {
        X(__bforget),
        X(ll_rw_block),
        X(__wait_on_buffer),
+       X(__wait_on_page),
        X(mark_buffer_uptodate),
        X(unlock_buffer),
        X(dcache_lookup),
index 638cea65b8613bd141dfda919d353b0b2401046b..e41524bc04814478f3d6839d0219222196c18c15 100644 (file)
@@ -41,7 +41,40 @@ struct page * page_hash_table[PAGE_HASH_SIZE];
  * Simple routines for both non-shared and shared mappings.
  */
 
-void invalidate_inode_pages(struct inode * inode, unsigned long start)
+/*
+ * Invalidate the pages of an inode, removing all pages that aren't
+ * locked down (those are sure to be up-to-date anyway, so we shouldn't
+ * invalidate them).
+ */
+void invalidate_inode_pages(struct inode * inode)
+{
+       struct page ** p;
+       struct page * page;
+
+       p = &inode->i_pages;
+       while ((page = *p) != NULL) {
+               if (page->locked) {
+                       p = &page->next;
+                       continue;
+               }
+               inode->i_nrpages--;
+               if ((*p = page->next) != NULL)
+                       (*p)->prev = page->prev;
+               page->dirty = 0;
+               page->next = NULL;
+               page->prev = NULL;
+               remove_page_from_hash_queue(page);
+               page->inode = NULL;
+               free_page(page_address(page));
+               continue;
+       }
+}
+
+/*
+ * Truncate the page cache at a set offset, removing the pages
+ * that are beyond that offset (and zeroing out partial pages).
+ */
+void truncate_inode_pages(struct inode * inode, unsigned long start)
 {
        struct page ** p;
        struct page * page;
@@ -261,14 +294,12 @@ repeat:
  * inode->i_op->readpage() function for the actual low-level
  * stuff.
  */
-#define READAHEAD_PAGES 3
-#define MAX_IO_PAGES 4
+#define MAX_READAHEAD (PAGE_SIZE*4)
 int generic_file_read(struct inode * inode, struct file * filp, char * buf, int count)
 {
-       int read = 0, newpage = 0;
+       int read = 0;
        unsigned long pos;
        unsigned long page_cache = 0;
-       int pre_read = 0;
        
        if (count <= 0)
                return 0;
@@ -277,8 +308,6 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
        do {
                struct page *page;
                unsigned long offset, addr, nr;
-               int i;
-               off_t p;
 
                if (pos >= inode->i_size)
                        break;
@@ -326,48 +355,29 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
                add_page_to_hash_queue(inode, page);
 
                inode->i_op->readpage(inode, page);
-               /* We only set "newpage" when we encounter a
-                   completely uncached page.  This way, we do no
-                   readahead if we are still just reading data out of
-                   the cache (even if the cached page is not yet
-                   uptodate --- it may be currently being read as a
-                   result of previous readahead).  -- sct */
-               newpage = 1;
 
 found_page:
                addr = page_address(page);
                if (nr > count)
                        nr = count;
-               /* We have two readahead cases.  First, do data
-                   pre-read if the current read request is for more
-                   than one page, so we can merge the adjacent
-                   requests. */
-               if (newpage && nr < count) {
-                       if (pre_read > 0)
-                               pre_read -= PAGE_SIZE;
-                       else {
-                               pre_read = (MAX_IO_PAGES-1) * PAGE_SIZE;
-                               if (pre_read > (count - nr))
-                                       pre_read = count - nr;
-                               for (i=0, p=pos; i<pre_read; i+=PAGE_SIZE) {
-                                       p += PAGE_SIZE;
-                                       page_cache = try_to_read_ahead(inode, p, page_cache);
-                               }
-                       }
-               }
-               else
-               /* Second, do readahead at the end of the read, if we
-                   are still waiting on the current IO to complete, if
-                   readahead is flagged for the file, and if we have
-                   finished with the current block. */
-               if (newpage && nr == count && filp->f_reada
-                   && !((pos + nr) & ~PAGE_MASK)) {
-                       for (i=0, p=pos; i<READAHEAD_PAGES; i++) {
-                               p += PAGE_SIZE;
-                               page_cache = try_to_read_ahead(inode, p, page_cache);
+
+               /*
+                * We may want to do read-ahead.. Do this only
+                * if we're waiting for the current page to be
+                * filled in, and if
+                *  - we're going to read more than this page
+                *  - if "f_reada" is set
+                */
+               if (page->locked) {
+                       if (nr < count || filp->f_reada) {
+                               unsigned long ahead = 0;
+                               do {
+                                       ahead += PAGE_SIZE;
+                                       page_cache = try_to_read_ahead(inode, pos + ahead, page_cache);
+                               } while (ahead < MAX_READAHEAD);
                        }
+                       __wait_on_page(page);
                }
-               wait_on_page(page);
                if (nr > inode->i_size - pos)
                        nr = inode->i_size - pos;
                memcpy_tofs(buf, (void *) (addr + offset), nr);
index e025d5404a70d32d9008e9cd7c8d9e577ba3d480..9b2444488b53a1b04726dbcbfc059f6c6566e285 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/system.h>
 #include <asm/segment.h>
 #include <asm/pgtable.h>
+#include <asm/string.h>
 
 unsigned long high_memory = 0;
 
@@ -177,13 +178,12 @@ void free_page_tables(struct task_struct * tsk)
 int new_page_tables(struct task_struct * tsk)
 {
        pgd_t * page_dir, * new_pg;
-       int i;
 
        if (!(new_pg = pgd_alloc()))
                return -ENOMEM;
        page_dir = pgd_offset(&init_mm, 0);
-       for (i = USER_PTRS_PER_PGD ; i < PTRS_PER_PGD ; i++)
-               new_pg[i] = page_dir[i];
+       memcpy(new_pg + USER_PTRS_PER_PGD, page_dir + USER_PTRS_PER_PGD,
+              (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof (pgd_t));
        invalidate_mm(tsk->mm);
        SET_PAGE_DIR(tsk, new_pg);
        tsk->mm->pgd = new_pg;
@@ -801,7 +801,7 @@ void vmtruncate(struct inode * inode, unsigned long offset)
 {
        struct vm_area_struct * mpnt;
 
-       invalidate_inode_pages(inode, offset);
+       truncate_inode_pages(inode, offset);
        if (!inode->i_mmap)
                return;
        mpnt = inode->i_mmap;
index ea6153562af7824a2d20973592b977ee08d95ecd..eb60235a408380871f7078c2c171bb611f2c56de 100644 (file)
@@ -571,8 +571,8 @@ static ax25_cb *ax25_create_cb(void)
 
        ax25->state    = AX25_STATE_0;
 
-       memset(&ax25->dest_addr,   '\0', sizeof(ax25_address));
-       memset(&ax25->source_addr, '\0', sizeof(ax25_address));
+       memset(&ax25->dest_addr,   '\0', AX25_ADDR_LEN);
+       memset(&ax25->source_addr, '\0', AX25_ADDR_LEN);
 
        return ax25;
 }
@@ -583,18 +583,17 @@ static ax25_cb *ax25_create_cb(void)
  *
  *     dl1bke 951121
  */
 int ax25_dev_is_dama_slave(struct device *dev)
 {
-       ax25_cb * ax25;
+       ax25_cb *ax25;
        int count = 0;
        
-       for (ax25=ax25_list; ax25 ; ax25 = ax25->next)
-               if ( (ax25->device == dev) && ax25->dama_slave )
-               {
+       for (ax25 = ax25_list; ax25 != NULL; ax25 = ax25->next) {
+               if (ax25->device == dev && ax25->dama_slave) {
                        count++;
                        break;
                }
+       }
                
        return count;
 }
@@ -652,15 +651,15 @@ int ax25_send_frame(struct sk_buff *skb, ax25_address *src, ax25_address *dest,
 
        ax25_fillin_cb(ax25, dev);
 
-       memcpy(&ax25->source_addr, src,  sizeof(ax25_address));
-       memcpy(&ax25->dest_addr,   dest, sizeof(ax25_address));
+       ax25->source_addr = *src;
+       ax25->dest_addr   = *dest;
 
        if (digi != NULL) {
                if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
                        kfree_s(ax25, sizeof(ax25));
                        return 0;
                }
-               memcpy(ax25->digipeat, digi, sizeof(ax25_digi));
+               *ax25->digipeat = *digi;
        } else {
                ax25_rt_build_path(ax25, dest);
        }
@@ -668,7 +667,7 @@ int ax25_send_frame(struct sk_buff *skb, ax25_address *src, ax25_address *dest,
        if (ax25_dev_is_dama_slave(ax25->device))       /* dl1bke 960116 */
                dama_establish_data_link(ax25);
        else
-       ax25_establish_data_link(ax25);
+               ax25_establish_data_link(ax25);
                
        ax25_insert_socket(ax25);
 
@@ -995,8 +994,7 @@ static struct sock *ax25_make_new(struct sock *osk, struct device *dev)
        sk->type   = osk->type;
        sk->socket = osk->socket;
 
-       switch(osk->type)
-       {
+       switch (osk->type) {
                case SOCK_DGRAM:
                        break;
                case SOCK_SEQPACKET:
@@ -1051,7 +1049,7 @@ static struct sock *ax25_make_new(struct sock *osk, struct device *dev)
 
        ax25->window  = osk->ax25->window;
 
-       memcpy(&ax25->source_addr, &osk->ax25->source_addr, sizeof(ax25_address));
+       ax25->source_addr = osk->ax25->source_addr;
        
        if (osk->ax25->digipeat != NULL) {
                if ((ax25->digipeat = (ax25_digi *)kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
@@ -1061,7 +1059,7 @@ static struct sock *ax25_make_new(struct sock *osk, struct device *dev)
                }
                
                /* dl1bke 960119: we have to copy the old digipeater list! */
-               memcpy(ax25->digipeat, osk->ax25->digipeat, sizeof(ax25_digi));
+               *ax25->digipeat = *osk->ax25->digipeat;
        }
 
        sk->ax25 = ax25;
@@ -1105,7 +1103,7 @@ static int ax25_release(struct socket *sock, struct socket *peer)
                                if (sk->ax25->dama_slave)
                                        ax25_send_control(sk->ax25, DISC, POLLON, C_COMMAND);
                                else
-                               ax25_send_control(sk->ax25, DM, POLLON, C_RESPONSE);
+                                       ax25_send_control(sk->ax25, DM, POLLON, C_RESPONSE);
                                sk->ax25->state = AX25_STATE_0;
                                sk->state       = TCP_CLOSE;
                                sk->state_change(sk);
@@ -1118,7 +1116,7 @@ static int ax25_release(struct socket *sock, struct socket *peer)
                                ax25_clear_queues(sk->ax25);
                                sk->ax25->n2count = 0;
                                if (!sk->ax25->dama_slave)
-                               ax25_send_control(sk->ax25, DISC, POLLON, C_COMMAND);
+                                       ax25_send_control(sk->ax25, DISC, POLLON, C_COMMAND);
                                sk->ax25->t3timer = 0;
                                sk->ax25->t1timer = sk->ax25->t1 = ax25_calculate_t1(sk->ax25);
                                sk->ax25->state   = AX25_STATE_2;
@@ -1170,9 +1168,9 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
                return -EPERM;
                
        if (call == NULL)
-               memcpy(&sk->ax25->source_addr, &addr->fsa_ax25.sax25_call, sizeof(ax25_address));
+               sk->ax25->source_addr = addr->fsa_ax25.sax25_call;
        else
-               memcpy(&sk->ax25->source_addr, call, sizeof(ax25_address));
+               sk->ax25->source_addr = *call;
 
        if (sk->debug)
                printk("AX25: source address set to %s\n", ax2asc(&sk->ax25->source_addr));
@@ -1258,14 +1256,12 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr,
 
                while (ct < addr->sax25_ndigis) {
                        sk->ax25->digipeat->repeated[ct] = 0;
-                       memcpy(&sk->ax25->digipeat->calls[ct], &fsa->fsa_digipeater[ct], sizeof(ax25_address));
+                       sk->ax25->digipeat->calls[ct] = fsa->fsa_digipeater[ct];
                        ct++;
                }
 
                sk->ax25->digipeat->lastrepeat = 0;
-       }
-       else
-       { /* dl1bke 960117 */
+       } else { /* dl1bke 960117 */
                if (sk->debug)
                        printk("building digipeater path\n");
                ax25_rt_build_path(sk->ax25, &addr->sax25_call);
@@ -1289,7 +1285,7 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr,
        if (sk->type == SOCK_SEQPACKET && ax25_find_cb(&sk->ax25->source_addr, &addr->sax25_call, sk->ax25->device) != NULL)
                return -EBUSY;                          /* Already such a connection */
 
-       memcpy(&sk->ax25->dest_addr, &addr->sax25_call, sizeof(ax25_address));
+       sk->ax25->dest_addr = addr->sax25_call;
        
        /* First the easy one */
        if (sk->type != SOCK_SEQPACKET) {
@@ -1305,7 +1301,7 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr,
        if (ax25_dev_is_dama_slave(sk->ax25->device))
                dama_establish_data_link(sk->ax25);
        else
-       ax25_establish_data_link(sk->ax25);
+               ax25_establish_data_link(sk->ax25);
                
        sk->ax25->state     = AX25_STATE_1;
        ax25_set_timer(sk->ax25);               /* Start going SABM SABM until a UA or a give up and DM */
@@ -1415,7 +1411,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
        }
                
        sax->fsa_ax25.sax25_family = AF_AX25;
-       memcpy(&sax->fsa_ax25.sax25_call, addr, sizeof(ax25_address));
+       sax->fsa_ax25.sax25_call   = *addr;
        sax->fsa_ax25.sax25_ndigis = 0;
        *uaddr_len = sizeof(struct sockaddr_ax25);
 
@@ -1423,9 +1419,9 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
        if (sk->ax25->digipeat != NULL) {
                ndigi = sk->ax25->digipeat->ndigi;
                sax->fsa_ax25.sax25_ndigis = ndigi;
-               *uaddr_len += sizeof(ax25_address) * ndigi;
+               *uaddr_len += AX25_ADDR_LEN * ndigi;
                for (i = 0; i < ndigi; i++)
-                       memcpy(&sax->fsa_digipeater[i], &sk->ax25->digipeat->calls[i], sizeof(ax25_address));
+                       sax->fsa_digipeater[i] = sk->ax25->digipeat->calls[i];
        }
 
        return 0;
@@ -1450,9 +1446,7 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
        skb->h.raw = skb->data;
        
 #ifdef CONFIG_FIREWALL
-       
-       if(call_in_firewall(PF_AX25, skb, skb->h.raw)!=FW_ACCEPT)
-       {
+       if (call_in_firewall(PF_AX25, skb, skb->h.raw) != FW_ACCEPT) {
                kfree_skb(skb, FREE_READ);
                return 0;
        }
@@ -1476,8 +1470,7 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
         *      Ours perhaps ?
         */
        if (dp.lastrepeat + 1 < dp.ndigi) {             /* Not yet digipeated completely */
-               if (ax25cmp(&dp.calls[dp.lastrepeat + 1], dev_addr) == 0) 
-               {
+               if (ax25cmp(&dp.calls[dp.lastrepeat + 1], dev_addr) == 0) {
                        struct device *dev_out = dev;
 
                        /* We are the digipeater. Mark ourselves as repeated
@@ -1485,10 +1478,8 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
                        dp.lastrepeat++;
                        dp.repeated[(int)dp.lastrepeat] = 1;
 
-                       if (ax25_dev_get_value(dev, AX25_VALUES_DIGI) & AX25_DIGI_XBAND) 
-                       {
-                               while (dp.lastrepeat + 1 < dp.ndigi) 
-                               {
+                       if (ax25_dev_get_value(dev, AX25_VALUES_DIGI) & AX25_DIGI_XBAND) {
+                               while (dp.lastrepeat + 1 < dp.ndigi) {
                                        struct device *dev_scan;
                                        if ((dev_scan = ax25rtr_get_dev(&dp.calls[dp.lastrepeat + 1])) == NULL)
                                                break;
@@ -1496,23 +1487,20 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
                                        dp.repeated[(int)dp.lastrepeat] = 1;
                                        dev_out = dev_scan;
                                }
-                               if (dev != dev_out && (ax25_dev_get_value(dev_out, AX25_VALUES_DIGI) & AX25_DIGI_XBAND) == 0)
-                               {
+                               if (dev != dev_out && (ax25_dev_get_value(dev_out, AX25_VALUES_DIGI) & AX25_DIGI_XBAND) == 0) {
                                        kfree_skb(skb, FREE_READ);
                                        return 0;
                                }
                        }
 
-                       if (dev == dev_out && (ax25_dev_get_value(dev, AX25_VALUES_DIGI) & AX25_DIGI_INBAND) == 0)
-                       {
+                       if (dev == dev_out && (ax25_dev_get_value(dev, AX25_VALUES_DIGI) & AX25_DIGI_INBAND) == 0) {
                                kfree_skb(skb, FREE_READ);
                                return 0;       /* Hey, Alan: look what you're doing below! You forgot this return! */
                        }
 
                        build_ax25_addr(skb->data, &src, &dest, &dp, type, MODULUS);
 #ifdef CONFIG_FIREWALL
-                       if(call_fw_firewall(PF_AX25, skb,skb->data)!=FW_ACCEPT)
-                       {
+                       if (call_fw_firewall(PF_AX25, skb, skb->data) != FW_ACCEPT) {
                                kfree_skb(skb, FREE_READ);
                                return 0;
                        }
@@ -1680,8 +1668,8 @@ static int ax25_rcv(struct sk_buff *skb, struct device *dev, ax25_address *dev_a
 #endif
        }
 
-       memcpy(&ax25->source_addr, &dest, sizeof(ax25_address));
-       memcpy(&ax25->dest_addr,   &src,  sizeof(ax25_address));
+       ax25->source_addr = dest;
+       ax25->dest_addr   = src;
 
        /*
         *      Sort out any digipeated paths.
@@ -1820,27 +1808,25 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, int len, int no
 
                        while (ct < usax->sax25_ndigis) {
                                dtmp.repeated[ct] = 0;
-                               memcpy(&dtmp.calls[ct], &fsa->fsa_digipeater[ct], sizeof(ax25_address));
+                               dtmp.calls[ct]    = fsa->fsa_digipeater[ct];
                                ct++;
                        }
 
                        dtmp.lastrepeat = 0;
                }
 
-               memcpy(&sax, usax, sizeof(sax));
-               if (sk->type == SOCK_SEQPACKET && memcmp(&sk->ax25->dest_addr, &sax.sax25_call, sizeof(ax25_address)) != 0)
+               sax = *usax;
+               if (sk->type == SOCK_SEQPACKET && ax25cmp(&sk->ax25->dest_addr, &sax.sax25_call) != 0)
                        return -EISCONN;
                if (usax->sax25_ndigis == 0)
-               {
                        dp = NULL;
-               }
                else
                        dp = &dtmp;
        } else {
                if (sk->state != TCP_ESTABLISHED)
                        return -ENOTCONN;
                sax.sax25_family = AF_AX25;
-               memcpy(&sax.sax25_call, &sk->ax25->dest_addr, sizeof(ax25_address));
+               sax.sax25_call   = sk->ax25->dest_addr;
                dp = sk->ax25->digipeat;
        }
        
@@ -1971,7 +1957,7 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int n
                   application know the digi calls further down (because it
                   did NOT ask to know them).  This could get political... **/
                sax->sax25_ndigis = digi.ndigi;
-               memcpy(&sax->sax25_call, &dest, sizeof(ax25_address));
+               sax->sax25_call   = dest;
 
                *addr_len = sizeof(struct sockaddr_ax25);
 
@@ -1980,7 +1966,7 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int n
                        struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)sax;
 
                        while (ct < digi.ndigi) {
-                               memcpy(&fsa->fsa_digipeater[ct], &digi.calls[ct], sizeof(ax25_address));
+                               fsa->fsa_digipeater[ct] = digi.calls[ct];
                                ct++;
                        }
 
@@ -2274,8 +2260,7 @@ void ax25_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
        int was_locked;
        
 #ifdef CONFIG_FIREWALL
-       if(call_out_firewall(PF_AX25, skb, skb->data)!=FW_ACCEPT)
-       {
+       if (call_out_firewall(PF_AX25, skb, skb->data) != FW_ACCEPT) {
                kfree_skb(skb, FREE_WRITE);
                return;
        }
@@ -2284,12 +2269,11 @@ void ax25_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
        skb->protocol = htons (ETH_P_AX25);
 
 #ifdef CONFIG_BPQETHER
-       if(dev->type == ARPHRD_ETHER)
-       {
+       if(dev->type == ARPHRD_ETHER) {
                static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
                int size;
-               if(skb_headroom(skb) < AX25_BPQ_HEADER_LEN)
-               {
+
+               if(skb_headroom(skb) < AX25_BPQ_HEADER_LEN) {
                        printk("ax25_queue_xmit: not enough space to add BPQ Ether header\n");
                        skb->free = 1;
                        kfree_skb(skb, FREE_WRITE);
@@ -2398,11 +2382,9 @@ int ax25_rebuild_header(unsigned char *bp, struct device *dev, unsigned long des
        if (arp_find(bp + 1, dest, dev, dev->pa_addr, skb))
                return 1;
 
-       if (bp[16] == AX25_P_IP) 
-       {
+       if (bp[16] == AX25_P_IP) {
                mode = ax25_ip_mode_get((ax25_address *)(bp + 1), dev);
-               if (mode == 'V' || mode == 'v' || (mode == ' ' && ax25_dev_get_value(dev, AX25_VALUES_IPDEFMODE) == 'V')) 
-               {
+               if (mode == 'V' || mode == 'v' || (mode == ' ' && ax25_dev_get_value(dev, AX25_VALUES_IPDEFMODE) == 'V')) {
 /*                     skb_device_unlock(skb); *//* Don't unlock - it might vanish.. TCP will respond correctly to this lock holding */
                        skb_pull(skb, AX25_HEADER_LEN - 1);     /* Keep PID */
 #ifdef HUNTING_FOR_ENCAP_BUG
@@ -2410,14 +2392,14 @@ int ax25_rebuild_header(unsigned char *bp, struct device *dev, unsigned long des
                /*                twice... We'll try a work-around here and hope for   */
                /*                the best.                                            */
 
-                       if ( !(ax25cmp((ax25_address *) (bp + 8), (ax25_address *) (skb->data + 8)) ||
-                              ax25cmp((ax25_address *) (bp + 1), (ax25_address *) (skb->data + 1)) ) )
-                       {
+                       if (!(ax25cmp((ax25_address *)(bp + 8), (ax25_address *)(skb->data + 8)) ||
+                             ax25cmp((ax25_address *)(bp + 1), (ax25_address *)(skb->data + 1)))) {
                                printk("ax25_rebuild_header(): encap bug...\n");
                                skb_pull(skb, AX25_HEADER_LEN);
-                       } else
+                       } else {
                                if (!*skb->data)
                                        printk("ax25_rebuild_header(): probably encap bug...\n");
+                       }
 #endif
                        ax25_send_frame(skb, (ax25_address *)(bp + 8), (ax25_address *)(bp + 1), NULL, dev);
                        return 1;
@@ -2432,6 +2414,8 @@ int ax25_rebuild_header(unsigned char *bp, struct device *dev, unsigned long des
        bp[14] |= LAPB_E;
        bp[14] |= SSSID_SPARE;
 
+       ax25_dg_build_path(skb, (ax25_address *)(bp + 1), dev);
+
        return 0;
 }      
 
index 8bd2e9f784a390b5db01a0ab7fd8dc5f72055c4f..1dba93bafd560da7e7d299413fa23745e3ee9064 100644 (file)
@@ -27,7 +27,7 @@
  *     AX.25 030       Jonathan(G4KLX) Added AX.25 fragment reception.
  *                                     Upgraded state machine for SABME.
  *                                     Added arbitrary protocol id support.
- *                     Joerg(DL1BKE)   Added DAMA support
+ *     AX.25 031       Joerg(DL1BKE)   Added DAMA support
  */
 
 #include <linux/config.h>
@@ -268,14 +268,12 @@ static int ax25_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
 
                case DISC:
                        ax25_send_control(ax25, UA, pf, C_RESPONSE);
-                       if (ax25->dama_slave)
-                       {
+                       if (ax25->dama_slave) {
                                ax25->state = AX25_STATE_0;
                                ax25->dama_slave = 0;
                                ax25_dama_off(ax25);
 
-                               if (ax25->sk != NULL) 
-                               {
+                               if (ax25->sk != NULL) {
                                        ax25->sk->state = TCP_CLOSE;
                                        ax25->sk->err   = 0;
                                        if (!ax25->sk->dead)
@@ -321,12 +319,11 @@ static int ax25_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                case REJ:
                case RNR:
                case RR:
-                       if (pf)
-                       {
+                       if (pf) {
                                if (ax25->dama_slave)
                                        ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
                                else
-                               ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
+                                       ax25_send_control(ax25, DM, POLLON, C_RESPONSE);
                        }
                        break;
                                
@@ -465,8 +462,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                                ax25_check_iframes_acked(ax25, nr);
                        }
                        if (ax25->condition & OWN_RX_BUSY_CONDITION) {
-                               if (pf)
-                               {
+                               if (pf) {
                                        if (ax25->dama_slave)   /* dl1bke 960114 */
                                                dama_enquiry_response(ax25);
                                        else
@@ -477,8 +473,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        if (ns == ax25->vr) {
                                queued = ax25_rx_iframe(ax25, skb);
                                if (ax25->condition & OWN_RX_BUSY_CONDITION) {
-                                       if (pf)
-                                       {
+                                       if (pf) {
                                                if (ax25->dama_slave)   /* dl1bke 960114 */
                                                        dama_enquiry_response(ax25);
                                                else
@@ -492,7 +487,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                                        if (ax25->dama_slave)   /* dl1bke 960114 */
                                                dama_enquiry_response(ax25);
                                        else
-                                       ax25_enquiry_response(ax25);
+                                               ax25_enquiry_response(ax25);
                                } else {
                                        if (!(ax25->condition & ACK_PENDING_CONDITION)) {
                                                ax25->t2timer = ax25->t2;
@@ -501,8 +496,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                                }
                        } else {
                                if (ax25->condition & REJECT_CONDITION) {
-                                       if (pf) 
-                                       {
+                                       if (pf) {
                                                if (ax25->dama_slave)   /* dl1bke 960114 */
                                                        dama_enquiry_response(ax25);
                                                else
@@ -513,7 +507,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                                        if (ax25->dama_slave)           /* dl1bke 960114 */
                                                dama_enquiry_response(ax25);
                                        else
-                                       ax25_send_control(ax25, REJ, pf, C_RESPONSE);
+                                               ax25_send_control(ax25, REJ, pf, C_RESPONSE);
                                        ax25->condition &= ~ACK_PENDING_CONDITION;
                                }
                        }
@@ -716,8 +710,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        }
                        ax25_frames_acked(ax25, nr);
                        if (ax25->condition & OWN_RX_BUSY_CONDITION) {
-                               if (pf)
-                               {       /* dl1bke 960114 */
+                               if (pf) {       /* dl1bke 960114 */
                                        if (ax25->dama_slave)
                                                ax25_enquiry_response(ax25);
                                        else
@@ -728,8 +721,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        if (ns == ax25->vr) {
                                queued = ax25_rx_iframe(ax25, skb);
                                if (ax25->condition & OWN_RX_BUSY_CONDITION) {
-                                       if (pf) 
-                                       {       /* dl1bke 960114 */
+                                       if (pf) {       /* dl1bke 960114 */
                                                if (ax25->dama_slave)
                                                        dama_enquiry_response(ax25);
                                                else
@@ -743,7 +735,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                                        if (ax25->dama_slave)   /* dl1bke 960114 */
                                                dama_enquiry_response(ax25);
                                        else
-                                       ax25_enquiry_response(ax25);
+                                               ax25_enquiry_response(ax25);
                                } else {
                                        if (!(ax25->condition & ACK_PENDING_CONDITION)) {
                                                ax25->t2timer = ax25->t2;
@@ -752,8 +744,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                                }
                        } else {
                                if (ax25->condition & REJECT_CONDITION) {
-                                       if (pf) 
-                                       {       /* dl1bke 960114 */
+                                       if (pf) {       /* dl1bke 960114 */
                                                if (ax25->dama_slave)
                                                        dama_enquiry_response(ax25);
                                                else
@@ -764,7 +755,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                                        if (ax25->dama_slave)           /* dl1bke 960114 */
                                                dama_enquiry_response(ax25);
                                        else
-                                       ax25_send_control(ax25, REJ, pf, C_RESPONSE);
+                                               ax25_send_control(ax25, REJ, pf, C_RESPONSE);
                                        ax25->condition &= ~ACK_PENDING_CONDITION;
                                }
                        }
index 7f2a80673c08b513cae4feef117ca0164a6e2c13..301a417fca9b1fc74a6e2b1ad596dad78ed44604 100644 (file)
@@ -24,7 +24,7 @@
  *                     Jonathan(G4KLX) Only poll when window is full.
  *     AX.25 030       Jonathan(G4KLX) Added fragmentation to ax25_output.
  *                                     Added support for extended AX.25.
- *                     Joerg(DL1BKE)   Added DAMA support
+ *     AX.25 031       Joerg(DL1BKE)   Added DAMA support
  */
 
 #include <linux/config.h>
@@ -109,8 +109,7 @@ void ax25_output(ax25_cb *ax25, struct sk_buff *skb)
                skb_queue_tail(&ax25->write_queue, skb);          /* Throw it on the queue */
        }
 
-       if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4)
-       {
+       if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
                if (!ax25->dama_slave)          /* bke 960114: we aren't allowed to transmit */
                        ax25_kick(ax25);        /* in DAMA mode unless we received a Poll */
        }
@@ -318,34 +317,34 @@ void ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr)
        }
 }
 
-/* dl1bke 960114: shouldn't ax25/dama_check_need_response reside as  */
-/*                static inline void ...() in ax25.h, should it? ;-) */
-
+/*
+ *     dl1bke 960114: shouldn't ax25/dama_check_need_response reside as
+ *                static inline void ...() in ax25.h, should it? ;-)
+ */
 void ax25_check_need_response(ax25_cb *ax25, int type, int pf)
 {
        if (!ax25->dama_slave && type == C_COMMAND && pf)
                ax25_enquiry_response(ax25);
 }
 
-/* dl1bke 960114: transmit I frames on DAMA poll */
-
-void dama_enquiry_response(ax25_cb * ax25)
+/*
+ *     dl1bke 960114: transmit I frames on DAMA poll
+ */
+void dama_enquiry_response(ax25_cb *ax25)
 {
-       ax25_cb * ax25o = NULL;
+       ax25_cb *ax25o;
        
-       if (!(ax25->condition & PEER_RX_BUSY_CONDITION) )
-       {
+       if (!(ax25->condition & PEER_RX_BUSY_CONDITION)) {
                ax25_requeue_frames(ax25);
                ax25_kick(ax25);
        }
-       if (ax25->state == AX25_STATE_1 ||
-           ax25->state == AX25_STATE_2 ||
-           skb_peek(&ax25->ack_queue) != NULL) 
-       {
-               ax25_t1_timeout(ax25);
 
-       } else
+       if (ax25->state == AX25_STATE_1 || ax25->state == AX25_STATE_2 ||
+           skb_peek(&ax25->ack_queue) != NULL) {
+               ax25_t1_timeout(ax25);
+       } else {
                ax25->n2count = 0;
+       }
        
        ax25->t3timer = ax25->t3;
        
@@ -367,31 +366,29 @@ void dama_enquiry_response(ax25_cb * ax25)
        /* transmissions of the other channels as well... This version    */    
        /* gives better performance on FLEXNET nodes. (Why, Gunter?)      */
 
-       for (ax25o=ax25_list; ax25o; ax25o=ax25o->next)
-       {
+       for (ax25o = ax25_list; ax25o != NULL; ax25o = ax25o->next) {
                if (ax25o->device != ax25->device)
                        continue;
-                       
-               if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2)
-               {
+
+               if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2) {
                        ax25_t1_timeout(ax25o);
                        continue;
                }
-                       
-               if ( !ax25o->dama_slave)
+
+               if (!ax25o->dama_slave)
                        continue;
                        
                if ( !(ax25o->condition & PEER_RX_BUSY_CONDITION) && 
                     (ax25o->state == AX25_STATE_3 || 
-                    (ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0)) )
-               {
+                    (ax25o->state == AX25_STATE_4 && ax25o->t1timer == 0))) {
                        ax25_requeue_frames(ax25o);
                        ax25_kick(ax25o);
                }
                
-               if (ax25o->state == AX25_STATE_1 ||
-                   ax25o->state == AX25_STATE_2 ||
-                   skb_peek(&ax25o->ack_queue) != NULL) ax25_t1_timeout(ax25o);
+               if (ax25o->state == AX25_STATE_1 || ax25o->state == AX25_STATE_2 ||
+                   skb_peek(&ax25o->ack_queue) != NULL) {
+                       ax25_t1_timeout(ax25o);
+               }
 
                ax25o->t3timer = ax25o->t3;
        }
index a65098a544600751cb9a0d73683f83998d8bf63a..172315124a0fc5a9e52ce4e8e83b8d5e3e085876 100644 (file)
@@ -30,7 +30,7 @@
  *     AX.25 031       Jonathan(G4KLX) Added concept of default route.
  *                     Joerg(DL1BKE)   ax25_rt_build_path() find digipeater list and device by 
  *                                     destination call. Needed for IP routing via digipeater
- *
+ *                     Jonathan(G4KLX) Added routing for IP datagram packets.
  */
  
 #include <linux/config.h>
@@ -101,21 +101,14 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev, ax25_digi *digi)
        }
 
        if (count > AX25_ROUTE_MAX) {
-               oldest->callsign = *src;
-               oldest->dev      = dev;
-               if (oldest->digipeat != NULL) {
+               if (oldest->digipeat != NULL)
                        kfree_s(oldest->digipeat, sizeof(ax25_digi));
-                       oldest->digipeat = NULL;
-               }
-               oldest->stamp    = xtime;
-               oldest->n        = 1;
-               oldest->ip_mode  = ' ';
-               return;
+               ax25_rt = oldest;
+       } else {
+               if ((ax25_rt = (struct ax25_route *)kmalloc(sizeof(struct ax25_route), GFP_ATOMIC)) == NULL)
+                       return;         /* No space */
        }
 
-       if ((ax25_rt = (struct ax25_route *)kmalloc(sizeof(struct ax25_route), GFP_ATOMIC)) == NULL)
-               return;         /* No space */
-
        ax25_rt->callsign = *src;
        ax25_rt->dev      = dev;
        ax25_rt->digipeat = NULL;
@@ -128,16 +121,18 @@ void ax25_rt_rx_frame(ax25_address *src, struct device *dev, ax25_digi *digi)
                        kfree_s(ax25_rt, sizeof(struct ax25_route));
                        return;
                }
-               memcpy(ax25_rt->digipeat, digi, sizeof(ax25_digi));
+               *ax25_rt->digipeat = *digi;
        }
 
-       save_flags(flags);
-       cli();
+       if (ax25_rt != oldest) {
+               save_flags(flags);
+               cli();
 
-       ax25_rt->next = ax25_route;
-       ax25_route    = ax25_rt;
+               ax25_rt->next = ax25_route;
+               ax25_route    = ax25_rt;
 
-       restore_flags(flags);
+               restore_flags(flags);
+       }
 }
 
 void ax25_rt_device_down(struct device *dev)
@@ -402,12 +397,12 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
                call = (ax25_address *)ax25->device->dev_addr;
        }
 
-       memcpy(&ax25->source_addr, call, sizeof(ax25_address));
+       ax25->source_addr = *call;
 
        if (ax25_rt->digipeat != NULL) {
                if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL)
                        return -ENOMEM;
-               memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
+               *ax25->digipeat = *ax25_rt->digipeat;
        }
 
        if (ax25->sk != NULL)
@@ -424,8 +419,7 @@ void ax25_rt_build_path(ax25_cb *ax25, ax25_address *addr)
        struct ax25_route *ax25_rt;
 
        for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
-               if ( ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->digipeat != NULL ) {
-               
+               if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->digipeat != NULL) {
                        if (ax25_rt->dev == NULL)
                                continue;
                        
@@ -433,12 +427,48 @@ void ax25_rt_build_path(ax25_cb *ax25, ax25_address *addr)
                                return;
 
                        ax25->device = ax25_rt->dev;
-                       memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
+                       *ax25->digipeat = *ax25_rt->digipeat;
+
                        return;
                }
        }
+
        ax25->digipeat = NULL;
 }
+
+void ax25_dg_build_path(struct sk_buff *skb, ax25_address *addr, struct device *dev)
+{
+       struct ax25_route *ax25_rt;
+       ax25_address src, dest;
+       unsigned char *bp;
+       int len;
+
+       for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
+               if (ax25cmp(&ax25_rt->callsign, addr) == 0 && ax25_rt->dev == dev) {
+                       if (ax25_rt->digipeat == NULL)
+                               return;
+
+                       len = ax25_rt->digipeat->ndigi * AX25_ADDR_LEN;
+                       
+                       if (skb_headroom(skb) < len) {
+                               printk("ax25_dg_build_path: not enough headroom for in skb\n");
+                               return;
+                       }
+
+                       memcpy(&dest, skb->data + 1, AX25_ADDR_LEN);
+                       memcpy(&src,  skb->data + 8, AX25_ADDR_LEN);
+
+                       bp = skb_push(skb, len);
+
+                       *bp++ = 0x00;           /* KISS Data */
+
+                       build_ax25_addr(bp, &src, &dest, ax25_rt->digipeat, C_COMMAND, MODULUS);
+
+                       return;
+               }
+       }
+}
+
 /*
  *     Register the mode of an incoming IP frame. It is assumed that an entry
  *     already exists in the routing table.
@@ -563,7 +593,6 @@ int ax25_dev_ioctl(unsigned int cmd, void *arg)
        struct device *dev;
        struct ax25_dev *ax25_dev;
        int err;
-       int count;
 
        switch (cmd) {
                case SIOCAX25SETPARMS:
index 242d4334626beb3bccff726ece61c0cca2b11f84..d3615016f0976783b71cbc83984de267bb28f983 100644 (file)
@@ -25,7 +25,7 @@
  *                                     Added fragmentation support.
  *                     Darryl(G7LED)   Added function ax25_requeue_frames() to split
  *                                     it up from ax25_frames_acked().
- *                     Joerg(DL1BKE)   DAMA needs KISS Fullduplex ON/OFF.
+ *     AX.25 031       Joerg(DL1BKE)   DAMA needs KISS Fullduplex ON/OFF.
  *                                     Thus we have ax25_kiss_cmd() now... ;-)
  *                     Dave Brown(N2RJT)
  *                                     Killed a silly bug in the DAMA code.
@@ -360,8 +360,7 @@ unsigned char *ax25_parse_addr(unsigned char *buf, int len, ax25_address *src, a
        digi->lastrepeat = -1;
        digi->ndigi      = 0;
        
-       while (!(buf[-1] & LAPB_E))
-       {
+       while (!(buf[-1] & LAPB_E)) {
                if (d >= AX25_MAX_DIGIS)  return NULL;  /* Max of 6 digis */
                if (len < 7) return NULL;       /* Short packet */
 
@@ -473,7 +472,16 @@ void ax25_digi_invert(ax25_digi *in, ax25_digi *out)
        out->lastrepeat = 0;
 }
 
-void ax25_kiss_cmd(ax25_cb * ax25, unsigned char cmd, unsigned char param)
+/*
+ *     :::FIXME:::
+ *     This is ****NOT**** the right approach. Not all drivers do kiss. We
+ *     need a driver level request to switch duplex mode, that does either
+ *     SCC changing, PI config or KISS as required.
+ *
+ *     Not to mention this request isnt currently reliable.
+ */
+void ax25_kiss_cmd(ax25_cb *ax25, unsigned char cmd, unsigned char param)
 {
        struct sk_buff *skb;
        unsigned char *p;
@@ -487,8 +495,7 @@ void ax25_kiss_cmd(ax25_cb * ax25, unsigned char cmd, unsigned char param)
        skb->free = 1;
        skb->arp = 1;
        
-       if (ax25->sk != NULL)
-       {
+       if (ax25->sk != NULL) {
                skb->sk = ax25->sk;
                ax25->sk->wmem_alloc += skb->truesize;
        }
@@ -507,10 +514,9 @@ void ax25_dama_on(ax25_cb *ax25)
 {
        int count = ax25_dev_is_dama_slave(ax25->device);
 
-       if (count == 0)
-       {
-               if (ax25->sk && ax25->sk->debug)
-                       printk("DAMA on\n");
+       if (count == 0) {
+               if (ax25->sk != NULL && ax25->sk->debug)
+                       printk("ax25_dama_on: DAMA on\n");
                ax25_kiss_cmd(ax25, 5, 1);
        }
 }
@@ -519,11 +525,9 @@ void ax25_dama_off(ax25_cb *ax25)
 {
        int count = ax25_dev_is_dama_slave(ax25->device);
        
-       
-       if (count == 0)
-       {
-               if (ax25->sk && ax25->sk->debug)
-                       printk("DAMA off\n");
+       if (count == 0) {
+               if (ax25->sk != NULL && ax25->sk->debug)
+                       printk("ax25_dama_off: DAMA off\n");
                ax25_kiss_cmd(ax25, 5, 0);
        }
 }
index 28c50381dfb7495f610cdbb9bdab6c783b85df58..368c7e13209d52f009e18473a1b7d79e90fcbf08 100644 (file)
@@ -17,6 +17,7 @@
  *     AX.25 028b      Jonathan(G4KLX) Extracted AX25 control block from the
  *                                     sock structure.
  *     AX.25 029       Alan(GW4PTS)    Switched to KA9Q constant names.
+ *     AX.25 031       Joerg(DL1BKE)   Added DAMA support
  */
 
 #include <linux/config.h>
@@ -112,7 +113,7 @@ static void ax25_timer(unsigned long param)
                                if (ax25->sk->rmem_alloc < (ax25->sk->rcvbuf / 2) && (ax25->condition & OWN_RX_BUSY_CONDITION)) {
                                        ax25->condition &= ~OWN_RX_BUSY_CONDITION;
                                        if (!ax25->dama_slave) /* dl1bke */
-                                       ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
+                                               ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
                                        ax25->condition &= ~ACK_PENDING_CONDITION;
                                        break;
                                }
@@ -133,19 +134,15 @@ static void ax25_timer(unsigned long param)
                        if (ax25->condition & ACK_PENDING_CONDITION) {
                                ax25->condition &= ~ACK_PENDING_CONDITION;
                                if (!ax25->dama_slave)                  /* dl1bke 960114 */
-                               ax25_timeout_response(ax25);
+                                       ax25_timeout_response(ax25);
                        }
                }
        }
 
-       if (ax25->t3timer > 0 && --ax25->t3timer == 0) 
-       {
-       
+       if (ax25->t3timer > 0 && --ax25->t3timer == 0) {
                /* dl1bke 960114: T3 expires and we are in DAMA mode:  */
                /*                send a DISC and abort the connection */
-                
-               if (ax25->dama_slave)
-               {
+               if (ax25->dama_slave) {
 #ifdef CONFIG_NETROM
                        nr_link_failed(&ax25->dest_addr, ax25->device);
 #endif
@@ -153,8 +150,7 @@ static void ax25_timer(unsigned long param)
                        ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
                                
                        ax25->state = AX25_STATE_0;
-                       if (ax25->sk != NULL)
-                       {
+                       if (ax25->sk != NULL) {
                                if (ax25->sk->debug)
                                        printk("T3 Timeout\n");
                                ax25->sk->state = TCP_CLOSE;
@@ -179,14 +175,13 @@ static void ax25_timer(unsigned long param)
        /*                nevertheless we have to re-enqueue the timer struct...   */
        
        if (ax25->t1timer == 0 || --ax25->t1timer > 0) {
-       
                ax25_reset_timer(ax25);
                return;
        }
 
-       if (!ax25_dev_is_dama_slave(ax25->device))
-       {
-               if (ax25->dama_slave) ax25->dama_slave = 0;
+       if (!ax25_dev_is_dama_slave(ax25->device)) {
+               if (ax25->dama_slave)
+                       ax25->dama_slave = 0;
                ax25_t1_timeout(ax25);
        }
 }
@@ -200,8 +195,6 @@ static void ax25_timer(unsigned long param)
  *                Thus we'll have to do parts of our T1 handling in
  *                ax25_enquiry_response().
  */
-
-
 void ax25_t1_timeout(ax25_cb * ax25)
 {      
        switch (ax25->state) {
@@ -255,14 +248,14 @@ void ax25_t1_timeout(ax25_cb * ax25)
                        } else {
                                ax25->n2count++;
                                if (!ax25_dev_is_dama_slave(ax25->device))      /* dl1bke */
-                               ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
+                                       ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
                        }
                        break;
 
                case AX25_STATE_3: 
                        ax25->n2count = 1;
                        if (!ax25->dama_slave)                  /* dl1bke 960114 */
-                       ax25_transmit_enquiry(ax25);
+                               ax25_transmit_enquiry(ax25);
                        ax25->state   = AX25_STATE_4;
                        break;
 
@@ -286,7 +279,7 @@ void ax25_t1_timeout(ax25_cb * ax25)
                        } else {
                                ax25->n2count++;
                                if (!ax25->dama_slave)          /* dl1bke 960114 */
-                               ax25_transmit_enquiry(ax25);
+                                       ax25_transmit_enquiry(ax25);
                        }
                        break;
        }
index efe1acc98b797c84692a1f5679bfc954b12608a3..defc9b3774df9b77dd7993cc0d34fda5bb34685f 100644 (file)
@@ -43,6 +43,8 @@
  *                                     on a Sparc.
  *             Bjorn Ekwall    :       Added KERNELD hack.
  *             Alan Cox        :       Cleaned up the backlog initialise.
+ *             Craig Metz      :       SIOCGIFCONF fix if space for under
+ *                                     1 device.
  *
  */
 
@@ -214,8 +216,15 @@ struct device *dev_get(const char *name)
 
 extern __inline__ void dev_load(const char *name)
 {
-       if(!dev_get(name))
-               request_module(name);
+        char *sptr;
+        if(!dev_get(name)) {
+#ifdef CONFIG_NET_ALIAS
+                for (sptr=name ; *sptr ; sptr++) if(*sptr==':') break;
+                if (!(*sptr && *(sptr+1)))
+#endif
+                        request_module(name);
+        }
 }
 
 #endif
@@ -788,11 +797,6 @@ static int dev_ifconf(char *arg)
        {
                if(!(dev->flags & IFF_UP))      /* Downed devices don't count */
                        continue;
-               memset(&ifr, 0, sizeof(struct ifreq));
-               strcpy(ifr.ifr_name, dev->name);
-               (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
-               (*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
-
                /*
                 *      Have we run out of space here ?
                 */
@@ -800,6 +804,12 @@ static int dev_ifconf(char *arg)
                if (len < sizeof(struct ifreq)) 
                        break;
 
+               memset(&ifr, 0, sizeof(struct ifreq));
+               strcpy(ifr.ifr_name, dev->name);
+               (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
+               (*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
+
+
                /*
                 *      Write this block to the caller's space. 
                 */
index 057d337da57a2e90a2aa1fc366af09393d3ca544..1a2c45ef99967bcc7de246c5b792ffcf152ec6d8 100644 (file)
  *     -       net_alias_type objs registration/unreg., module-ables.
  *     -       /proc/net/aliases & /proc/net/alias_types entries
  * Fixes:
- *     JJC     :       several net_alias_type func. renamed.
- *     JJC     :       net_alias_type object methods now pass *this.
- *     JJC     :       xxx_rcv device selection based on <src,dst> addrs
+ *                     JJC     :       several net_alias_type func. renamed.
+ *                     JJC     :       net_alias_type object methods now pass 
+ *                                     *this.
+ *                     JJC     :       xxx_rcv device selection based on <src,dst> 
+ *                                     addrs
+ *             Andreas Schultz :       Kerneld support.
  *
  * FIXME:
  *     - User calls sleep/wake_up locking.
@@ -30,6 +33,7 @@
  *     
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 
 #include <linux/net_alias.h>
 
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
+
 /*
  * Only allow the following flags to pass from main device to aliases
  */
@@ -346,13 +354,23 @@ net_alias_dev_create(struct device *main_dev, int slot, int *err, struct sockadd
    */
   
   nat = nat_getbytype(family);
-  if (!nat)
-  {
-    printk("net_alias_dev_create(%s:%d): unregistered family==%d\n",
-          main_dev->name, slot, family);
-    /* *err = -EAFNOSUPPORT; */
-    *err = -EINVAL;
-    return NULL;
+  if (!nat) {
+#ifdef CONFIG_KERNELD
+    char modname[20];
+    sprintf (modname,"netalias-%d", family);
+    request_module(modname);
+
+    nat = nat_getbytype(family);
+    if (!nat) {
+#endif
+      printk("net_alias_dev_create(%s:%d): unregistered family==%d\n",
+             main_dev->name, slot, family);
+      /* *err = -EAFNOSUPPORT; */
+      *err = -EINVAL;
+      return NULL;
+#ifdef CONFIG_KERNELD
+    }
+#endif
   }
   
   /*
index 22db2f00f3cecb8d3314fa8f97dffe3a12d075a4..0cf40fea4e7550ac5e62e2a6f622a77c578a8e1b 100644 (file)
@@ -558,17 +558,15 @@ void __release_sock(struct sock *sk)
         */
 
        /* See if we have any packets built up. */
+       start_bh_atomic();
        while ((skb = __skb_dequeue(&sk->back_log)) != NULL) 
        {
-               barrier();
-               sk->users = 1;
                if (sk->prot->rcv) 
                        sk->prot->rcv(skb, skb->dev, (struct options*)skb->proto_priv,
                                 skb->saddr, skb->len, skb->daddr, 1,
                                /* Only used for/by raw sockets. */
                                (struct inet_protocol *)sk->pair); 
-               sk->users = 0;
-               barrier();
        }
+       end_bh_atomic();
 #endif  
 }
index af88f82711b269cdd452ccbfcdd477211728566a..6b3503ed3872f7cdf39a03a9d7d36defb4532e69 100644 (file)
@@ -322,36 +322,24 @@ void destroy_sock(struct sock *sk)
                kfree_skb(skb, FREE_WRITE);
        }
        
-       /* 
-        *      In case it's sleeping somewhere. 
-        */
-        
-       if (!sk->dead) 
-               sk->write_space(sk);
-
        /*
-        *      Don't discard received data until the user side kills its
-        *      half of the socket.
+        *      Clean up the read buffer.
         */
 
-       if (sk->dead
+       while((skb=skb_dequeue(&sk->receive_queue))!=NULL
        {
-               while((skb=skb_dequeue(&sk->receive_queue))!=NULL) 
-               {
                /*
                 * This will take care of closing sockets that were
                 * listening and didn't accept everything.
                 */
-                       if (skb->sk != NULL && skb->sk != sk) 
-                       {
-                               IS_SKB(skb);
-                               skb->sk->dead = 1;
-                               skb->sk->prot->close(skb->sk, 0);
-                       }
+               if (skb->sk != NULL && skb->sk != sk) 
+               {
                        IS_SKB(skb);
-                       kfree_skb(skb, FREE_READ);
+                       skb->sk->prot->close(skb->sk, 0);
                }
-       }       
+               IS_SKB(skb);
+               kfree_skb(skb, FREE_READ);
+       }
 
        /*
         *      Now we need to clean up the send head. 
@@ -396,7 +384,6 @@ void destroy_sock(struct sock *sk)
         
        if (sk->pair) 
        {
-               sk->pair->dead = 1;
                sk->pair->prot->close(sk->pair, 0);
                sk->pair = NULL;
        }
@@ -407,7 +394,7 @@ void destroy_sock(struct sock *sk)
         * everything is gone.
         */
 
-       if (sk->dead && sk->rmem_alloc == 0 && sk->wmem_alloc == 0) 
+       if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0) 
        {
                if(sk->opt)
                        kfree(sk->opt);
@@ -423,6 +410,7 @@ void destroy_sock(struct sock *sk)
        {
                /* this should never happen. */
                /* actually it can if an ack has just been sent. */
+               printk("Socket destroy delayed\n");
                sk->destroy = 1;
                sk->ack_backlog = 0;
                release_sock(sk);
@@ -1028,7 +1016,6 @@ static int inet_accept(struct socket *sock, struct socket *newsock, int flags)
        {
                struct sock *sk=(struct sock *)newsock->data;
                newsock->data=NULL;
-               sk->dead = 1;
                destroy_sock(sk);
        }
   
@@ -1078,7 +1065,6 @@ static int inet_accept(struct socket *sock, struct socket *newsock, int flags)
        if (sk2->state != TCP_ESTABLISHED && sk2->err > 0) 
        {
                err = sock_error(sk2);
-               sk2->dead=1;
                destroy_sock(sk2);
                newsock->data = NULL;
                return err;
index f2363c9e6fa68be9d4e193ab7c25b2107dc2de46..f8ec3371405c9c7545c3fe4db6125493c4392012 100644 (file)
@@ -53,6 +53,9 @@
  *                                     message (960131).
  *             Christian Daudt :       removed del_timer from 
  *                                     igmp_timer_expire function (960205).
+ *             Christian Daudt :       igmp_heard_report now only calls
+ *                                     igmp_timer_expire if tm->running is
+ *                                     true (960216).
  */
 
 
@@ -288,7 +291,7 @@ static void igmp_heard_report(struct device *dev, unsigned long address)
        if ((address & IGMP_LOCAL_GROUP_MASK) != IGMP_LOCAL_GROUP) {
          /* Timers are only set for non-local groups */
          for(im=dev->ip_mc_list;im!=NULL;im=im->next) {
-           if(im->multiaddr==address) {
+           if(im->multiaddr==address && im->tm_running) {
              igmp_stop_timer(im);
            }
          }
index d0c1470bbe8c7dd1b26395c16bc3a10b8c550343..77257ff7a2ac26e70f882933bfe146e9619b561c 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/in.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
+#include <linux/if_arp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/route.h>
@@ -557,9 +558,10 @@ static __inline__ void fib_add_1(short flags, __u32 dst, __u32 mask,
        {
                /*
                 *      Don't try to add a gateway we can't reach.. 
+                *      Tunnel devices are exempt from this rule.
                 */
                 
-               if (dev != get_gw_dev(gw))
+               if ((dev != get_gw_dev(gw)) && dev->type!=ARPHRD_TUNNEL)
                        return;
                        
                flags |= RTF_GATEWAY;
index 45ab5160728ceb45c4d81a63d4fc0f44c4ca7964..9c4a5a0f7d7fa8e3ff6ce0e4543ff80a0196490f 100644 (file)
@@ -480,7 +480,6 @@ static void tcp_close_pending (struct sock *sk)
 
        while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) 
        {
-               skb->sk->dead=1;
                tcp_close(skb->sk, 0);
                kfree_skb(skb, FREE_READ);
        }
@@ -1728,7 +1727,7 @@ static int tcp_close_state(struct sock *sk, int dead)
 
 /*
  *     Shutdown the sending side of a connection. Much like close except
- *     that we don't receive shut down or set sk->dead=1.
+ *     that we don't receive shut down or set sk->dead.
  */
 
 void tcp_shutdown(struct sock *sk, int how)
@@ -1817,6 +1816,7 @@ static void tcp_close(struct sock *sk, unsigned long timeout)
                tcp_set_state(sk, TCP_CLOSE);
                tcp_close_pending(sk);
                release_sock(sk);
+               sk->dead = 1;
                return;
        }
        
@@ -1873,9 +1873,9 @@ static void tcp_close(struct sock *sk, unsigned long timeout)
         * This will destroy it. The timers will take care of actually
         * free'ing up the memory.
         */
-       sk->dead = 1;
        tcp_cache_zap();        /* Kill the cache again. */
        release_sock(sk);
+       sk->dead = 1;
 }
 
 
index 1b08274f7f3b99c79a537b76e641d008f9a88136..6eb9257399ddc6d9e199ddab3565657123a83579 100644 (file)
@@ -670,9 +670,7 @@ void tcp_send_synack(struct sock * newsk, struct sock * sk, struct sk_buff * skb
        if (buff == NULL) 
        {
                sk->err = ENOMEM;
-               newsk->dead = 1;
-               newsk->state = TCP_CLOSE;
-               /* And this will destroy it */
+               destroy_sock(newsk);
                kfree_skb(skb, FREE_READ);
                tcp_statistics.TcpAttemptFails++;
                return;
@@ -697,8 +695,7 @@ void tcp_send_synack(struct sock * newsk, struct sock * sk, struct sk_buff * skb
                sk->err = tmp;
                buff->free = 1;
                kfree_skb(buff,FREE_WRITE);
-               newsk->dead = 1;
-               newsk->state = TCP_CLOSE;
+               destroy_sock(newsk);
                skb->sk = sk;
                kfree_skb(skb, FREE_READ);
                tcp_statistics.TcpAttemptFails++;
index c437d5f71478aed9cc6db8a927eeb0887d59cc1f..458a7c72b93af6704f434d4d8787e6d2b0fd5c7c 100644 (file)
@@ -94,7 +94,7 @@ void net_timer (unsigned long data)
 
        if (sk->users)
        {
-               sk->timer.expires = jiffies+10;
+               sk->timer.expires = jiffies+HZ;
                add_timer(&sk->timer);
                sti();
                return;
@@ -134,15 +134,7 @@ void net_timer (unsigned long data)
                 *      the socket to be freed.
                 */
 
-                       if(sk->wmem_alloc!=0 || sk->rmem_alloc!=0)
-                       {
-                               sk->wmem_alloc++;       /* So it DOESN'T go away */
-                               destroy_sock (sk);
-                               sk->wmem_alloc--;       /* Might now have hit 0 - fall through and do it again if so */
-                               sk->users = 0;  /* This will be ok, the destroy won't totally work */
-                       }
-                       if(sk->wmem_alloc==0 && sk->rmem_alloc==0)
-                               destroy_sock(sk);       /* Socket gone, DON'T update sk->users! */
+                       destroy_sock(sk);
                        break;
 
                case TIME_CLOSE:
@@ -152,7 +144,7 @@ void net_timer (unsigned long data)
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->shutdown = SHUTDOWN_MASK;
-                       reset_timer (sk, TIME_DESTROY, TCP_DONE_TIME);
+                       reset_timer (sk, TIME_DONE, TCP_DONE_TIME);
                        break;
 
                default:
index 8adabf2d99f57f7b8e21dbe7494676e74ba5d5bd..bbe3ba916b47e559cb1bc696c3adda51ef232337 100644 (file)
@@ -1614,6 +1614,7 @@ ipx_create(struct socket *sock, int protocol)
        sk->socket=sock;
        sk->type=sock->type;
        sk->ipx_type=0;         /* General user level IPX */
+       sk->ipx_ncp_server = NULL;
        sk->debug=0;
        sk->ipx_intrfc = NULL;
        memset(&sk->ipx_dest_addr,'\0',sizeof(sk->ipx_dest_addr));
index 7ac4bdf78defc52b7fbe9bf84c127f9e95200f43..fc0057a2aa97715ac2877c2fb8655a8b0677351b 100644 (file)
@@ -151,7 +151,7 @@ static void nr_insert_socket(struct sock *sk)
  *     Find a socket that wants to accept the Connect Request we just
  *     received.
  */
-static struct sock *nr_find_listener(ax25_address *addr, int type)
+static struct sock *nr_find_listener(ax25_address *addr)
 {
        unsigned long flags;
        struct sock *s;
@@ -160,7 +160,7 @@ static struct sock *nr_find_listener(ax25_address *addr, int type)
        cli();
 
        for (s = nr_list; s != NULL; s = s->next) {
-               if (ax25cmp(&s->nr->source_addr, addr) == 0 && s->type == type && s->state == TCP_LISTEN) {
+               if (ax25cmp(&s->nr->source_addr, addr) == 0 && s->state == TCP_LISTEN) {
                        restore_flags(flags);
                        return s;
                }
@@ -173,7 +173,7 @@ static struct sock *nr_find_listener(ax25_address *addr, int type)
 /*
  *     Find a connected NET/ROM socket given my circuit IDs.
  */
-static struct sock *nr_find_socket(unsigned char index, unsigned char id, int type)
+static struct sock *nr_find_socket(unsigned char index, unsigned char id)
 {
        struct sock *s;
        unsigned long flags;
@@ -182,7 +182,7 @@ static struct sock *nr_find_socket(unsigned char index, unsigned char id, int ty
        cli();
 
        for (s = nr_list; s != NULL; s = s->next) {
-               if (s->nr->my_index == index && s->nr->my_id == id && s->type == type) {
+               if (s->nr->my_index == index && s->nr->my_id == id) {
                        restore_flags(flags);
                        return s;
                }
@@ -196,7 +196,7 @@ static struct sock *nr_find_socket(unsigned char index, unsigned char id, int ty
 /*
  *     Find a connected NET/ROM socket given their circuit IDs.
  */
-static struct sock *nr_find_peer(unsigned char index, unsigned char id, int type)
+static struct sock *nr_find_peer(unsigned char index, unsigned char id)
 {
        struct sock *s;
        unsigned long flags;
@@ -205,7 +205,7 @@ static struct sock *nr_find_peer(unsigned char index, unsigned char id, int type
        cli();
 
        for (s = nr_list; s != NULL; s = s->next) {
-               if (s->nr->your_index == index && s->nr->your_id == id && s->type == type) {
+               if (s->nr->your_index == index && s->nr->your_id == id) {
                        restore_flags(flags);
                        return s;
                }
@@ -385,8 +385,8 @@ static int nr_listen(struct socket *sock, int backlog)
 {
        struct sock *sk = (struct sock *)sock->data;
 
-       if (sk->type == SOCK_SEQPACKET && sk->state != TCP_LISTEN) {
-               memset(&sk->nr->user_addr, '\0', sizeof(ax25_address));
+       if (sk->state != TCP_LISTEN) {
+               memset(&sk->nr->user_addr, '\0', AX25_ADDR_LEN);
                sk->max_ack_backlog = backlog;
                sk->state           = TCP_LISTEN;
                return 0;
@@ -498,9 +498,9 @@ static int nr_create(struct socket *sock, int protocol)
        nr->state      = NR_STATE_0;
        nr->device     = NULL;
 
-       memset(&nr->source_addr, '\0', sizeof(ax25_address));
-       memset(&nr->user_addr,   '\0', sizeof(ax25_address));
-       memset(&nr->dest_addr,   '\0', sizeof(ax25_address));
+       memset(&nr->source_addr, '\0', AX25_ADDR_LEN);
+       memset(&nr->user_addr,   '\0', AX25_ADDR_LEN);
+       memset(&nr->dest_addr,   '\0', AX25_ADDR_LEN);
 
        nr->sk = sk;
        sk->nr = nr;
@@ -604,54 +604,48 @@ static int nr_release(struct socket *sock, struct socket *peer)
 
        if (sk == NULL) return 0;
 
-       if (sk->type == SOCK_SEQPACKET) {
-               switch (sk->nr->state) {
-                       case NR_STATE_0:
-                               sk->state     = TCP_CLOSE;
-                               sk->state_change(sk);
-                               sk->dead      = 1;
-                               nr_destroy_socket(sk);
-                               break;
-
-                       case NR_STATE_1:
-                               sk->nr->state = NR_STATE_0;
-                               sk->state     = TCP_CLOSE;
-                               sk->state_change(sk);
-                               sk->dead      = 1;
-                               nr_destroy_socket(sk);
-                               break;
-
-                       case NR_STATE_2:
-                               nr_write_internal(sk, NR_DISCACK);
-                               sk->nr->state = NR_STATE_0;
-                               sk->state     = TCP_CLOSE;
-                               sk->state_change(sk);
-                               sk->dead      = 1;
-                               nr_destroy_socket(sk);
-                               break;                  
-
-                       case NR_STATE_3:
-                               nr_clear_queues(sk);
-                               sk->nr->n2count = 0;
-                               nr_write_internal(sk, NR_DISCREQ);
-                               sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
-                               sk->nr->t2timer = 0;
-                               sk->nr->t4timer = 0;
-                               sk->nr->state   = NR_STATE_2;
-                               sk->state       = TCP_CLOSE;
-                               sk->state_change(sk);
-                               sk->dead        = 1;
-                               sk->destroy     = 1;
-                               break;
-
-                       default:
-                               break;
-               }
-       } else {
-               sk->state = TCP_CLOSE;
-               sk->state_change(sk);
-               sk->dead = 1;
-               nr_destroy_socket(sk);
+       switch (sk->nr->state) {
+
+               case NR_STATE_0:
+                       sk->state     = TCP_CLOSE;
+                       sk->state_change(sk);
+                       sk->dead      = 1;
+                       nr_destroy_socket(sk);
+                       break;
+
+               case NR_STATE_1:
+                       sk->nr->state = NR_STATE_0;
+                       sk->state     = TCP_CLOSE;
+                       sk->state_change(sk);
+                       sk->dead      = 1;
+                       nr_destroy_socket(sk);
+                       break;
+
+               case NR_STATE_2:
+                       nr_write_internal(sk, NR_DISCACK);
+                       sk->nr->state = NR_STATE_0;
+                       sk->state     = TCP_CLOSE;
+                       sk->state_change(sk);
+                       sk->dead      = 1;
+                       nr_destroy_socket(sk);
+                       break;                  
+
+               case NR_STATE_3:
+                       nr_clear_queues(sk);
+                       sk->nr->n2count = 0;
+                       nr_write_internal(sk, NR_DISCREQ);
+                       sk->nr->t1timer = sk->nr->t1 = nr_calculate_t1(sk);
+                       sk->nr->t2timer = 0;
+                       sk->nr->t4timer = 0;
+                       sk->nr->state   = NR_STATE_2;
+                       sk->state       = TCP_CLOSE;
+                       sk->state_change(sk);
+                       sk->dead        = 1;
+                       sk->destroy     = 1;
+                       break;
+
+               default:
+                       break;
        }
 
        sock->data = NULL;      
@@ -687,8 +681,8 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (addr->fsa_ax25.sax25_ndigis == 1) {
                if (!suser())
                        return -EPERM;
-               memcpy(&sk->nr->user_addr,   &addr->fsa_digipeater[0],   sizeof(ax25_address));
-               memcpy(&sk->nr->source_addr, &addr->fsa_ax25.sax25_call, sizeof(ax25_address));
+               sk->nr->user_addr   = addr->fsa_digipeater[0];
+               sk->nr->source_addr = addr->fsa_ax25.sax25_call;
        } else {
                source = &addr->fsa_ax25.sax25_call;
 
@@ -698,8 +692,8 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                        user = source;
                }
 
-               memcpy(&sk->nr->user_addr,   user,   sizeof(ax25_address));
-               memcpy(&sk->nr->source_addr, source, sizeof(ax25_address));
+               sk->nr->user_addr   = *user;
+               sk->nr->source_addr = *source;
        }
 
        sk->nr->device = dev;
@@ -731,7 +725,7 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
                return -ECONNREFUSED;
        }
        
-       if (sk->state == TCP_ESTABLISHED && sk->type == SOCK_SEQPACKET)
+       if (sk->state == TCP_ESTABLISHED)
                return -EISCONN;        /* No reconnect on a seqpacket socket */
                
        sk->state   = TCP_CLOSE;        
@@ -754,17 +748,16 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
                        user = source;
                }
 
-               memcpy(&sk->nr->user_addr,   user,   sizeof(ax25_address));
-               memcpy(&sk->nr->source_addr, source, sizeof(ax25_address));
-
-               sk->nr->device = dev;
+               sk->nr->user_addr   = *user;
+               sk->nr->source_addr = *source;
+               sk->nr->device      = dev;
 
                nr_insert_socket(sk);           /* Finish the bind */
        }
 
-       memcpy(&sk->nr->dest_addr, &addr->sax25_call, sizeof(ax25_address));
+       sk->nr->dest_addr = addr->sax25_call;
 
-       while (nr_find_socket((unsigned char)circuit / 256, (unsigned char)circuit % 256, SOCK_SEQPACKET) != NULL)
+       while (nr_find_socket((unsigned char)circuit / 256, (unsigned char)circuit % 256) != NULL)
                circuit++;
 
        sk->nr->my_index = circuit / 256;
@@ -878,13 +871,13 @@ static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
                        return -ENOTCONN;
                sax->fsa_ax25.sax25_family = AF_NETROM;
                sax->fsa_ax25.sax25_ndigis = 1;
-               memcpy(&sax->fsa_ax25.sax25_call, &sk->nr->user_addr, sizeof(ax25_address));
-               memcpy(&sax->fsa_digipeater[0],   &sk->nr->dest_addr, sizeof(ax25_address));
-               *uaddr_len = sizeof(struct sockaddr_ax25) + sizeof(ax25_address);
+               sax->fsa_ax25.sax25_call = sk->nr->user_addr;
+               sax->fsa_digipeater[0]   = sk->nr->dest_addr;
+               *uaddr_len = sizeof(struct sockaddr_ax25) + AX25_ADDR_LEN;
        } else {
                sax->fsa_ax25.sax25_family = AF_NETROM;
                sax->fsa_ax25.sax25_ndigis = 0;
-               memcpy(&sax->fsa_ax25.sax25_call, &sk->nr->source_addr, sizeof(ax25_address));
+               sax->fsa_ax25.sax25_call   = sk->nr->source_addr;
                *uaddr_len = sizeof(struct sockaddr_ax25);
        }
 
@@ -929,8 +922,8 @@ int nr_rx_frame(struct sk_buff *skb, struct device *dev)
         * Find an existing socket connection, based on circuit ID, if its
         * a Connect Request base it on their circuit ID.
         */
-       if (((frametype & 0x0F) != NR_CONNREQ && (sk = nr_find_socket(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL) ||
-           ((frametype & 0x0F) == NR_CONNREQ && (sk = nr_find_peer(circuit_index, circuit_id, SOCK_SEQPACKET)) != NULL)) {
+       if (((frametype & 0x0F) != NR_CONNREQ && (sk = nr_find_socket(circuit_index, circuit_id)) != NULL) ||
+           ((frametype & 0x0F) == NR_CONNREQ && (sk = nr_find_peer(circuit_index, circuit_id)) != NULL)) {
                skb->h.raw = skb->data;
 
                if ((frametype & 0x0F) == NR_CONNACK && skb->len == 22)
@@ -944,9 +937,9 @@ int nr_rx_frame(struct sk_buff *skb, struct device *dev)
        if ((frametype & 0x0F) != NR_CONNREQ)
                return 0;
                
-       sk = nr_find_listener(dest, SOCK_SEQPACKET);
+       sk = nr_find_listener(dest);
 
-       user   = (ax25_address *)(skb->data + 21);
+       user = (ax25_address *)(skb->data + 21);
 
        if (sk == NULL || sk->ack_backlog == sk->max_ack_backlog || (make = nr_make_new(sk)) == NULL) {
                nr_transmit_dm(skb);
@@ -959,9 +952,9 @@ int nr_rx_frame(struct sk_buff *skb, struct device *dev)
        make->state         = TCP_ESTABLISHED;
 
        /* Fill in his circuit details */
-       memcpy(&make->nr->source_addr, dest, sizeof(ax25_address));
-       memcpy(&make->nr->dest_addr,   src,  sizeof(ax25_address));
-       memcpy(&make->nr->user_addr,   user, sizeof(ax25_address));
+       make->nr->source_addr = *dest;
+       make->nr->dest_addr   = *src;
+       make->nr->user_addr   = *user;
 
        make->nr->your_index = circuit_index;
        make->nr->your_id    = circuit_id;
@@ -1033,8 +1026,8 @@ static int nr_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nobl
        if (usax) {
                if (msg->msg_namelen < sizeof(sax))
                        return -EINVAL;
-               memcpy(&sax, usax, sizeof(sax));
-               if (sk->type == SOCK_SEQPACKET && memcmp(&sk->nr->dest_addr, &sax.sax25_call, sizeof(ax25_address)) != 0)
+               sax = *usax;
+               if (ax25cmp(&sk->nr->dest_addr, &sax.sax25_call) != 0)
                        return -EISCONN;
                if (sax.sax25_family != AF_NETROM)
                        return -EINVAL;
@@ -1042,7 +1035,7 @@ static int nr_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nobl
                if (sk->state != TCP_ESTABLISHED)
                        return -ENOTCONN;
                sax.sax25_family = AF_NETROM;
-               memcpy(&sax.sax25_call, &sk->nr->dest_addr, sizeof(ax25_address));
+               sax.sax25_call   = sk->nr->dest_addr;
        }
        
        if (sk->debug)
@@ -1130,7 +1123,7 @@ static int nr_recvmsg(struct socket *sock, struct msghdr *msg, int size, int nob
         * This works for seqpacket too. The receiver has ordered the queue for
         * us! We do one quick check first though
         */
-       if (sk->type == SOCK_SEQPACKET && sk->state != TCP_ESTABLISHED)
+       if (sk->state != TCP_ESTABLISHED)
                return -ENOTCONN;
 
        /* Now we can treat all alike */
@@ -1149,9 +1142,9 @@ static int nr_recvmsg(struct socket *sock, struct msghdr *msg, int size, int nob
                struct sockaddr_ax25 addr;
                
                addr.sax25_family = AF_NETROM;
-               memcpy(&addr.sax25_call, skb->data + 7, sizeof(ax25_address));
+               memcpy(&addr.sax25_call, skb->data + 7, AX25_ADDR_LEN);
 
-               memcpy(sax, &addr, sizeof(*sax));
+               *sax = addr;
 
                *addr_len = sizeof(*sax);
        }
@@ -1189,8 +1182,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        put_fs_long(amount, (unsigned long *)arg);
                        return 0;
 
-               case TIOCINQ:
-               {
+               case TIOCINQ: {
                        struct sk_buff *skb;
                        /* These two are safe on a single CPU system as only user tasks fiddle here */
                        if ((skb = skb_peek(&sk->receive_queue)) != NULL)
@@ -1231,8 +1223,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        if (!suser()) return -EPERM;
                        return nr_rt_ioctl(cmd, (void *)arg);
 
-               case SIOCNRGETPARMS:
-               {
+               case SIOCNRGETPARMS: {
                        struct nr_parms_struct nr_parms;
                        if ((err = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct nr_parms_struct))) != 0)
                                return err;
@@ -1242,8 +1233,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        return 0;
                }
 
-               case SIOCNRSETPARMS:
-               {
+               case SIOCNRSETPARMS: {
                        struct nr_parms_struct nr_parms;
                        if (!suser()) return -EPERM;
                        if ((err = verify_area(VERIFY_READ, (void *)arg, sizeof(struct nr_parms_struct))) != 0)
index 8c181291a817152897793fac76e12de28f53d154..d2ae23be3ae7e024d524ea9b3b2b84977b7b4add 100644 (file)
@@ -55,8 +55,7 @@ int nr_rx_ip(struct sk_buff *skb, struct device *dev)
 {
        struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
 
-       if (!dev->start) 
-       {
+       if (!dev->start) {
                stats->rx_errors++;
                return 0;
        }
index b475ea7c24c485f677c381fb9eaa2a0f3dfeb89d..091d63398dde5230f5612d7e3c5b90e280d6fb9c 100644 (file)
@@ -150,7 +150,7 @@ void nr_kick(struct sock *sk)
        end   = (sk->nr->va + sk->window) % NR_MODULUS;
 
        if (!(sk->nr->condition & PEER_RX_BUSY_CONDITION) &&
-           start != end                                   &&
+           start != end                                  &&
            skb_peek(&sk->write_queue) != NULL) {
 
                sk->nr->vs = start;
@@ -208,13 +208,13 @@ void nr_transmit_buffer(struct sock *sk, struct sk_buff *skb)
         */
        dptr = skb_push(skb, NR_NETWORK_LEN);
 
-       memcpy(dptr, &sk->nr->source_addr, sizeof(ax25_address));
+       memcpy(dptr, &sk->nr->source_addr, AX25_ADDR_LEN);
        dptr[6] &= ~LAPB_C;
        dptr[6] &= ~LAPB_E;
        dptr[6] |= SSSID_SPARE;
        dptr += AX25_ADDR_LEN;
 
-       memcpy(dptr, &sk->nr->dest_addr,   sizeof(ax25_address));
+       memcpy(dptr, &sk->nr->dest_addr, AX25_ADDR_LEN);
        dptr[6] &= ~LAPB_C;
        dptr[6] |= LAPB_E;
        dptr[6] |= SSSID_SPARE;
index bb87f74fd5ab5bbfee61a74b37cc1ac36038d929..307c6f6c247fbea072cf0f16ac3d0d3c79d16ec5 100644 (file)
@@ -88,21 +88,20 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
                if ((nr_neigh = (struct nr_neigh *)kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
                        return -ENOMEM;
 
-               memcpy(&nr_neigh->callsign, ax25, sizeof(ax25_address));
-
-               nr_neigh->digipeat= NULL;
-               nr_neigh->dev     = dev;
-               nr_neigh->quality = nr_default.quality;
-               nr_neigh->locked  = 0;
-               nr_neigh->count   = 0;
-               nr_neigh->number  = nr_neigh_no++;
+               nr_neigh->callsign = *ax25;
+               nr_neigh->digipeat = NULL;
+               nr_neigh->dev      = dev;
+               nr_neigh->quality  = nr_default.quality;
+               nr_neigh->locked   = 0;
+               nr_neigh->count    = 0;
+               nr_neigh->number   = nr_neigh_no++;
 
                if (ax25_digi != NULL) {
                        if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) {
                                kfree_s(nr_neigh, sizeof(*nr_neigh));
                                return -ENOMEM;
                        }
-                       memcpy(nr_neigh->digipeat, ax25_digi, sizeof(*ax25_digi));
+                       *nr_neigh->digipeat = *ax25_digi;
                }
                        
                save_flags(flags);
@@ -118,7 +117,7 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
                if ((nr_node = (struct nr_node *)kmalloc(sizeof(*nr_node), GFP_ATOMIC)) == NULL)
                        return -ENOMEM;
 
-               memcpy(&nr_node->callsign, nr, sizeof(ax25_address));
+               nr_node->callsign = *nr;
                memcpy(&nr_node->mnemonic, mnemonic, sizeof(nr_node->mnemonic));
 
                nr_node->which = 0;
@@ -355,14 +354,13 @@ static int nr_add_neigh(ax25_address *callsign, struct device *dev, unsigned int
        if ((nr_neigh = (struct nr_neigh *)kmalloc(sizeof(*nr_neigh), GFP_ATOMIC)) == NULL)
                return -ENOMEM;
 
-       memcpy(&nr_neigh->callsign, callsign, sizeof(ax25_address));
-
-       nr_neigh->digipeat= NULL;
-       nr_neigh->dev     = dev;
-       nr_neigh->quality = quality;
-       nr_neigh->locked  = 1;
-       nr_neigh->count   = 0;
-       nr_neigh->number  = nr_neigh_no++;
+       nr_neigh->callsign = *callsign;
+       nr_neigh->digipeat = NULL;
+       nr_neigh->dev      = dev;
+       nr_neigh->quality  = quality;
+       nr_neigh->locked   = 1;
+       nr_neigh->count    = 0;
+       nr_neigh->number   = nr_neigh_no++;
 
        save_flags(flags);
        cli();
index 6291797cb5004759c31763ffe94322d6ecc14e09..6198574e489cc2b32d45de03594021445c5d56a6 100644 (file)
@@ -192,12 +192,12 @@ void nr_write_internal(struct sock *sk, int frametype)
                        *dptr++  = 0;
                        *dptr++  = frametype;
                        *dptr++  = sk->window;
-                       memcpy(dptr, &sk->nr->user_addr, sizeof(ax25_address));
+                       memcpy(dptr, &sk->nr->user_addr, AX25_ADDR_LEN);
                        dptr[6] &= ~LAPB_C;
                        dptr[6] &= ~LAPB_E;
                        dptr[6] |= SSSID_SPARE;
                        dptr    += AX25_ADDR_LEN;
-                       memcpy(dptr, &sk->nr->source_addr, sizeof(ax25_address));
+                       memcpy(dptr, &sk->nr->source_addr, AX25_ADDR_LEN);
                        dptr[6] &= ~LAPB_C;
                        dptr[6] &= ~LAPB_E;
                        dptr[6] |= SSSID_SPARE;
index 4f99d594aecd1e44e6ac2dd7dfcd7343b9220803..536027232137575be8289f921bb7da1d6af9465b 100644 (file)
@@ -20,6 +20,7 @@
  *             Alan Cox        :       Limit size of allocated blocks.
  *             Alan Cox        :       Fixed the stupid socketpair bug.
  *             Alan Cox        :       BSD compatibility fine tuning.
+ *             Alan Cox        :       Fixed a bug in connect when interrupted.
  *
  *
  * Known differences from reference BSD that was tested:
@@ -69,8 +70,9 @@ static unix_socket *unix_socket_list=NULL;
 #define min(a,b)       (((a)<(b))?(a):(b))
 
 /*
- * Make sure the unix name is null-terminated.
+ *     Make sure the unix name is null-terminated.
  */
 static inline void unix_mkname(struct sockaddr_un * sunaddr, unsigned long len)
 {
        if (len >= sizeof(*sunaddr))
@@ -468,9 +470,13 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
                        sock->state=SS_UNCONNECTED;
                        return -ECONNREFUSED;
                }
-               if(sock->state==SS_CONNECTING)
+               if(sock->state!=SS_CONNECTING)
+                       return -EISCONN;
+               if(flags&O_NONBLOCK)
                        return -EALREADY;
-               return -EISCONN;
+               /*
+                *      Drop through the connect up logic to the wait.
+                */
        }
        
        if(addr_len < sizeof(sunaddr->sun_family)+1 || sunaddr->sun_family!=AF_UNIX)
@@ -478,15 +484,14 @@ static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
                
        unix_mkname(sunaddr, addr_len);
                
-       if(sk->type==SOCK_DGRAM && sk->protinfo.af_unix.other)
-       {
-               sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
-               sk->protinfo.af_unix.other=NULL;
-               sock->state=SS_UNCONNECTED;
-       }
-
-       if(sock->type==SOCK_DGRAM)
+       if(sk->type==SOCK_DGRAM)
        {
+               if(sk->protinfo.af_unix.other)
+               {
+                       sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
+                       sk->protinfo.af_unix.other=NULL;
+                       sock->state=SS_UNCONNECTED;
+               }
                other=unix_find_other(sunaddr->sun_path, &err);
                if(other==NULL)
                        return err;
index 950be2918f038f861c1cfead203dd027e01d941c..16cb97798ceb67a00e9575280f28cda02ba75fca 100644 (file)
@@ -79,7 +79,8 @@ function help () {
      #now pick out the right help text:
      text=$(sed -n "/^$var[    ]*\$/,\${
                        /^$var[         ]*\$/b
-                       /^#.*/b;/^[     ]*\$/q
+                       /^#.*/b
+                       /^[     ]*\$/q
                        p
                    }" Documentation/Configure.help)
      if [ -z "$text" ]
index 33f5092c092a69cf918a4f2c00e42b41de0b5458..f83d5b4ba0c4c70e3925ec7a3bca70c218aa346f 100644 (file)
@@ -588,11 +588,12 @@ function activate_menu () {
                        default="${defaults%%\ 1*}" defaults="${defaults#*\ 1}"
                        ;;
                2)      
+                       echo >>dialog.out
                        read selection <dialog.out
                        default="${selection##* }"
                        case "$selection" in
                        *"-->"*) : ;;
-                       *)       eval help $selection ;;
+                       *)       eval help "$selection" ;;
                        esac
                        ;;
                255|1)