]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.85 2.1.85
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:14:38 +0000 (15:14 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:14:38 +0000 (15:14 -0500)
53 files changed:
CREDITS
Documentation/Configure.help
Documentation/IO-APIC.txt [new file with mode: 0644]
Documentation/filesystems/isofs.txt [new file with mode: 0644]
Documentation/md.txt [new file with mode: 0644]
Documentation/networking/scc.txt [deleted file]
Documentation/networking/z8530drv.txt
MAINTAINERS
Makefile
arch/alpha/config.in
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/irq.c
arch/i386/Makefile
arch/i386/config.in
arch/i386/kernel/bios32.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/irq.c
arch/i386/kernel/irq.h
arch/i386/kernel/setup.c
arch/i386/kernel/smp.c
arch/ppc/config.in
drivers/block/Config.in
drivers/block/genhd.c
drivers/block/md.c
drivers/char/hfmodem/Config.in [new file with mode: 0644]
drivers/net/8390.c
drivers/net/de4x5.c
drivers/net/hamradio/Config.in
drivers/net/hamradio/bpqether.c
drivers/net/hamradio/scc.c
drivers/scsi/Config.in
drivers/scsi/ibmmca.c
drivers/scsi/ibmmca.h
fs/autofs/dirhash.c
fs/dcache.c
fs/proc/root.c
fs/sysv/CHANGES
fs/sysv/INTRO
fs/sysv/inode.c
fs/sysv/namei.c
include/asm-alpha/hardirq.h
include/asm-alpha/softirq.h
include/linux/fs.h
include/linux/proc_fs.h
include/linux/sysv_fs_sb.h
include/linux/timer.h
init/main.c
kernel/ksyms.c
net/ax25/Config.in [new file with mode: 0644]
net/core/dev.c
net/core/scm.c
net/ipv4/ipconfig.c
scripts/checkconfig.pl

diff --git a/CREDITS b/CREDITS
index 3bd591c152ec4a2bd703e646c12cc427ced3a3f3..90896f9d9606d3ad86d95f5d5ece1ded05baf849 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -730,6 +730,16 @@ S: 36 Mudtown Road
 S: Wantage, New Jersey 07461
 S: USA
 
+N: Harald Hoyer
+E: HarryH@Royal.Net
+W: http://hot.spotline.de/
+W: http://home.pages.de/~saturn
+D: ip_masq_quake
+D: md boot support
+S: Alleenstrasse 27
+S: D-71679 Asperg
+S: Germany
+
 N: Miguel de Icaza Amozurrutia
 E: miguel@nuclecu.unam.mx
 D: Linux/SPARC team, Midnight Commander maintainer
@@ -1361,8 +1371,9 @@ S: 79098 Freiburg
 S: Germany
 
 N: Joerg Reuter
-E: jreuter@lykos.oche.de
-E: dl1bke@db0pra.ampr.org
+E: jreuter@poboxes.com
+W: http://www.rat.de/jr/
+W: http://qsl.net/dl1bke/
 D: Generic Z8530 driver, AX.25 DAMA slave implementation
 D: Several AX.25 hacks
 
index 854c49b81e97ba74cb6803dfaf730c535450df98..49a10500c976d1102f5fbacddea14ac36043f2db 100644 (file)
@@ -658,6 +658,11 @@ CONFIG_MD_RAID5
   want to compile it as a module, say M here and read
   Documentation/modules.txt. If unsure, say Y.
 
+Boot support (linear, striped)
+CONFIG_MD_BOOT
+  To boot with an initial linear or striped md device you have to 
+  select this. For lilo and loadlin options see Documentation/md.txt.
+
 Support for Deskstation RPC44 
 CONFIG_DESKSTATION_RPC44
   This is a machine with a R4400 100 MHz CPU. To compile a Linux
@@ -2737,29 +2742,54 @@ CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT
 
 IBMMCA SCSI support
 CONFIG_SCSI_IBMMCA
-  If your computer sports an MCA bus system architecture (IBM PS/2)
-  with an SCSI harddrive, say Y here. Please read
-  Documentation/mca.txt. This driver is also available as a module ( =
-  code which can be inserted in and removed from the running kernel
-  whenever you want). The module will be called ibmmca.o. If you want
-  to compile it as a module, say M here and read
-  Documentation/modules.txt.  
-  Normally, all IBM MCA SCSI adapters are automatically detected. If
-  that doesn't work right however, you can completely override
-  auto-detection by specifying "ibmmcascsi=io1,io2,..." at the boot
-  loader's command prompt or "io_port=io1,io2,... scsi_id=id1,id2,..."
-  as a parameter of insmod.  "io" and "id" are the I/O base address
-  and the SCSI ID of each adapter, respectively.
-  If you want to compile this driver as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want),
-  say M here and read Documentation/modules.txt. The module will be
-  called ibmmca.o.
-
-reset SCSI-devices while booting
-CONFIG_SCSI_IBMMCA_DEV_RESET
-  If you say Y here, each connected SCSI device will get a reset
-  command at boot time. This can be necessary for some special SCSI
-  devices. If unsure, say N.
+  This is support for the IBM SCSI adapter found in many of the PS/2
+  series.  CONFIG_MCA must be set for this to work.  If the adapter
+  isn't found during boot (a common problem for models 56, 57, 76, and
+  77) you'll need to use the 'ibmmcascsi=<pun>', where <pun> is the id
+  of the SCSI subsystem (usually 7, but if that doesn't work check your
+  reference diskette). Owners of model 95 with a LED-matrix-display
+  can in addition activate some activity info like under OS/2, but more
+  informative, by setting 'ibmmcascsi=display' as additional kernel-
+  parameter.
+
+Standard SCSI-order
+CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+  In the PC-world and in most modern SCSI-BIOS-setups, SCSI-harddisks
+  are assigned to the driveletters, starting with the lowest SCSI-id
+  (physical number - pun) to be drive C:, as seen from DOS and similar
+  operating systems. When looking into papers, describing the
+  ANSI-SCSI-standard, this assignment of drives appears to be wrong.
+  The SCSI-standard follows a hardware-hierarchy which says, that
+  id 7 has the highest priority and id 0 the lowest. Therefore, the
+  hostadapters are still today everywhere placed as SCSI-id 7 by
+  default. In the SCSI-standard, the driveletters express the priority
+  of the disk. C: should be the harddisk or a partition on it, with the
+  highest priority. This must therefore be the disk with the highest
+  SCSI-id (e.g. 6) and not the one with the lowest! IBM-BIOS kept the
+  original definition of the SCSI-standard as also industrial- and
+  process-control-machines, like VME-CPUs running under realtime-OSs
+  (e.g. LynxOS, OS9) do.
+  If you like to run Linux on your MCA-machine with the same assignment,
+  of harddisks, as seen from e.g. DOS or OS/2 on your machine, which
+  is in addition conform to the SCSI-standard, you must say 'y' here.
+  This is also necessary for MCA-Linux-users who want to keep downward-
+  compatibility to older releases of the IBM-MCA-SCSI-driver (older than
+  driver-release 2.00 and older than June 1997).
+  If you like to have the lowest SCSI-id assigned as drive C:, as modern
+  SCSI-BIOS do, which is not conform to the standard, but widely spread
+  and common in the PC-world of today, you must say 'n' here.
+
+Reset SCSI-devices at boottime
+CONFIG_IBMMCA_SCSI_DEV_RESET
+  By default, SCSI-devices are reset, when the machine is powered on.
+  However, some devices exist, like special-control-devices,
+  SCSI-CNC-machines, SCSI-printer or scanners of older type, that
+  do not reset, when switched on. If you say 'y' here, each device
+  along your SCSI-bus will get a reset-command after it has been
+  probed, while the kernel is booting. Say always 'n' here, if you
+  have no such strange SCSI-devices on your bus. If you say 'y' and
+  some more modern devices, like harddisks, do not like too much
+  resets, your system will hang when booting.
 
 Always IN2000 SCSI support
 CONFIG_SCSI_IN2000
diff --git a/Documentation/IO-APIC.txt b/Documentation/IO-APIC.txt
new file mode 100644 (file)
index 0000000..84ab57c
--- /dev/null
@@ -0,0 +1,137 @@
+
+most (all) Intel SMP boards have the so-called 'IO-APIC', which is
+an enhanced interrupt controller, able to route hardware interrupts
+to multiple CPUs, or to CPU groups.
+
+Linux supports the IO-APIC, but unfortunately there are broken boards
+out there which make it unsafe to enable the IO-APIC unconditionally.
+The Linux policy thus is to enable the IO-APIC only if it's 100% safe, ie.:
+
+          - the board is on the 'whitelist'
+
+       or - the board does not have PCI pins connected to the IO-APIC
+
+       or - the user has overriden blacklisted settings with the
+            pirq= boot option line.
+
+Kernel messages tell you wether the board is 'safe'. If your box
+boots with enabled IO-APIC IRQs, then you have nothing else to do. Your
+/proc/interrupts will look like this one:
+
+   ---------------------------->
+   hell:~> cat /proc/interrupts
+              CPU0       CPU1
+     0:      90782          0   XT PIC   timer
+     1:       4135       2375  IO-APIC   keyboard
+     2:          0          0   XT PIC   cascade
+     3:        851        807  IO-APIC   serial
+     9:          6         22  IO-APIC   ncr53c8xx
+    11:        307        154  IO-APIC   NE2000
+    13:          4          0   XT PIC   fpu
+    14:      56000      30610  IO-APIC   ide0
+   NMI:          0
+   IPI:          0
+   <----------------------------
+
+some interrupts will still be 'XT PIC', but this is not a problem, none
+of those IRQ sources is 'heavy'.
+
+If one of your boot messages says 'unlisted/blacklisted board, DISABLING
+IO-APIC IRQs', then you should do this to get multi-CPU IO-APIC IRQs
+running:
+
+       A) if your board is unlisted, then mail to linux-smp to get
+          it into either the white or the blacklist
+       B) if your board is blacklisted, then figure out the apropriate
+          pirq= option to get your system boot
+
+
+pirq= lines look like the following in /etc/lilo.conf:
+
+       append="pirq=15,11,10"
+
+the actual numbers depend on your system, on your PCI cards and on their
+PCI slot position. Usually PCI slots are 'daisy chained' before they are
+connected to the PCI chipset irq routing facility (the incoming PIRQ1-4
+lines):
+
+               ,-.        ,-.        ,-.        ,-.        ,-.
+     PIRQ4 ----| |-.    ,-| |-.    ,-| |-.    ,-| |--------| |
+               |S|  \  /  |S|  \  /  |S|  \  /  |S|        |S|
+     PIRQ3 ----|l|-. `/---|l|-. `/---|l|-. `/---|l|--------|l|
+               |o|  \/    |o|  \/    |o|  \/    |o|        |o|
+     PIRQ2 ----|t|-./`----|t|-./`----|t|-./`----|t|--------|t|
+               |1| /\     |2| /\     |3| /\     |4|        |5|
+     PIRQ1 ----| |-  `----| |-  `----| |-  `----| |--------| |
+               `-'        `-'        `-'        `-'        `-'
+
+every PCI card emits a PCI IRQ, which can be INTA,INTB,INTC,INTD:
+
+                               ,-.
+                         INTD--| |
+                               |S|
+                         INTC--|l|
+                               |o|
+                         INTB--|t|
+                               |x|
+                         INTA--| |
+                               `-'
+
+These INTA-D PCI IRQs are always 'local to the card', their real meaning
+depends on which slot they are in. If you look at the daisy chaining diagram,
+a card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ2 of
+the PCI chipset. Most cards issue INTA, this creates optimal distibution
+between the PIRQ lines. (distributing IRQ sources properly is not a
+necessity, PCI IRQs can be shared at will, but it's a good for performance
+to have non shared interrupts). Slot5 should be used for videocards, they
+dont use interrupts normally, thus they are not daisy chained either.
+
+so if you have your SCSI card (IRQ11) in Slot1, Tulip card (IRQ9) in
+Slot2, then you'll have to specify this pirq= line:
+
+       append="pirq=11,9"
+
+the following script tries to figure out such a default pirq= line from
+your PCI configuration:
+
+       echo -n pirq=; echo `scanpci | grep T_L | cut -c56-` | sed 's/ /,/g'
+
+note that this script wont work if you have skipped a few slots or if your
+board does not do default daisy-chaining. (or the IO-APIC has the PIRQ pins
+connected in some strange way). Eg. if in the above case you have your SCSI
+card (IRQ11) in Slot3, and have Slot1 empty:
+
+       append="pirq=0,9,11"
+
+[value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting)
+slots.]
+
+generally, it's always possible to find out the correct pirq= settings, just
+permutate all IRQ numbers properly ... it will take some time though. An
+'incorrect' pirq line will cause the booting process to hang, or a device
+wont function properly (if it's inserted as eg. a module).
+
+If you have 2 PCI buses, then you can use up to 8 pirq values. Although such
+boards tend to have a good configuration and will be included in the
+whitelist.
+
+Be prepared that it might happen that you need some strange pirq line:
+
+       append="pirq=0,0,0,0,0,0,9,11"
+
+use smart try-and-err techniques to find out the correct pirq line ...
+
+
+the following pirq line can be used to force a board into the whitelist:
+
+       append="pirq=0"
+
+[if your system works with no problems after this, then it should be added
+to the official whitelist, contact us]
+
+good luck and mail to linux-smp@vger.rutgers.edu or
+linux-kernel@vger.rutger.edu if you have any problems that are not covered
+by this document.
+
+-- mingo
+
diff --git a/Documentation/filesystems/isofs.txt b/Documentation/filesystems/isofs.txt
new file mode 100644 (file)
index 0000000..8c826f1
--- /dev/null
@@ -0,0 +1,32 @@
+Mount options that are the same as for msdos and vfat partitions.
+
+  conv=binary   Data is returned exactly as is, with CRLF's.  [default]
+  conv=text     (Carriage return, line feed) is replaced with newline.
+  conv=mtext    (Carriage return, line feed) is returned as is (?).
+  conv=auto     Chooses, file by file, conv=binary or conv=text (by guessing)
+  gid=nnn      All files in the partition will be in group nnn.
+  uid=nnn      All files in the partition will be owned by user id nnn.
+  umask=nnn    The permission mask (see umask(1)) for the partition.
+
+Mount options that are the same as vfat partitions. These are only useful
+when using discs encoded using Microsoft's Joliet extensions.
+  iocharset=name Character set to use for converting from Unicode to
+               ASCII.  Joliet filenames are stored in Unicode format, but
+               Unix for the most part doesn't know how to deal with Unicode.
+               There is also an option of doing UTF8 translations with the
+               utf8 option.
+  utf8          Encode Unicode names in UTF8 format. Default is no.
+
+Mount options that are unique to the isofs filesystem.
+  block=512     Set the block size for the disk to 512 bytes
+  block=1024    Set the block size for the disk to 1024 bytes
+  block=2048    Set the block size for the disk to 2048 bytes
+  check=relaxed Matches filenames with different cases
+  check=strict  Matches only filenames with the exact same case
+  cruft         Try to handle badly formatted CDs.
+  map=off       Do not map non-rockridge filenames to lowercase
+  map=normal    Map rockridge filenames to lowercase
+  mode=xxx      Sets the permissions on files to xxx
+  nojoliet      Ignore Joliet extensions if they are present.
+  norock        Ignore rockridge extensions if they are present.
+  unhide        Show hidden files.
diff --git a/Documentation/md.txt b/Documentation/md.txt
new file mode 100644 (file)
index 0000000..0107ca5
--- /dev/null
@@ -0,0 +1,37 @@
+Tools that manage md devices can be found at sweet-smoke.ufr-info-p7.ibp.fr
+in public/Linux/md035.tar.gz.
+
+       Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr>
+
+--
+
+You can boot (if you selected boot support in the configuration) with your md 
+device with the following kernel command line:
+
+md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn
+
+md device no. = the number of the md device ... 
+              0 means md0, 
+             1 md1,
+             2 md2,
+             3 md3,
+             4 md4
+
+raid level = -1 linear mode
+              0 striped mode
+             other modes are currently unsupported.
+
+chunk size factor = (raid-0 and raid-1 only)
+              Set  the chunk size as PAGE_SIZE << n.
+             
+fault level = (raid-1 only)
+              Set  the maximum fault number as n.
+             Currently unsupported due to lack of boot support for raid1.
+                           
+dev0-devn: e.g. /dev/hda1,/dev/hdc1,/dev/sda1,/dev/sdb1
+                           
+my loadlin line looks like this:
+
+e:\loadlin\loadlin e:\zimage root=/dev/md0 md=0,0,4,0,/dev/hdb2,/dev/hdc3 ro
+                           
+        Harald Hoyer <HarryH@Royal.Net>
diff --git a/Documentation/networking/scc.txt b/Documentation/networking/scc.txt
deleted file mode 100644 (file)
index b3eb344..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-You will find subset of the documentation in
-
-                 linux/Documentation/networking/z8530drv.txt
-
-To use this driver you MUST have the full package from:
-
-Internet:
-=========
-
-1. db0bm.automation.fh-aachen.de/incoming/dl1bke/z8530drv-utils-3.0.tar.gz
-
-2. ftp.ucsd.edu:/hamradio/packet/tcpip/incoming/z8530drv-utils-3.0.tar.gz
-   If you can't find it there, try .../tcpip/linux/z8530drv-utils-3.0.tar.gz
-
-and various mirrors (i.e. nic.switch.ch)
-
-The package includes the utilities necessary to initialize and
-control the driver.
-
-Joerg Reuter   ampr-net: dl1bke@db0pra.ampr.org
-               AX-25   : DL1BKE @ DB0ACH.#NRW.DEU.EU
-               Internet: jreuter@lykos.oche.de
index ac22b0b15bb695ff97b655e5a7370f85f46692ea..b566181a91e6afc96b28caa0dd67a388014b9cfb 100644 (file)
@@ -4,9 +4,9 @@ full package from:
 Internet:
 =========
 
-1. ftp://db0bm.automation.fh-aachen.de/incoming/z8530drv/z8530drv-utils-3.0.tar.gz
+1. ftp://ftp.ccac.rwth-aachen.de/pub/jr/z8530drv-utils-3.0-1.tar.gz
 
-2. ftp://ftp.pspt.fi/pub/ham/linux/ax25/z8530drv-utils-3.0.tar.gz
+2. ftp://ftp.pspt.fi/pub/ham/linux/ax25/z8530drv-utils-3.0-1.tar.gz
 
 3. ftp://ftp.ucsd.edu/hamradio/packet/tcpip/incoming/z8530drv-utils-3.0.tar.gz
    If you can't find it there, try .../tcpip/linux/z8530drv-utils-3.0.tar.gz
@@ -23,7 +23,7 @@ http://www.rat.de/jr
 
    ********************************************************************
 
-        (c) 1993,1997 by Joerg Reuter DL1BKE <jreuter@poboxes.com>
+        (c) 1993,1998 by Joerg Reuter DL1BKE <jreuter@poboxes.com>
 
         portions (c) 1993 Guido ten Dolle PE1NNZ
 
index de3b11e925c4ad8eb08a99051168771af5dad7d7..2e8a002941f921dfa9e5ec609413601ec8582b26 100644 (file)
@@ -156,7 +156,9 @@ S:  Supported
 
 DAMA SLAVE for AX.25
 P:     Joerg Reuter
-M:     jreuter@lykos.oche.de
+M:     jreuter@poboxes.com
+W:     http://www.rat.de/jr/
+W:     http://qsl.net/dl1bke/
 L:     linux-hams@vger.rutgers.edu
 S:     Maintained
 
@@ -602,7 +604,9 @@ S:  Maintained
 
 Z8530 DRIVER FOR AX.25
 P:     Joerg Reuter
-M:     jreuter@lykos.oche.de
+M:     jreuter@poboxes.com
+W:     http://www.rat.de/jr/
+W:     http://qsl.net/dl1bke/
 L:     linux-hams@vger.rutgers.edu
 S:     Maintained
 
index 2b386d291ec63ee07f5cb6a4148fa6646e044bf0..5e5b7db9d980c3e87a186b5b0635f6f4dda4b416 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 84
+SUBLEVEL = 85
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
 
index bfad551993bad80780ee6a96bc4203fca3467cf6..aff036696d0019c6fe3483ac3398501b1d4e62e6 100644 (file)
@@ -191,7 +191,7 @@ if [ "$CONFIG_NET" = "y" ]; then
   endmenu
 fi
 
-source drivers/net/hamradio/Config.in
+source net/ax25/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
index e7283d0b4446ed417b213772560812581b155052..c9b6eea236a7dd4296b151022bf11b402aea675b 100644 (file)
@@ -40,7 +40,7 @@ extern void __remlu (void);
 extern void __divqu (void);
 extern void __remqu (void);
 
-EXPORT_SYMBOL(__alpha_bh_counter);
+EXPORT_SYMBOL(local_bh_count);
 EXPORT_SYMBOL(local_irq_count);
 
 /* platform dependent support */
index f1bfa1bef885f37649ab849489cbc6cf0f0ed73e..29d454f03a872a79d1be599f9ad74cddd7abcfcc 100644 (file)
@@ -524,7 +524,7 @@ static inline void handle_nmi(struct pt_regs * regs)
 }
 
 unsigned int local_irq_count[NR_CPUS];
-atomic_t __alpha_bh_counter;
+unsigned int local_bh_count[NR_CPUS];
 
 #ifdef __SMP__
 #error "Me no hablo Alpha SMP"
index bc4e030299e15f9ecd37f3ba8d0f68abd4119831..98bde850fca6a9807f29f54292aa1e83a349a8db 100644 (file)
@@ -23,7 +23,9 @@ OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
 LDFLAGS=-e stext
 LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
 
-CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce
+CFLAGS_PIPE := -pipe
+CFLAGS_NSR  := -fno-strength-reduce
+CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) $(CFLAGS_NSR)
 
 ifdef CONFIG_M386
 CFLAGS := $(CFLAGS) -m386 -DCPU=386
index 8f0582c93b2c29230c194a7a34174b93c1012e07..3e52c2218bc68777a4e226c974c7eb3865c76ea0 100644 (file)
@@ -93,7 +93,7 @@ if [ "$CONFIG_NET" = "y" ]; then
   endmenu
 fi
 
-source drivers/net/hamradio/Config.in
+source net/ax25/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
index 0167c667dcfc9727ace625015283a6629c2205f3..578a2b4d647e8ff57a9dfff7cf0991cd48649a26 100644 (file)
 #include <asm/system.h>
 #include <asm/io.h>
 
+#include <linux/smp_lock.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/smp.h>
+
+#include "irq.h"
+
 /*
  * Generic PCI access -- indirect calls according to detected HW.
  */
@@ -133,7 +140,39 @@ int pcibios_find_device (unsigned short vendor, unsigned short device_id,
 int pcibios_read_config_byte (unsigned char bus,
        unsigned char device_fn, unsigned char where, unsigned char *value)
 {
-       return access_pci->read_config_byte(bus, device_fn, where, value);
+       int res;
+
+       res = access_pci->read_config_byte(bus, device_fn, where, value);
+
+#ifdef __SMP__
+/*
+ * IOAPICs can take PCI IRQs directly, lets first check the mptable:
+ */
+       if (where == PCI_INTERRUPT_LINE) {
+               int irq;
+               char pin;
+
+               /*
+                * get the PCI IRQ INT _physical pin_ for this device
+                */
+               access_pci->read_config_byte(bus, device_fn,
+                                               PCI_INTERRUPT_PIN, &pin);
+               /*
+                * subtle, PCI pins are numbered starting from 1 ...
+                */
+               pin--;
+
+               irq = IO_APIC_get_PCI_irq_vector (bus,PCI_SLOT(device_fn),pin);
+               if (irq != -1)
+                       *value = (unsigned char) irq;
+
+               printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
+                       bus,PCI_SLOT(device_fn), pin, irq);
+
+       }
+#endif
+
+       return res;
 }
 
 int pcibios_read_config_word (unsigned char bus,
index f1206ba6a1844fa11f084d5e5c444b75990d1459..0fdb5c047ef2e4247a5938fc35d3083a37353409 100644 (file)
@@ -109,7 +109,7 @@ void io_apic_write (unsigned int reg, unsigned int value)
        *(io_apic_reg+4) = value;
 }
 
-void enable_IO_APIC_irq (int irq)
+void enable_IO_APIC_irq (unsigned int irq)
 {
        struct IO_APIC_route_entry entry;
 
@@ -121,7 +121,11 @@ void enable_IO_APIC_irq (int irq)
        io_apic_write(0x10+2*irq, *(((int *)&entry)+0));
 }
 
-void disable_IO_APIC_irq (int irq)
+/*
+ * this function is just here to make things complete, otherwise it's
+ * unused
+ */
+void disable_IO_APIC_irq (unsigned int irq)
 {
        struct IO_APIC_route_entry entry;
 
@@ -133,7 +137,7 @@ void disable_IO_APIC_irq (int irq)
        io_apic_write(0x10+2*irq, *(((int *)&entry)+0));
 }
 
-void clear_IO_APIC_irq (int irq)
+void clear_IO_APIC_irq (unsigned int irq)
 {
        struct IO_APIC_route_entry entry;
 
@@ -151,8 +155,9 @@ void clear_IO_APIC_irq (int irq)
  * specific CPU-side IRQs.
  */
 
-#define MAX_PIRQS 4
+#define MAX_PIRQS 8
 int pirq_entries [MAX_PIRQS];
+int pirqs_enabled;
 
 void ioapic_pirq_setup(char *str, int *ints)
 {
@@ -161,9 +166,12 @@ void ioapic_pirq_setup(char *str, int *ints)
        for (i=0; i<MAX_PIRQS; i++)
                pirq_entries[i]=-1;
 
-       if (!ints)
+       if (!ints) {
+               pirqs_enabled=0;
                printk("PIRQ redirection SETUP, trusting MP-BIOS.\n");
-       else {
+
+       } else {
+               pirqs_enabled=1;
                printk("PIRQ redirection SETUP, working around broken MP-BIOS.\n");
                max = MAX_PIRQS;
                if (ints[0] < MAX_PIRQS)
@@ -229,9 +237,10 @@ void setup_IO_APIC_irqs (void)
                        }
                        case MP_BUS_PCI: /* PCI pin */
                        {
-                               irq = mp_irqs[idx].mpc_srcbusirq >> 2;
-                               if (irq>=16)
-                                       printk("WARNING: MP BIOS says PIRQ%d is redirected to %d, suspicious.\n",idx-16, irq); 
+                               /*
+                                * PCI IRQs are 'directly mapped'
+                                */
+                               irq = i;
                                break;
                        }
                        default:
@@ -358,7 +367,7 @@ void setup_IO_APIC_irqs (void)
                printk(" not connected.\n");
 }
 
-void setup_IO_APIC_irq_ISA_default (int irq)
+void setup_IO_APIC_irq_ISA_default (unsigned int irq)
 {
        struct IO_APIC_route_entry entry;
 
@@ -381,8 +390,23 @@ void setup_IO_APIC_irq_ISA_default (int irq)
        io_apic_write(0x11+2*irq, *(((int *)&entry)+1));
 }
 
-void setup_IO_APIC_irq (int irq)
+int IO_APIC_get_PCI_irq_vector (int bus, int slot, int pci_pin)
 {
+       int i;
+
+       for (i=0; i<mp_irq_entries; i++) {
+               int lbus = mp_irqs[i].mpc_srcbus;
+
+               if (IO_APIC_IRQ(i) &&
+                   (mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
+                   !mp_irqs[i].mpc_irqtype &&
+                   (bus == mp_irqs[i].mpc_srcbus) &&
+                   (slot == (mp_irqs[i].mpc_srcbusirq >> 2)) &&
+                   (pci_pin == (mp_irqs[i].mpc_srcbusirq & 3)))
+
+                       return mp_irqs[i].mpc_dstirq;
+       }
+       return -1;
 }
 
 void print_IO_APIC (void)
@@ -471,6 +495,47 @@ void init_sym_mode (void)
        printk("...done.\n");
 }
 
+char ioapic_OEM_ID [16];
+char ioapic_Product_ID [16];
+
+struct ioapic_list_entry {
+       char * oem_id;
+       char * product_id;
+};
+
+struct ioapic_list_entry ioapic_whitelist [] = {
+
+       { "INTEL   "    ,       "PR440FX     "  },
+       { 0             ,       0               }
+};
+
+struct ioapic_list_entry ioapic_blacklist [] = {
+
+       { "OEM00000"    ,       "PROD00000000"  },
+       { 0             ,       0               }
+};
+
+
+static int in_ioapic_list (struct ioapic_list_entry * table)
+{
+       for (;table->oem_id; table++)
+               if ((!strcmp(table->oem_id,ioapic_OEM_ID)) &&
+                   (!strcmp(table->product_id,ioapic_Product_ID)))
+                       return 1;
+       return 0;
+}
+
+static int ioapic_whitelisted (void)
+{
+       return in_ioapic_list(ioapic_whitelist);
+}
+
+static int ioapic_blacklisted (void)
+{
+       return in_ioapic_list(ioapic_blacklist);
+}
+
+
 void setup_IO_APIC (void)
 {
        int i;
@@ -490,8 +555,6 @@ void setup_IO_APIC (void)
                nr_ioapic_registers = reg_01.entries+1;
        }
 
-       init_IO_APIC_traps();
-
        /*
         * do not trust the IO-APIC being empty at bootup
         */
@@ -504,6 +567,30 @@ void setup_IO_APIC (void)
                        setup_IO_APIC_irq_ISA_default (i);
 #endif
 
+       /*
+        * the following IO-APIC's can be enabled:
+        *
+        * - whitelisted ones
+        * - those which have no PCI pins connected
+        * - those for which the user has specified a pirq= parameter
+        */
+       if (    ioapic_whitelisted() ||
+               (nr_ioapic_registers == 16) ||
+               pirqs_enabled)
+       {
+               printk("ENABLING IO-APIC IRQs\n");
+               io_apic_irqs = ~((1<<0)|(1<<2)|(1<<13));
+       } else {
+               if (ioapic_blacklisted())
+                       printk(" blacklisted board, DISABLING IO-APIC IRQs\n");
+               else
+                       printk(" unlisted board, DISABLING IO-APIC IRQs\n");
+
+               printk(" see Documentation/IO-APIC.txt to enable them\n");
+               io_apic_irqs = 0;
+       }
+
+       init_IO_APIC_traps();
        setup_IO_APIC_irqs ();
 
        printk("nr of MP irq sources: %d.\n", mp_irq_entries);
index 872c5bb273b5ed969443075e532f321574a1bb11..f5e61f727f1f833c08d85bb6634b8d18580e65e1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     linux/arch/i386/kernel/irq.c
  *
- *     Copyright (C) 1992 Linus Torvalds
+ *     Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
  *
  * This file contains the code used by various IRQ handling routines:
  * asking for different IRQ's should be done through these routines
 
 #include "irq.h"
 
-/*
- * I had a lockup scenario where a tight loop doing
- * spin_unlock()/spin_lock() on CPU#1 was racing with
- * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
- * apparently the spin_unlock() information did not make it
- * through to CPU#0 ... nasty, is this by design, do we haveto limit
- * 'memory update oscillation frequency' artificially like here?
- *
- * Such 'high frequency update' races can be avoided by careful design, but
- * some of our major constructs like spinlocks use similar techniques,
- * it would be nice to clarify this issue. Set this define to 0 if you
- * want to check wether your system freezes. I suspect the delay done
- * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
- * i thought that such things are guaranteed by design, since we use
- * the 'LOCK' prefix.
- */
-#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 1
-
-#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
-# define SYNC_OTHER_CORES(x) udelay(x+1)
-#else
-/*
- * We have to allow irqs to arrive between __sti and __cli
- */
-# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
-#endif
-
 unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
 
@@ -96,11 +69,8 @@ static unsigned int cached_irq_mask = (1<<NR_IRQS)-1;
 
 spinlock_t irq_controller_lock;
 
-static int irq_events [NR_IRQS] = { -1, };
+static unsigned int irq_events [NR_IRQS] = { -1, };
 static int disabled_irq [NR_IRQS] = { 0, };
-#ifdef __SMP__
-static int irq_owner [NR_IRQS] = { NO_PROC_ID, };
-#endif
 
 /*
  * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
@@ -125,10 +95,54 @@ static int irq_owner [NR_IRQS] = { NO_PROC_ID, };
    *  - explicitly use irq 16-19 depending on which PCI irq
    *    line your PCI controller uses.
    */
-  unsigned int io_apic_irqs = 0xff0000;
+  unsigned int io_apic_irqs = 0;
+#endif
+
+struct hw_interrupt_type {
+       void (*handle)(unsigned int irq, int cpu, struct pt_regs * regs);
+       void (*enable)(unsigned int irq);
+       void (*disable)(unsigned int irq);
+};
+
+
+static void do_8259A_IRQ (unsigned int irq, int cpu, struct pt_regs * regs);
+static void enable_8259A_irq (unsigned int irq);
+static void disable_8259A_irq (unsigned int irq);
+
+static struct hw_interrupt_type i8259A_irq_type = {
+       do_8259A_IRQ,
+       enable_8259A_irq,
+       disable_8259A_irq
+};
+
+
+#ifdef __SMP__
+static void do_ioapic_IRQ (unsigned int irq, int cpu, struct pt_regs * regs);
+static void enable_ioapic_irq (unsigned int irq);
+static void disable_ioapic_irq (unsigned int irq);
+
+static struct hw_interrupt_type ioapic_irq_type = {
+       do_ioapic_IRQ,
+       enable_ioapic_irq,
+       disable_ioapic_irq
+};
 #endif
 
-static inline void mask_8259A(int irq)
+struct hw_interrupt_type *irq_handles[NR_IRQS] =
+{
+       [0 ... 15] = &i8259A_irq_type                   /* standard ISA IRQs */
+#ifdef __SMP__
+       , [16 ... NR_IRQS-1] = &ioapic_irq_type         /* 'high' PCI IRQs */
+#endif
+};
+
+
+/*
+ * These have to be protected by the irq controller spinlock
+ * before being called.
+ */
+
+static inline void mask_8259A(unsigned int irq)
 {
        cached_irq_mask |= 1 << irq;
        if (irq & 8) {
@@ -138,7 +152,7 @@ static inline void mask_8259A(int irq)
        }
 }
 
-static inline void unmask_8259A(int irq)
+static inline void unmask_8259A(unsigned int irq)
 {
        cached_irq_mask &= ~(1 << irq);
        if (irq & 8) {
@@ -148,7 +162,7 @@ static inline void unmask_8259A(int irq)
        }
 }
 
-void set_8259A_irq_mask(int irq)
+void set_8259A_irq_mask(unsigned int irq)
 {
        /*
         * (it might happen that we see IRQ>15 on a UP box, with SMP
@@ -163,21 +177,7 @@ void set_8259A_irq_mask(int irq)
        }
 }
 
-/*
- * These have to be protected by the spinlock
- * before being called.
- */
-void mask_irq(unsigned int irq)
-{
-       if (IO_APIC_IRQ(irq))
-               disable_IO_APIC_irq(irq);
-       else {
-               cached_irq_mask |= 1 << irq;
-               set_8259A_irq_mask(irq);
-       }
-}
-
-void unmask_irq(unsigned int irq)
+void unmask_generic_irq(unsigned int irq)
 {
        if (IO_APIC_IRQ(irq))
                enable_IO_APIC_irq(irq);
@@ -218,8 +218,8 @@ BUILD_IRQ(12) BUILD_IRQ(13) BUILD_IRQ(14) BUILD_IRQ(15)
 BUILD_IRQ(16) BUILD_IRQ(17) BUILD_IRQ(18) BUILD_IRQ(19)
 
 /*
- * [FIXME: anyone with 2 separate PCI buses and 2 IO-APICs,
- *         please speak up and request experimental patches.
+ * [FIXME: anyone with 2 separate PCI buses and 2 IO-APICs, please
+ *        speak up if problems and request experimental patches.
  *         --mingo ]
  */
 
@@ -417,6 +417,33 @@ static inline void wait_on_bh(void)
        } while (atomic_read(&global_bh_count) != 0);
 }
 
+/*
+ * I had a lockup scenario where a tight loop doing
+ * spin_unlock()/spin_lock() on CPU#1 was racing with
+ * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
+ * apparently the spin_unlock() information did not make it
+ * through to CPU#0 ... nasty, is this by design, do we have to limit
+ * 'memory update oscillation frequency' artificially like here?
+ *
+ * Such 'high frequency update' races can be avoided by careful design, but
+ * some of our major constructs like spinlocks use similar techniques,
+ * it would be nice to clarify this issue. Set this define to 0 if you
+ * want to check wether your system freezes. I suspect the delay done
+ * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
+ * i thought that such things are guaranteed by design, since we use
+ * the 'LOCK' prefix.
+ */
+#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 1
+
+#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
+# define SYNC_OTHER_CORES(x) udelay(x+1)
+#else
+/*
+ * We have to allow irqs to arrive between __sti and __cli
+ */
+# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
+#endif
+
 static inline void wait_on_irq(int cpu)
 {
        int count = MAXCOUNT;
@@ -563,7 +590,7 @@ void __global_restore_flags(unsigned long flags)
 
 #endif
 
-static int handle_IRQ_event(int irq, struct pt_regs * regs)
+static int handle_IRQ_event(unsigned int irq, struct pt_regs * regs)
 {
        struct irqaction * action;
        int status;
@@ -591,43 +618,118 @@ static int handle_IRQ_event(int irq, struct pt_regs * regs)
 }
 
 
-/*
- * disable/enable_irq() wait for all irq contexts to finish
- * executing. Also it's recursive.
- */
 void disable_irq(unsigned int irq)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&irq_controller_lock, flags);
-       disabled_irq[irq]++;
-       mask_irq(irq);
+       irq_handles[irq]->disable(irq);
        spin_unlock_irqrestore(&irq_controller_lock, flags);
 
        synchronize_irq();
 }
 
-void enable_irq(unsigned int irq)
+/*
+ * disable/enable_irq() wait for all irq contexts to finish
+ * executing. Also it's recursive.
+ */
+static void disable_8259A_irq(unsigned int irq)
 {
-       unsigned long flags;
+       disabled_irq[irq]++;
+       cached_irq_mask |= 1 << irq;
+       set_8259A_irq_mask(irq);
+}
 
+#ifdef __SMP__
+static void disable_ioapic_irq(unsigned int irq)
+{
+       disabled_irq[irq]++;
+       /*
+        * We do not disable IO-APIC irqs in hardware ...
+        */
+}
+#endif
+
+void enable_8259A_irq (unsigned int irq)
+{
+       unsigned long flags;
        spin_lock_irqsave(&irq_controller_lock, flags);
-       disabled_irq[irq]--;
-       unmask_irq(irq);
+       if (disabled_irq[irq])
+               disabled_irq[irq]--;
+       else {
+               spin_unlock_irqrestore(&irq_controller_lock, flags);
+               return;
+       }
+       cached_irq_mask &= ~(1 << irq);
+       set_8259A_irq_mask(irq);
        spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
+#ifdef __SMP__
+void enable_ioapic_irq (unsigned int irq)
+{
+       unsigned long flags;
+       int cpu = smp_processor_id(), should_handle_irq;
+
+       spin_lock_irqsave(&irq_controller_lock, flags);
+       if (disabled_irq[irq])
+               disabled_irq[irq]--;
+       else {
+               spin_unlock_irqrestore(&irq_controller_lock, flags);
+               return;
+       }
+       /*
+        * In the SMP+IOAPIC case it might happen that there are an unspecified
+        * number of pending IRQ events unhandled. We protect against multiple
+        * enable_irq()'s executing them via disable_irq[irq]++
+        */
+       if (!disabled_irq[irq] && irq_events[irq]) {
+               struct pt_regs regs; /* FIXME: these are fake currently */
+
+               disabled_irq[irq]++;
+               spin_unlock(&irq_controller_lock);
+               release_irqlock(cpu);
+               irq_enter(cpu, irq);
+again:
+               handle_IRQ_event(irq, &regs);
+
+               spin_lock(&irq_controller_lock);
+               disabled_irq[irq]--;
+               should_handle_irq=0;
+               if (--irq_events[irq] && !disabled_irq[irq]) {
+                       should_handle_irq=1;
+                       disabled_irq[irq]++;
+               }
+               spin_unlock(&irq_controller_lock);
+
+               if (should_handle_irq)
+                       goto again;
+
+               irq_exit(cpu, irq);
+               __restore_flags(flags);
+       } else {
+               enable_IO_APIC_irq(irq);
+               spin_unlock_irqrestore(&irq_controller_lock, flags);
+       }
+}
+#endif
+
+void enable_irq(unsigned int irq)
+{
+       irq_handles[irq]->enable(irq);
+}
+
 /*
  * Careful! The 8259A is a fragile beast, it pretty
  * much _has_ to be done exactly like this (mask it
  * first, _then_ send the EOI, and the order of EOI
  * to the two 8259s is important!
  */
-static inline void mask_and_ack_8259A(int irq_nr)
+static inline void mask_and_ack_8259A(unsigned int irq)
 {
        spin_lock(&irq_controller_lock);
-       cached_irq_mask |= 1 << irq_nr;
-       if (irq_nr & 8) {
+       cached_irq_mask |= 1 << irq;
+       if (irq & 8) {
                inb(0xA1);      /* DUMMY */
                outb(cached_A1,0xA1);
                outb(0x62,0x20);        /* Specific EOI to cascade */
@@ -640,7 +742,7 @@ static inline void mask_and_ack_8259A(int irq_nr)
        spin_unlock(&irq_controller_lock);
 }
 
-static void do_8259A_IRQ(int irq, int cpu, struct pt_regs * regs)
+static void do_8259A_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
 {
        mask_and_ack_8259A(irq);
 
@@ -656,45 +758,36 @@ static void do_8259A_IRQ(int irq, int cpu, struct pt_regs * regs)
 }
 
 #ifdef __SMP__
-/*
- * FIXME! This is completely broken.
- */
-static void do_ioapic_IRQ(int irq, int cpu, struct pt_regs * regs)
+static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
 {
-       int should_handle_irq;
+       int should_handle_irq = 0;
+
+       ack_APIC_irq();
 
        spin_lock(&irq_controller_lock);
-       should_handle_irq = 0;
-       if (!irq_events[irq]++ && !disabled_irq[irq]) {
-               should_handle_irq = 1;
-               irq_owner[irq] = cpu;
-               hardirq_enter(cpu);
-       }
 
-       ack_APIC_irq();
+       if (!irq_events[irq]++ && !disabled_irq[irq])
+               should_handle_irq = 1;
 
        spin_unlock(&irq_controller_lock);
-       
-       if (should_handle_irq) {
-again:
-               if (!handle_IRQ_event(irq, regs))
-                       disabled_irq[irq] = 1;
 
-       }
+       irq_enter(cpu, irq);
 
-       spin_lock(&irq_controller_lock);
-       release_irqlock(cpu);
+       if (should_handle_irq) {
+again:
+               handle_IRQ_event(irq, regs);
 
-       if ((--irq_events[irq]) && (!disabled_irq[irq]) && should_handle_irq) {
+               spin_lock(&irq_controller_lock);
+               should_handle_irq=0;
+               if (--irq_events[irq] && !disabled_irq[irq])
+                       should_handle_irq=1;
                spin_unlock(&irq_controller_lock);
-               goto again;
-       }
 
-       irq_owner[irq] = NO_PROC_ID;
-       hardirq_exit(cpu);
-       spin_unlock(&irq_controller_lock);
+               if (should_handle_irq)
+                       goto again;
+       }
 
-       enable_IO_APIC_irq(irq);
+       irq_exit(cpu, irq);
 }
 #endif
 
@@ -714,8 +807,6 @@ again:
  */
 asmlinkage void do_IRQ(struct pt_regs regs)
 {      
-       void (*do_lowlevel_IRQ)(int, int, struct pt_regs *);
-
        /* 
         * We ack quickly, we don't want the irq controller
         * thinking we're snobs just because some other CPU has
@@ -726,18 +817,11 @@ asmlinkage void do_IRQ(struct pt_regs regs)
         * 0 return value means that this irq is already being
         * handled by some other CPU. (or is disabled)
         */
-       int irq = regs.orig_eax & 0xff;
+       unsigned int irq = regs.orig_eax & 0xff;
        int cpu = smp_processor_id();
 
        kstat.irqs[cpu][irq]++;
-
-       do_lowlevel_IRQ = do_8259A_IRQ;
-#ifdef __SMP__
-       if (IO_APIC_IRQ(irq))
-               do_lowlevel_IRQ = do_ioapic_IRQ;
-#endif
-       
-       do_lowlevel_IRQ(irq, cpu, &regs);
+       irq_handles[irq]->handle(irq, cpu, &regs);
 
        /*
         * This should be conditional: we should really get
@@ -751,7 +835,7 @@ asmlinkage void do_IRQ(struct pt_regs regs)
        }
 }
 
-int setup_x86_irq(int irq, struct irqaction * new)
+int setup_x86_irq(unsigned int irq, struct irqaction * new)
 {
        int shared = 0;
        struct irqaction *old, **p;
@@ -780,16 +864,18 @@ int setup_x86_irq(int irq, struct irqaction * new)
 
        if (!shared) {
                spin_lock(&irq_controller_lock);
+#ifdef __SMP__
                if (IO_APIC_IRQ(irq)) {
+                       irq_handles[irq] = &ioapic_irq_type;
                        /*
                         * First disable it in the 8259A:
                         */
                        cached_irq_mask |= 1 << irq;
                        if (irq < 16)
                                set_8259A_irq_mask(irq);
-                       setup_IO_APIC_irq(irq);
                }
-               unmask_irq(irq);
+#endif
+               unmask_generic_irq(irq);
                spin_unlock(&irq_controller_lock);
        }
        restore_flags(flags);
@@ -873,10 +959,11 @@ unsigned long probe_irq_on (void)
         */
        for (i = NR_IRQS-1; i > 0; i--) {
                if (!irq_action[i]) {
-                       spin_lock(&irq_controller_lock);
-                       unmask_irq(i);
+                       unsigned long flags;
+                       spin_lock_irqsave(&irq_controller_lock, flags);
+                       unmask_generic_irq(i);
                        irqs |= (1 << i);
-                       spin_unlock(&irq_controller_lock);
+                       spin_unlock_irqrestore(&irq_controller_lock, flags);
                }
        }
 
@@ -921,6 +1008,7 @@ out:
        return irq_found;
 }
 
+#ifdef __SMP__
 void init_IO_APIC_traps(void)
 {
        int i;
@@ -938,16 +1026,17 @@ void init_IO_APIC_traps(void)
        for (i = 0; i < NR_IRQS ; i++)
                if (IO_APIC_GATE_OFFSET+(i<<3) <= 0xfe)  /* HACK */ {
                        if (IO_APIC_IRQ(i)) {
+                               irq_handles[i] = &ioapic_irq_type;
                                /*
                                 * First disable it in the 8259A:
                                 */
                                cached_irq_mask |= 1 << i;
                                if (i < 16)
                                        set_8259A_irq_mask(i);
-                               setup_IO_APIC_irq(i);
                        }
                }
 }
+#endif
 
 __initfunc(void init_IRQ(void))
 {
@@ -961,9 +1050,6 @@ __initfunc(void init_IRQ(void))
        printk("INIT IRQ\n");
        for (i=0; i<NR_IRQS; i++) {
                irq_events[i] = 0;
-#ifdef __SMP__
-               irq_owner[i] = NO_PROC_ID;
-#endif
                disabled_irq[i] = 0;
        }
        /*
index f1e2edea530cdb387fe3eaed1c01c610beb0d5fb..74a529dac4ae9bba47656e2b8b4c02f66622e7de 100644 (file)
@@ -9,15 +9,15 @@
 
 #define IO_APIC_GATE_OFFSET 0x51
 
-void mask_irq(unsigned int irq_nr);
-void unmask_irq(unsigned int irq_nr);
-void enable_IO_APIC_irq (int irq);
-void disable_IO_APIC_irq (int irq);
-void set_8259A_irq_mask(int irq_nr);
-void setup_IO_APIC_irq (int irq);
+void mask_irq(unsigned int irq);
+void unmask_irq(unsigned int irq);
+void enable_IO_APIC_irq (unsigned int irq);
+void disable_IO_APIC_irq (unsigned int irq);
+void set_8259A_irq_mask(unsigned int irq);
 void ack_APIC_irq (void);
 void setup_IO_APIC (void);
 void init_IO_APIC_traps(void);
+int IO_APIC_get_PCI_irq_vector (int bus, int slot, int fn);
 
 #ifdef __SMP__
  extern unsigned int io_apic_irqs;
@@ -34,6 +34,8 @@ enum mp_bustype {
        MP_BUS_PCI
 };
 extern int mp_bus_id_to_type [MAX_MP_BUSSES];
+extern char ioapic_OEM_ID [16];
+extern char ioapic_Product_ID [16];
 
 extern spinlock_t irq_controller_lock; /*
                                        * Protects both the 8259 and the
@@ -44,7 +46,7 @@ extern spinlock_t irq_controller_lock; /*
 
 #include <asm/atomic.h>
 
-static inline void irq_enter(int cpu, int irq)
+static inline void irq_enter(int cpu, unsigned int irq)
 {
        hardirq_enter(cpu);
        while (test_bit(0,&global_irq_lock)) {
@@ -52,7 +54,7 @@ static inline void irq_enter(int cpu, int irq)
        }
 }
 
-static inline void irq_exit(int cpu, int irq)
+static inline void irq_exit(int cpu, unsigned int irq)
 {
        hardirq_exit(cpu);
        release_irqlock(cpu);
index edddd457882cb8894543b7b2f033ea31134fe029..d2861d3f875dd1c2da93fe5bfba3cf21ae4e0093 100644 (file)
@@ -331,8 +331,9 @@ struct cpu_model_info {
 
 static struct cpu_model_info cpu_models[] __initdata = {
        { X86_VENDOR_INTEL,     4,
-               { "486 DX-25/33", "486 DX-50", "486 SX", "487 DX", "486 DX/2", "486 SL", "486 SX/2",
-                 NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL }},
+               { "486 DX-25/33", "486 DX-50", "486 SX", "486 DX/2", "486 SL", "486 SX/2",
+                 NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL,
+                 NULL, NULL }},
        { X86_VENDOR_INTEL,     5,
          { "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75+",
            "OverDrive PODP5V83", "Pentium MMX", NULL, NULL,
index 35944e8487f66d6bba7c18893c1940a429bcd5c2..52b41c79033e1e200166cb61bf41a2c5ce157079 100644 (file)
@@ -258,10 +258,14 @@ __initfunc(static int smp_read_mpc(struct mp_config_table *mpc))
        }
        memcpy(str,mpc->mpc_oem,8);
        str[8]=0;
+       memcpy(ioapic_OEM_ID,str,9);
        printk("OEM ID: %s ",str);
+       
        memcpy(str,mpc->mpc_productid,12);
        str[12]=0;
+       memcpy(ioapic_Product_ID,str,13);
        printk("Product ID: %s ",str);
+
        printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
 
        /* set the local APIC address */
@@ -367,14 +371,6 @@ __initfunc(static int smp_read_mpc(struct mp_config_table *mpc))
                                        --mp_irq_entries;
                                }
 
-printk(" Itype:%d Iflag:%d srcbus:%d srcbusI:%d dstapic:%d dstI:%d.\n",
-               m->mpc_irqtype,
-               m->mpc_irqflag,
-               m->mpc_srcbus,
-               m->mpc_srcbusirq,
-               m->mpc_dstapic,
-               m->mpc_dstirq);
-
                                mpt+=sizeof(*m);
                                count+=sizeof(*m);
                                break;
@@ -1372,10 +1368,13 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
                                p->counter = 0;
                                need_resched = 1;
                        }
-                       if (p->priority < DEF_PRIORITY)
+                       if (p->priority < DEF_PRIORITY) {
                                kstat.cpu_nice += user;
-                       else
+                               kstat.per_cpu_nice[cpu] += user;
+                       } else {
                                kstat.cpu_user += user;
+                               kstat.per_cpu_user[cpu] += user;
+                       }
 
                        kstat.cpu_system += system;
                        kstat.per_cpu_system[cpu] += system;
index 95de5ab23fa538a196792490f561a8296b5efafb..6a244a72ae52dd994f191e0cad0e05ff9effa42b 100644 (file)
@@ -129,7 +129,7 @@ if [ "$CONFIG_NET" = "y" ]; then
   endmenu
 fi
 
-source drivers/net/hamradio/Config.in
+source net/ax25/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
index 10e9f56d08c69eac145860959858d4bcab779bd4..99226e40a5e65974df6c41601a71694bddf2e0d7 100644 (file)
@@ -65,6 +65,9 @@ if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
   tristate '   RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
   tristate '   RAID-4/RAID-5 mode' CONFIG_MD_RAID5
 fi
+if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_STRIPED" = "y" ]; then
+  bool '      Boot support (linear, striped)' CONFIG_MD_BOOT
+fi
 tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
 if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
   bool '   Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
index 966a4031e25d63690d1a5627dd356aa64c16547f..06ec5fad382496683a9a5b41bd3da38ea3fe1067 100644 (file)
@@ -1093,6 +1093,9 @@ __initfunc(void device_setup(void))
        extern void console_map_init(void);
 #ifdef CONFIG_PARPORT
        extern int parport_init(void);
+#endif
+#ifdef CONFIG_MD_BOOT
+        extern void md_setup_drive(void) __init;
 #endif
        struct gendisk *p;
        int nr=0;
@@ -1124,4 +1127,7 @@ __initfunc(void device_setup(void))
 #endif
        rd_load();
 #endif
+#ifdef CONFIG_MD_BOOT
+        md_setup_drive();
+#endif
 }
index 8c592c7518cf9f531724cddb72a961ff1836b401..817342efed446c88780de0e1c7f1d5fe24583ca4 100644 (file)
@@ -8,6 +8,7 @@
    A lot of inspiration came from hd.c ...
 
    kerneld support by Boris Tobotras <boris@xtalk.msk.su>
+   boot support for linear and striped mode by Harald Hoyer <HarryH@Royal.Net>
 
    RAID-1/RAID-5 extensions by:
         Ingo Molnar, Miguel de Icaza, Gadi Oxman
 #include <asm/bitops.h>
 #include <asm/atomic.h>
 
+#ifdef CONFIG_MD_BOOT
+extern dev_t name_to_dev_t(char *line) __init;
+#endif
+
 static struct hd_struct md_hd_struct[MAX_MD_DEV];
 static int md_blocksizes[MAX_MD_DEV];
 int md_maxreadahead[MAX_MD_DEV];
@@ -988,10 +993,13 @@ int md_thread(void * arg)
                cli();
                if (!test_bit(THREAD_WAKEUP, &thread->flags)) {
                        do {
-                                spin_lock_irq(&current->sigmask_lock);
+                                spin_lock(&current->sigmask_lock);
                                 flush_signals(current);
-                                spin_unlock_irq(&current->sigmask_lock);
+                                spin_unlock(&current->sigmask_lock);
                                 interruptible_sleep_on(&thread->wqueue);
+                                cli();
+                                if (test_bit(THREAD_WAKEUP, &thread->flags))
+                                       break;
                        } while (signal_pending(current));
                }
        }
@@ -1055,7 +1063,7 @@ int md_do_sync(struct md_dev *mddev)
                 */
                curr_bsize = blksize_size[major][minor];
                if (curr_bsize != blocksize) {
-diff_blocksize:
+               diff_blocksize:
                        if (curr_bsize > blocksize)
                                /*
                                 * this is safe, rounds downwards.
@@ -1163,6 +1171,102 @@ void mdsyncd (void *data)
        
 }
 
+#ifdef CONFIG_MD_BOOT
+struct {
+       int set;
+       int ints[100];
+       char str[100];
+} md_setup_args __initdata = {
+       0,{0},{0}
+};
+
+/* called from init/main.c */
+__initfunc(void md_setup(char *str,int *ints))
+{
+       int i;
+       for(i=0;i<=ints[0];i++) {
+               md_setup_args.ints[i] = ints[i];
+               strcpy(md_setup_args.str, str);
+/*      printk ("md: ints[%d]=%d.\n", i, ints[i]);*/
+       }
+       md_setup_args.set=1;
+       return;
+}
+
+__initfunc(void do_md_setup(char *str,int *ints))
+{
+       int minor, pers, factor, fault;
+       dev_t dev;
+       int i=1;
+
+       if(ints[0] < 4) {
+               printk ("md: Too few Arguments (%d).\n", ints[0]);
+               return;
+       }
+   
+       minor=ints[i++];
+   
+       if (minor >= MAX_MD_DEV) {
+               printk ("md: Minor device number too high.\n");
+               return;
+       }
+
+       pers = 0;
+       
+       switch(ints[i++]) {  /* Raidlevel  */
+       case -1:
+#ifdef CONFIG_MD_LINEAR
+               pers = LINEAR;
+               printk ("md: Setting up md%d as linear device.\n",minor);
+#else 
+               printk ("md: Linear mode not configured." 
+                       "Recompile the kernel with linear mode enabled!\n");
+#endif
+               break;
+       case 0:
+               pers = STRIPED;
+#ifdef CONFIG_MD_STRIPED
+               printk ("md: Setting up md%d as a striped device.\n",minor);
+#else 
+               printk ("md: Striped mode not configured." 
+                       "Recompile the kernel with striped mode enabled!\n");
+#endif
+               break;
+/*      not supported yet
+       case 1:
+               pers = RAID1;
+               printk ("md: Setting up md%d as a raid1 device.\n",minor);
+               break;
+       case 5:
+               pers = RAID5;
+               printk ("md: Setting up md%d as a raid5 device.\n",minor);
+               break;
+*/
+       default:           
+               printk ("md: Unknown or not supported raid level %d.\n", ints[--i]);
+               return;
+       }
+
+       if(pers) {
+
+         factor=ints[i++]; /* Chunksize  */
+         fault =ints[i++]; /* Faultlevel */
+   
+         pers=pers | factor | (fault << FAULT_SHIFT);   
+   
+         while( str && (dev = name_to_dev_t(str))) {
+           do_md_add (minor, dev);
+           if(str = strchr (str, ','))
+             str++;
+         }
+
+         do_md_run (minor, pers);
+         printk ("md: Loading md%d.\n",minor);
+       }
+   
+}
+#endif
+
 void linear_init (void);
 void raid0_init (void);
 void raid1_init (void);
@@ -1216,6 +1320,13 @@ __initfunc(int md_init (void))
 #ifdef CONFIG_MD_RAID5
   raid5_init ();
 #endif
-  
   return (0);
 }
+
+#ifdef CONFIG_MD_BOOT
+__initfunc(void md_setup_drive(void))
+{
+       if(md_setup_args.set)
+               do_md_setup(md_setup_args.str, md_setup_args.ints);
+}
+#endif
diff --git a/drivers/char/hfmodem/Config.in b/drivers/char/hfmodem/Config.in
new file mode 100644 (file)
index 0000000..a23281f
--- /dev/null
@@ -0,0 +1,6 @@
+comment 'Misc. hamradio protocols'
+tristate 'Shortwave radio modem driver' CONFIG_HFMODEM
+if [ "$CONFIG_HFMODEM" != "n" ]; then
+  bool '   HFmodem support for Soundblaster and compatible cards' CONFIG_HFMODEM_SBC
+  bool '   HFmodem support for WSS and Crystal cards' CONFIG_HFMODEM_WSS
+fi
index 597566c24fbf011c58477e3d9001d95507532acc..33d7028f1fdb2ca3f9efa2d1348a6b67d2f349b8 100644 (file)
@@ -54,6 +54,8 @@ static const char *version =
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
 #include <linux/errno.h>
 #include <linux/fcntl.h>
 #include <linux/in.h>
@@ -185,10 +187,12 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
 
     /* Mask interrupts from the ethercard. */
     outb_p(0x00, e8390_base + EN0_IMR);
+    disable_irq(dev->irq);
     synchronize_irq();
     if (dev->interrupt) {
        printk("%s: Tx request while isr active.\n",dev->name);
        outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+       enable_irq(dev->irq);
        ei_local->stat.tx_errors++;
        dev_kfree_skb(skb, FREE_WRITE);
        return 0;
@@ -226,6 +230,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
        ei_local->irqlock = 0;
        dev->tbusy = 1;
        outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+       enable_irq(dev->irq);
        ei_local->stat.tx_errors++;
        return 1;
     }
@@ -272,6 +277,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
     /* Turn 8390 interrupts back on. */
     ei_local->irqlock = 0;
     outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+    enable_irq(dev->irq);
 
     dev_kfree_skb (skb, FREE_WRITE);
     ei_local->stat.tx_bytes += send_length;
@@ -608,7 +614,6 @@ static void ei_receive(struct device *dev)
 static void ei_rx_overrun(struct device *dev)
 {
     int e8390_base = dev->base_addr;
-    unsigned long wait_start_time;
     unsigned char was_txing, must_resend = 0;
     struct ei_device *ei_local = (struct ei_device *) dev->priv;
     
@@ -629,9 +634,7 @@ static void ei_rx_overrun(struct device *dev)
      * it "is not a reliable indicator and subsequently should be ignored."
      * We wait at least 10ms.
      */
-    wait_start_time = jiffies;
-    while (jiffies - wait_start_time <= 1*HZ/100)
-       barrier();
+    udelay(10*1000);
 
     /*
      * Reset RBCR[01] back to zero as per magic incantation.
index 227a06976f67d0d987dc693a10d67013133fb645..54476ebff67281fcd434694ac32639a2d663c567 100644 (file)
@@ -2216,7 +2216,7 @@ pci_probe(struct device *dev, u_long ioaddr))
 __initfunc(static void
 srom_search(int index))
 {
-    u_char pb, dev_fn;
+    u_char pb, dev_fn, tirq;
     u_short dev_id, dev_num, vendor, status;
     u_int tmp, irq = 0, device, class = DE4X5_CLASS_CODE;
     u_long iobase = 0;                     /* Clear upper 32 bits in Alphas */
@@ -2266,8 +2266,8 @@ srom_search(int index))
 
        /* Fetch the IRQ to be used */
 #ifndef __sparc_v9__
-       pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, 
-                                                                (char *)&irq);
+       pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, &tirq);
+       irq = tirq;
 #else
        irq = pdev->irq;
 #endif
index 9b5fb3726f845708574bb0e9adaff9e57909a317..c0719608abe5f33851fb2282afa8acbe1b059bdf 100644 (file)
@@ -1,61 +1,27 @@
-#
-# Amateur Radio protocols and AX.25 device configuration
-#
-# 19971130     Now in an own category to make correct compilation of the 
-#              AX.25 stuff easier...
-#              Joerg Reuter DL1BKE <jreuter@poboxes.com>
+comment 'AX.25 network device drivers'
 
-mainmenu_option next_comment
-comment 'Amateur Radio support'
-bool 'Amateur Radio support' CONFIG_HAMRADIO
-
-if [ "$CONFIG_HAMRADIO" != "n" ] ; then
-  if [ "$CONFIG_NET" != "n" ] ; then
-    comment 'Packet Radio protocols'
-    tristate 'Amateur Radio AX.25 Level 2 protocol' CONFIG_AX25
-    if [ "$CONFIG_AX25" != "n" ]; then
-      bool '   AX.25 DAMA Slave support' CONFIG_AX25_DAMA_SLAVE
-#     bool '   AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER
-      dep_tristate '   Amateur Radio NET/ROM protocol' CONFIG_NETROM $CONFIG_AX25
-      dep_tristate '   Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25
-    fi
-    
-    if [ "$CONFIG_AX25" != "n" ]; then
-      comment 'AX.25 network device drivers'
-      tristate 'Serial port KISS driver' CONFIG_MKISS
-#     tristate 'Serial port 6PACK driver' CONFIG_6PACK
-      tristate 'BPQ Ethernet driver' CONFIG_BPQETHER
-    
-      dep_tristate 'High-speed (DMA) SCC driver for AX.25' CONFIG_DMASCC $CONFIG_AX25
-      tristate 'Z8530 SCC driver' CONFIG_SCC
-      if [ "$CONFIG_SCC" != "n" ]; then
-        bool '   additional delay for PA0HZP OptoSCC compatible boards' CONFIG_SCC_DELAY
-        bool '   support for TRX that feedback the tx signal to rx' CONFIG_SCC_TRXECHO
-      fi
+dep_tristate 'Serial port KISS driver' CONFIG_MKISS $CONFIG_AX25
+# dep_tristate 'Serial port 6PACK driver' CONFIG_6PACK $CONFIG_AX25
+dep_tristate 'BPQ Ethernet driver' CONFIG_BPQETHER $CONFIG_AX25
     
-      tristate 'BAYCOM ser12 fullduplex driver for AX.25' CONFIG_BAYCOM_SER_FDX
-      tristate 'BAYCOM ser12 halfduplex driver for AX.25' CONFIG_BAYCOM_SER_HDX
-      tristate 'BAYCOM picpar and par96 driver for AX.25' CONFIG_BAYCOM_PAR
-    
-      tristate 'Soundcard modem driver' CONFIG_SOUNDMODEM
-      if [ "$CONFIG_SOUNDMODEM" != "n" ]; then
-        bool '   soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC
-        bool '   soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS
-        bool '   soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200
-        bool '   soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7
-        bool '   soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
-        bool '   soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
-        bool '   soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
-      fi
-    fi
-  fi
-   
-  comment 'Misc. hamradio protocols'
-  tristate 'Shortwave radio modem driver' CONFIG_HFMODEM
-  if [ "$CONFIG_HFMODEM" != "n" ]; then
-    bool '   HFmodem support for Soundblaster and compatible cards' CONFIG_HFMODEM_SBC
-    bool '   HFmodem support for WSS and Crystal cards' CONFIG_HFMODEM_WSS
-  fi
+dep_tristate 'High-speed (DMA) SCC driver for AX.25' CONFIG_DMASCC $CONFIG_AX25
+dep_tristate 'Z8530 SCC driver' CONFIG_SCC $CONFIG_AX25
+if [ "$CONFIG_SCC" != "n" ]; then
+  bool '   additional delay for PA0HZP OptoSCC compatible boards' CONFIG_SCC_DELAY
+  bool '   support for TRX that feedback the tx signal to rx' CONFIG_SCC_TRXECHO
 fi
+    
+dep_tristate 'BAYCOM ser12 fullduplex driver for AX.25' CONFIG_BAYCOM_SER_FDX $CONFIG_AX25
+dep_tristate 'BAYCOM ser12 halfduplex driver for AX.25' CONFIG_BAYCOM_SER_HDX $CONFIG_AX25
+dep_tristate 'BAYCOM picpar and par96 driver for AX.25' CONFIG_BAYCOM_PAR $CONFIG_AX25
 
-endmenu
+dep_tristate 'Soundcard modem driver' CONFIG_SOUNDMODEM $CONFIG_AX25
+if [ "$CONFIG_SOUNDMODEM" != "n" ]; then
+  bool '   soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC
+  bool '   soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS
+  bool '   soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200
+  bool '   soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7
+  bool '   soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
+  bool '   soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
+  bool '   soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
+fi
index 54d63121e13c299110188e0f6f7d2df74d18826a..ec9ff47284e019c871b2fdcbf4b2abedb85095fb 100644 (file)
@@ -51,6 +51,7 @@
  *                                             call.
  *                                             Fixed to match Linux networking
  *                                             changes - 2.1.15.
+ *     BPQ   004       Joerg(DL1BKE)           Fixed to not lock up on ifconfig.
  */
 
 #include <linux/config.h>
@@ -78,6 +79,7 @@
 #include <linux/firewall.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/rtnetlink.h>
 
 #include <net/ip.h>
 #include <net/arp.h>
@@ -186,7 +188,11 @@ static int bpq_check_devices(struct device *dev)
                        if (&bpq->axdev == dev)
                                result = 1;
 
-                       unregister_netdev(&bpq->axdev);
+                       /* We should be locked, call 
+                        * unregister_netdevice directly 
+                        */
+
+                       unregister_netdevice(&bpq->axdev);
                        kfree(bpq);
                }
 
@@ -531,7 +537,9 @@ static int bpq_new_device(struct device *dev)
        dev->name = buf;
        dev->init = bpq_dev_init;
 
-       if (register_netdev(dev) != 0) {
+       /* We should be locked, call register_netdevice() directly. */
+
+       if (register_netdevice(dev) != 0) {
                kfree(bpq);
                 return -EIO;
         }
index 11784150e33dac9e18f47f4177183834ed06ffc2..1ca131ba031bf3b19f226329923f51153fe0f93a 100644 (file)
@@ -1,4 +1,4 @@
-#define RCS_ID "$Id: scc.c,v 1.71 1997/11/29 19:59:20 jreuter Exp jreuter $"
+#define RCS_ID "$Id: scc.c,v 1.73 1998/01/29 17:38:51 jreuter Exp jreuter $"
 
 #define VERSION "3.0"
 #define BANNER  "Z8530 SCC driver version "VERSION".dl1bke (experimental) by DL1BKE\n"
@@ -6,6 +6,9 @@
 /*
  * Please use z8530drv-utils-3.0 with this version.
  *            ------------------
+ *
+ * You can find a subset of the documentation in 
+ * linux/Documentation/networking/z8530drv.txt.
  */
 
 /*
@@ -16,7 +19,7 @@
 
    ********************************************************************
 
-       Copyright (c) 1993, 1997 Joerg Reuter DL1BKE
+       Copyright (c) 1993, 1998 Joerg Reuter DL1BKE
 
        portions (c) 1993 Guido ten Dolle PE1NNZ
 
@@ -89,7 +92,8 @@
    970108      - Fixed the remaining problems.
    970402      - Hopefully fixed the problems with the new *_timer()
                  routines, added calibration code.
-   971012      - made SCC_DELAY a CONFIG option, added CONFIG_SCC_TRXECHO
+   971012      - Made SCC_DELAY a CONFIG option, added CONFIG_SCC_TRXECHO
+   980129      - Small fix to avoid lock-up on initialization
 
    Thanks to all who contributed to this driver with ideas and bug
    reports!
@@ -195,7 +199,7 @@ static void scc_key_trx (struct scc_channel *scc, char tx);
 static void scc_isr(int irq, void *dev_id, struct pt_regs *regs);
 static void scc_init_timer(struct scc_channel *scc);
 
-static int scc_net_setup(struct scc_channel *scc, unsigned char *name);
+static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev);
 static int scc_net_init(struct device *dev);
 static int scc_net_open(struct device *dev);
 static int scc_net_close(struct device *dev);
@@ -1529,7 +1533,7 @@ static void z8530_init(void)
  * Allocate device structure, err, instance, and register driver
  */
 
-static int scc_net_setup(struct scc_channel *scc, unsigned char *name)
+static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev)
 {
        unsigned char *buf;
        struct device *dev;
@@ -1553,11 +1557,11 @@ static int scc_net_setup(struct scc_channel *scc, unsigned char *name)
        dev->name = buf;
        dev->init = scc_net_init;
 
-       if (register_netdev(dev) != 0)
+       if ((addev? register_netdevice(dev) : register_netdev(dev)) != 0)
        {
                kfree(dev);
-               return -EIO;
-       }
+                return -EIO;
+        }
 
        return 0;
 }
@@ -1868,7 +1872,7 @@ static int scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
                                        request_region(SCC_Info[2*Nchips+chan].ctrl, 1, "scc ctrl");
                                        request_region(SCC_Info[2*Nchips+chan].data, 1, "scc data");
                                        if (Nchips+chan != 0)
-                                               scc_net_setup(&SCC_Info[2*Nchips+chan], device_name);
+                                               scc_net_setup(&SCC_Info[2*Nchips+chan], device_name, 1);
                                }
                        }
                        
@@ -2178,7 +2182,7 @@ __initfunc(int scc_init (void))
 
        sprintf(devname,"%s0", SCC_DriverName);
        
-       result = scc_net_setup(SCC_Info, devname);
+       result = scc_net_setup(SCC_Info, devname, 0);
        if (result)
        {
                printk(KERN_ERR "z8530drv: cannot initialize module\n");
@@ -2203,7 +2207,7 @@ int init_module(void)
        result = scc_init();
 
        if (result == 0)
-               printk(KERN_INFO "Copyright 1993,1997 Joerg Reuter DL1BKE (jreuter@poboxes.com)\n");
+               printk(KERN_INFO "Copyright 1993,1998 Joerg Reuter DL1BKE (jreuter@poboxes.com)\n");
                
        return result;
 }
index 7738a5bb383ac270b71c7d51564a71e8a67dbb3d..d70bf55b4416fcc12daad6b3c2b47084bcaff8d4 100644 (file)
@@ -84,10 +84,11 @@ if [ "$CONFIG_PCI" = "y" -a "$CONFIG_SCSI_NCR53C7xx" != "y" ]; then
   fi
 fi
 if [ "$CONFIG_MCA" = "y" ]; then
-   dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI
-   if [ "$CONFIG_SCSI_IBMMCA" != "n" ]; then
-      bool '  reset SCSI-devices while booting' CONFIG_SCSI_IBMMCA_DEV_RESET
-   fi
+  bool 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA
+  if [ "$CONFIG_SCSI_IBMMCA" = "y" ]; then
+     bool '  Standard SCSI-order' CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+     bool '  Reset SCSI-devices at boottime' CONFIG_IBMMCA_SCSI_DEV_RESET
+  fi
 fi
 if [ "$CONFIG_PARPORT" != "n" ]; then
   dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI $CONFIG_PARPORT
index 2600f73977dd4a5eeda0d03bbfde0893a9da4276..60be3c6199f739b40b2cc81459ce07c1caebaf31 100644 (file)
    5) Magneto-Optical drives and medium-changers are also recognized, now.
       Therefore, we have a completely gapfree recognition of all SCSI-
       device-types, that are known by Linux up to kernel 2.1.31.
-   6) The flag CONFIG_SCSI_IBMMCA_DEV_RESET has been inserted. If it is set
-      within the configuration, each connected SCSI-device will get a reset
-      command during boottime. This can be necessary for some special
-      SCSI-devices.  (See also the new Config.in file.)
+   6) The flag SCSI_IBMMCA_DEV_RESET has been inserted. If it is set within
+      the configuration, each connected SCSI-device will get a reset command
+      during boottime. This can be necessary for some special SCSI-devices.
+      This flag should be included in Config.in.
+      (See also the new Config.in file.)
    Probable next improvement: bad disk handler.
    - Michael Lang
  
    1) Some debugging and speed optimization applied.
    - Michael Lang
 
+   Dec 15, 1997
+    - chrisb@truespectra.com
+    - made the front panel display thingy optional, specified from the
+    command-line via ibmmcascsi=display.  Along the lines of the /LED
+    option for the OS/2 driver.
+    - fixed small bug in the LED display that would hang some machines.
+    - reversed ordering of the drives (using the
+    IBMMCA_SCSI_ORDER_STANDARD define).  This is necessary for two main
+    reasons:
+       - users who've already installed Linux won't be screwed.  Keep
+       in mind that not everyone is a kernel hacker.
+       - be consistent with the BIOS ordering of the drives.  In the
+       BIOS, id 6 is C:, id 0 might be D:.  With this scheme, they'd be
+       backwards.  This confuses the crap out of those heathens who've
+       got a impure Linux installation (which, <wince>, I'm one of).
+    This whole problem arises because IBM is actually non-standard with
+    the id to BIOS mappings.  You'll find, in fdomain.c, a similar
+    comment about a few FD BIOS revisions.  The Linux (and apparently
+    industry) standard is that C: maps to scsi id (0,0).  Let's stick
+    with that standard.
+    - Since this is technically a branch of my own, I changed the
+    version number to 3.0e-cpb.
+
+   Jan 17, 1998: (v3.0f)
+   1) Addition of some statistical info for /proc in proc_info.
+   2) Taking care of the SCSI-assignment problem, dealed by Chris at Dec 15
+      1997. In fact, IBM is right, concerning the assignment of SCSI-devices 
+      to driveletters. It is conform to the ANSI-definition of the SCSI-
+      standard to assign drive C: to SCSI-id 6, because it is the highest
+      hardware priority after the hostadapter (that has still today by
+      default everywhere id 7). Also realtime-operating systems that I use, 
+      like LynxOS and OS9, which are quite industrial systems use top-down
+      numbering of the harddisks, that is also starting at id 6. Now, one
+      sits a bit between two chairs. On one hand side, using the define
+      IBMMCA_SCSI_ORDER_STANDARD makes Linux assigning disks conform to
+      the IBM- and ANSI-SCSI-standard and keeps this driver downward
+      compatible to older releases, on the other hand side, people is quite
+      habituated in believing that C: is assigned to (0,0) and much other
+      SCSI-BIOS do so. Therefore, I moved the IBMMCA_SCSI_ORDER_STANDARD 
+      define out of the driver and put it into Config.in as subitem of 
+      'IBM SCSI support'. A help, added to Documentation/Configure.help 
+      explains the differences between saying 'y' or 'n' to the user, when 
+      IBMMCA_SCSI_ORDER_STANDARD prompts, so the ordinary user is enabled to 
+      choose the way of assignment, depending on his own situation and gusto.
+   3) Adapted SCSI_IBMMCA_DEV_RESET to the local naming convention, so it is
+      now called IBMMCA_SCSI_DEV_RESET.
+   4) Optimization of proc_info and its subroutines.
+   5) Added more in-source-comments and extended the driver description by
+      some explanation about the SCSI-device-assignment problem.
+   - Michael Lang
+   
+   Jan 18, 1998: (v3.0g)
+   1) Correcting names to be absolutely conform to the later 2.1.x releases.
+      This is necessary for 
+            IBMMCA_SCSI_DEV_RESET -> CONFIG_IBMMCA_SCSI_DEV_RESET
+            IBMMCA_SCSI_ORDER_STANDARD -> CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+   - Michael Lang
 
        TODO:
  
        - It seems that the handling of bad disks is really bad -
 /*--------------------------------------------------------------------*/
 
 /* current version of this driver-source: */
-#define IBMMCA_SCSI_DRIVER_VERSION "3.0d"
+#define IBMMCA_SCSI_DRIVER_VERSION "3.0f"
+
+/* use standard Linux ordering, where C: maps to (0,0), unlike the IBM
+standard which seems to like C: => (6,0) */
+/* #define IBMMCA_SCSI_ORDER_STANDARD is defined/undefined in Config.in
+ * now, while configuring the kernel. */
 
 /*
    Driver Description
    If your boot-partition is not coming up, also edit the /etc/lilo.conf-file
    in a Linux session booted on old kernel and run lilo before reboot. Check
    lilo.conf anyway to get boot on other partitions with foreign OSes right
-   again.
-
+   again. 
+   The problem is, that Linux does not assign the SCSI-devices in the
+   way as described in the ANSI-SCSI-standard. Linux assigns /dev/sda to 
+   the device with at minimum id 0. But the first drive should be at id 6,
+   because for historical reasons, drive at id 6 has, by hardware, the highest
+   priority and a drive at id 0 the lowest. IBM was one of the rare producers,
+   where the BIOS assigns drives belonging to the ANSI-SCSI-standard. Most 
+   other producers' BIOS does not (I think even Adaptec-BIOS). The 
+   IBMMCA_SCSI_ORDER_STANDARD flag helps to be able to choose the preferred 
+   way of SCSI-device-assignment. Defining this flag would result in Linux 
+   determining the devices in the same order as DOS and OS/2 does on your 
+   MCA-machine. This is also standard on most industrial computers. Leaving 
+   this flag undefined will get your devices ordered in the default way of 
+   Linux. See also the remarks of Chris Beauregard from Dec 15, 1997 and
+   the followups.
+   
    (C) Regular Processing 
    Only three functions get involved: ibmmca_queuecommand(), issue_cmd(),
    and interrupt_handler().
 
 /* basic I/O-port of first adapter */
 #define IM_IO_PORT   0x3540
-/* maximum number of hosts that can be find */
+/* maximum number of hosts that can be found */
 #define IM_N_IO_PORT 8
 
 /*requests going into the upper nibble of the Attention register */
@@ -589,16 +666,19 @@ struct im_tsb
    interest, debugging or just for having fun. The left number gives the
    host-adapter number and the right shows the accessed SCSI-ID. */
 
+/* use_display is set by the ibmmcascsi=display command line arg */
+static int use_display = 0;
 #define PS2_DISK_LED_ON(ad,id) {\
-       if( machine_id == 0xf8 ) { outb((char)(id+48), MOD95_LED_PORT ); \
+       if( use_display ) { outb((char)(id+48), MOD95_LED_PORT ); \
         outb((char)(ad+48), MOD95_LED_PORT+1); } \
        else outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR); \
 }
 
+/* bug fixed, Dec 15, 1997, where | was replaced by & here */
 #define PS2_DISK_LED_OFF() {\
-       if( machine_id == 0xf8 ) { outb( ' ', MOD95_LED_PORT ); \
+       if( use_display ) { outb( ' ', MOD95_LED_PORT ); \
         outb(' ', MOD95_LED_PORT+1); } \
-       else outb(inb(PS2_SYS_CTR) | 0x3f, PS2_SYS_CTR); \
+       else outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); \
 }
 
 /*--------------------------------------------------------------------*/
@@ -609,6 +689,8 @@ struct subsys_list_struct
     unsigned short mca_id;
     char *description;
   };
+
+/* List of possible IBM-SCSI-adapters */
 struct subsys_list_struct subsys_list[] =
 {
   {0x8efc, "IBM Fast SCSI-2 Adapter"},
@@ -632,14 +714,14 @@ of the adapter itself. */
 /*local data for a logical device */
 struct logical_device
   {
-    struct im_scb scb;
+    struct im_scb scb; /* SCSI-subsystem-control-block structure */
     struct im_tsb tsb;
     struct im_sge sge[16];
     Scsi_Cmnd *cmd;  /* SCSI-command that is currently in progress */
      
     int device_type; /* type of the SCSI-device. See include/scsi/scsi.h
-                       for interpreation of the possible values */
-    int block_length;
+                       for interpretation of the possible values */
+    int block_length;/* blocksize of a particular logical SCSI-device */
   };
 
 /* statistics of the driver during operations (for proc_info) */
@@ -649,6 +731,8 @@ struct Driver_Statistics
       int ldn_access[MAX_LOG_DEV+1];         /* total accesses on a ldn */
       int ldn_read_access[MAX_LOG_DEV+1];    /* total read-access on a ldn */
       int ldn_write_access[MAX_LOG_DEV+1];   /* total write-access on a ldn */
+      int ldn_inquiry_access[MAX_LOG_DEV+1]; /* total inquiries on a ldn */
+      int ldn_modeselect_access[MAX_LOG_DEV+1]; /* total mode selects on ldn */
       int total_accesses;                    /* total accesses on all ldns */
       int total_interrupts;                  /* total interrupts (should be
                                                same as total_accesses) */
@@ -663,26 +747,28 @@ struct Driver_Statistics
 /* data structure for each host adapter */
 struct ibmmca_hostdata
 {
-  /* array of logical devices */
-    struct logical_device _ld[MAX_LOG_DEV];
-  /* array to convert (pun, lun) into logical device number */
+  /* array of logical devices: */
+    struct logical_device _ld[MAX_LOG_DEV];   
+  /* array to convert (pun, lun) into logical device number: */
     unsigned char _get_ldn[8][8];
   /*array that contains the information about the physical SCSI-devices
-       attached to this host adapter */
+   attached to this host adapter: */
     unsigned char _get_scsi[8][8];
-  /* used only when checking logical devices */
+  /* used only when checking logical devices: */
     int _local_checking_phase_flag;
+  /* report received interrupt: */
     int _got_interrupt;
+  /* report termination-status of SCSI-command: */
     int _stat_result;
-  /* reset status (used only when doing reset) */
+  /* reset status (used only when doing reset): */
     int _reset_status;
-  /* code of the last SCSI command (needed for panic info) */
+  /* code of the last SCSI command (needed for panic info): */
     int _last_scsi_command;
-  /* counter that points on next reassignable ldn for dynamical remapping */
-  /* The default value is 7, that is the first reassignable number in
-     the list on startup. */
+  /* Counter that points on the next reassignable ldn for dynamical 
+   remapping. The default value is 7, that is the first reassignable 
+   number in the list at boottime: */
     int _next_ldn;
-  /* Statistics for this IBM-SCSI-host */
+  /* Statistics-structure for this IBM-SCSI-host: */
     struct Driver_Statistics _IBM_DS;
 };
 
@@ -701,21 +787,21 @@ struct ibmmca_hostdata
 #define IBM_DS (HOSTDATA(shpnt)->_IBM_DS)
 
 /* Define a arbitrary number as subsystem-marker-type. This number is, as 
-   described in the SCSI-Standard, not occupied by other device-types. */
+   described in the ANSI-SCSI-standard, not occupied by other device-types. */
 #define TYPE_IBM_SCSI_ADAPTER   0x2F
 
 /* Define 0xFF for no device type, because this type is not defined within
-   the SCSI-standard, therefore, it can be used and should not cause any
+   the ANSI-SCSI-standard, therefore, it can be used and should not cause any
    harm. */
 #define TYPE_NO_DEVICE          0xFF
 
-/* define medium-changer. If this is not defined previously, define 
-   this type here. */
+/* define medium-changer. If this is not defined previously, e.g. Linux
+   2.0.x, define this type here. */
 #ifndef TYPE_MEDIUM_CHANGER
 #define TYPE_MEDIUM_CHANGER     0x08
 #endif
 
-/* define operations for immediate_assign */
+/* define possible operations for the immediate_assign command */
 #define SET_LDN        0
 #define REMOVE_LDN     1
 
@@ -732,7 +818,7 @@ static int io_port[IM_MAX_HOSTS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 static int scsi_id[IM_MAX_HOSTS] = { 7, 7, 7, 7, 7, 7, 7, 7 };
 
 /* fill module-parameters only, when this define is present.
-   (that is kernel >=2.1.0) */
+   (that is kernel version 2.1.x) */
 #ifdef MODULE_PARM
 MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
 MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i"); 
@@ -1036,24 +1122,19 @@ static char *ti_p(int value)
    return("-");
 }
 
-/* type-interpreter for logical devices 
-   (A bit stupid, but it was necessary to get the '-' and the Hex-codes
-   into one type.) */
+/* interpreter for logical device numbers (ldn) */
 static char *ti_l(int value)
 {
-   switch (value)
-     {
-       case 0:  return("0"); break; case 1:  return("1"); break;
-       case 2:  return("2"); break; case 3:  return("3"); break;
-       case 4:  return("4"); break; case 5:  return("5"); break;
-       case 6:  return("6"); break; case 7:  return("7"); break;
-       case 8:  return("8"); break; case 9:  return("9"); break;
-       case 10: return("a"); break; case 11: return("b"); break;
-        case 12: return("c"); break; case 13: return("d"); break;
-       case 14: return("e"); break; case 15: return("f"); break;
-       default: return("-"); break;
-     }
-   return("-");
+   const char hex[16] = ("0123456789abcdef");
+   static char answer[2];
+
+   answer[1] = (char)(0x0);
+   if (value<=MAX_LOG_DEV)
+     answer[0] = hex[value];
+   else
+     answer[0] = '-';
+   
+   return (char *)&answer;
 }
 
 /* 
@@ -1093,7 +1174,7 @@ static void check_devices (struct Scsi_Host *shpnt)
   memset (get_ldn, TYPE_NO_DEVICE, sizeof get_ldn); /* this is essential ! */
   memset (get_scsi, TYPE_NO_DEVICE, sizeof get_scsi); /* this is essential ! */
 
-  for (lun=0; lun<=7; lun++) /* mark the adapter at its pun on all luns*/
+  for (lun=0; lun<8; lun++) /* mark the adapter at its pun on all luns*/
     {
       get_scsi[subsystem_pun][lun] = TYPE_IBM_SCSI_ADAPTER; 
       get_ldn[subsystem_pun][lun] = MAX_LOG_DEV; /* make sure, the subsystem
@@ -1111,13 +1192,13 @@ static void check_devices (struct Scsi_Host *shpnt)
       immediate_assign(shpnt,0,0,ldn,REMOVE_LDN); /* remove ldn (wherever)*/
     }
 
-  lun = 0;
+  lun = 0; /* default lun is 0 */
 
   /* STEP 2: */
   printk("\nIBM MCA SCSI: Probing SCSI-devices.");
-  for (id=0; id<=7; id++)
+  for (id=0; id<8; id++)
 #ifdef CONFIG_SCSI_MULTI_LUN
-    for (lun=0; lun<=7; lun++)
+    for (lun=0; lun<8; lun++)
 #endif
       {
 #ifdef IM_DEBUG_PROBE
@@ -1137,16 +1218,16 @@ static void check_devices (struct Scsi_Host *shpnt)
          }
       }
   
-  /* STEP 3: */
+  /* STEP 3: */   
   printk("\nIBM MCA SCSI: Mapping SCSI-devices.");
    
   ldn = 0;
   lun = 0;
 
 #ifdef CONFIG_SCSI_MULTI_LUN   
-  for (lun=0; lun<=7 && ldn<MAX_LOG_DEV; lun++)
+  for (lun=0; lun<8 && ldn<MAX_LOG_DEV; lun++)
 #endif
-    for (id=0; id<=7 && ldn<MAX_LOG_DEV; id++)
+    for (id=0; id<8 && ldn<MAX_LOG_DEV; id++)
       {
 #ifdef IM_DEBUG_PROBE
        printk(".");
@@ -1163,7 +1244,7 @@ static void check_devices (struct Scsi_Host *shpnt)
                if (device_exists (shpnt, ldn, &ld[ldn].block_length,
                                   &ld[ldn].device_type))
                  {
-#ifdef CONFIG_SCSI_IBMMCA_DEV_RESET
+#ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
                    int ticks;
                    printk("(resetting)");
                    ticks = IM_RESET_DELAY*HZ;
@@ -1211,8 +1292,8 @@ static void check_devices (struct Scsi_Host *shpnt)
    /* STEP 4: */
    
    /* map remaining ldns to non-existing devices */
-   for (lun=1; lun<=7 && ldn<MAX_LOG_DEV; lun++)
-     for (id=0; id<=7 && ldn<MAX_LOG_DEV; id++)
+   for (lun=1; lun<8 && ldn<MAX_LOG_DEV; lun++)
+     for (id=0; id<8 && ldn<MAX_LOG_DEV; id++)
      {
        if (get_scsi[id][lun] == TYPE_NO_LUN ||
            get_scsi[id][lun] == TYPE_NO_DEVICE)
@@ -1228,24 +1309,29 @@ static void check_devices (struct Scsi_Host *shpnt)
      } 
        
    printk("\n");
-
+#ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+   printk("IBM MCA SCSI: SCSI-access-order: IBM/ANSI.\n");
+#else
+   printk("IBM MCA SCSI: SCSI-access-order: Linux.\n");
+#endif
+   
 #ifdef IM_DEBUG_PROBE
    /* Show the physical and logical mapping during boot. */
    printk("IBM MCA SCSI: Determined SCSI-device-mapping:\n");
    printk("    Physical SCSI-Device Map               Logical SCSI-Device Map\n");
    printk("ID\\LUN  0  1  2  3  4  5  6  7       ID\\LUN  0  1  2  3  4  5  6  7\n");
-   for (id=0; id<=7; id++)
+   for (id=0; id<8; id++)
      {
-       printk("%2d     %2s %2s %2s %2s %2s %2s %2s %2s",
-             id, ti_p(get_scsi[id][0]), ti_p(get_scsi[id][1]), 
-             ti_p(get_scsi[id][2]), ti_p(get_scsi[id][3]), 
-             ti_p(get_scsi[id][4]), ti_p(get_scsi[id][5]), 
-             ti_p(get_scsi[id][6]), ti_p(get_scsi[id][7]));
-       printk("       %2d     %2s %2s %2s %2s %2s %2s %2s %2s\n",
-             id, ti_l(get_ldn[id][0]), ti_l(get_ldn[id][1]), 
-             ti_l(get_ldn[id][2]), ti_l(get_ldn[id][3]), 
-             ti_l(get_ldn[id][4]), ti_l(get_ldn[id][5]),
-             ti_l(get_ldn[id][6]), ti_l(get_ldn[id][7]));
+        printk("%2d     %2s %2s %2s %2s %2s %2s %2s %2s",
+              id, ti_p(get_scsi[id][0]), ti_p(get_scsi[id][1]), 
+              ti_p(get_scsi[id][2]), ti_p(get_scsi[id][3]), 
+              ti_p(get_scsi[id][4]), ti_p(get_scsi[id][5]), 
+              ti_p(get_scsi[id][6]), ti_p(get_scsi[id][7]));
+
+       printk("       %2d     ",id);
+       for (lun=0; lun<8; lun++)
+         printk("%2s ",ti_l(get_ldn[id][lun]));
+       printk("\n");
      }
 #endif
 
@@ -1270,6 +1356,8 @@ static void check_devices (struct Scsi_Host *shpnt)
   memset (IBM_DS.ldn_access, 0x0, sizeof (IBM_DS.ldn_access));
   memset (IBM_DS.ldn_read_access, 0x0, sizeof (IBM_DS.ldn_read_access));
   memset (IBM_DS.ldn_write_access, 0x0, sizeof (IBM_DS.ldn_write_access));
+  memset (IBM_DS.ldn_inquiry_access, 0x0, sizeof (IBM_DS.ldn_inquiry_access));
+  memset (IBM_DS.ldn_modeselect_access, 0x0, sizeof (IBM_DS.ldn_modeselect_access));
   memset (IBM_DS.ldn_assignments, 0x0, sizeof (IBM_DS.ldn_assignments));
    
   return;
@@ -1412,10 +1500,14 @@ device_exists (struct Scsi_Host *shpnt, int ldn, int *block_length,
 void 
 ibmmca_scsi_setup (char *str, int *ints)
 {
-   int i;
-
-   for (i = 0; i < IM_MAX_HOSTS && i < ints[0]; i++)
-      io_port[i] = ints[i+1];
+   if( str && !strcmp( str, "display" ) ) {
+       use_display = 1;
+   } else if( ints ) {
+          int i;
+          for (i = 0; i < IM_MAX_HOSTS && i < ints[0]; i++) {
+             io_port[i] = ints[i+1];
+          }
+   }
 }
 
 #endif
@@ -1597,9 +1689,16 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
   int current_ldn;
   int id,lun;
 
+  /* use industry standard ordering of the IDs */
+#ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+  int target = 6 - cmd->target;
+#else
+  int target = cmd->target;
+#endif
+
   /*if (target,lun) is NO LUN or not existing at all, return error */
-  if ((get_scsi[cmd->target][cmd->lun] == TYPE_NO_LUN)||
-      (get_scsi[cmd->target][cmd->lun] == TYPE_NO_DEVICE))
+  if ((get_scsi[target][cmd->lun] == TYPE_NO_LUN)||
+      (get_scsi[target][cmd->lun] == TYPE_NO_DEVICE))
      {
        cmd->result = DID_NO_CONNECT << 16;
        done (cmd);
@@ -1607,7 +1706,7 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
      }
    
   /*if (target,lun) unassigned, do further checks... */
-  ldn = get_ldn[cmd->target][cmd->lun];
+  ldn = get_ldn[target][cmd->lun];
   if (ldn >= MAX_LOG_DEV) /* on invalid ldn do special stuff */
     {
       if (ldn > MAX_LOG_DEV) /* dynamical remapping if ldn unassigned */
@@ -1623,7 +1722,7 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                      printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n");
                      printk("              On ldn 7-14 SCSI-commands everywhere in progress.\n");
                      printk("              Reporting DID_NO_CONNECT for device (%d,%d).\n",
-                            cmd->target, cmd->lun);
+                            target, cmd->lun);
                      cmd->result = DID_NO_CONNECT << 16;/* return no connect*/
                      done (cmd);
                      return 0;
@@ -1631,8 +1730,8 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
              }
 
            /* unmap non-processing ldn */
-           for (id=0; id<=7; id ++)
-             for (lun=0; lun<=7; lun++)
+           for (id=0; id<8; id ++)
+             for (lun=0; lun<8; lun++)
              {
                 if (get_ldn[id][lun] == next_ldn)
                   {
@@ -1645,9 +1744,9 @@ DYN_ASSIGN:
            /* unassign found ldn (pun,lun does not matter for remove) */
            immediate_assign(shpnt,0,0,next_ldn,REMOVE_LDN);
            /* assign found ldn to aimed pun,lun */
-           immediate_assign(shpnt,cmd->target,cmd->lun,next_ldn,SET_LDN);
+           immediate_assign(shpnt,target,cmd->lun,next_ldn,SET_LDN);
            /* map found ldn to pun,lun */
-           get_ldn[cmd->target][cmd->lun] = next_ldn;
+           get_ldn[target][cmd->lun] = next_ldn;
             /* change ldn to the right value, that is now next_ldn */
            ldn = next_ldn;
            /* set reduced interrupt_handler-mode for checking */
@@ -1668,19 +1767,19 @@ DYN_ASSIGN:
                 /* panic here, because a device, found at boottime has 
                    vanished */
                 panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n",
-                      ldn, cmd->target, cmd->lun);
+                      ldn, target, cmd->lun);
            
            /* set back to normal interrupt_handling */
            local_checking_phase_flag = 0;
            
            /* Information on syslog terminal */
            printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n",
-                  ldn, cmd->target, cmd->lun);
+                  ldn, target, cmd->lun);
            
            /* increase next_ldn for next dynamical assignment */ 
            next_ldn ++;
            if (next_ldn>=MAX_LOG_DEV) next_ldn = 7;
-        }
+        }       
       else
         {  /* wall against Linux accesses to the subsystem adapter */   
             cmd->result = DID_NO_CONNECT << 16;
@@ -1729,7 +1828,7 @@ DYN_ASSIGN:
   printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn);
 #endif
 
-  /* for specific device debugging: */
+  /* for specific device-type debugging: */
 #ifdef IM_DEBUG_CMD_SPEC_DEV
   if (ld[ldn].device_type==IM_DEBUG_CMD_DEVICE)
      printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n", 
@@ -1794,7 +1893,7 @@ DYN_ASSIGN:
             }
            scb->u2.blk.length = ld[ldn].block_length;
           if (++disk_rw_in_progress == 1)
-             PS2_DISK_LED_ON (shpnt->host_no, cmd->target);
+             PS2_DISK_LED_ON (shpnt->host_no, target);
          break;
            
          /* for other devices, enter here. Other types are not known by
@@ -1830,11 +1929,12 @@ DYN_ASSIGN:
           /* Read/write on this non-disk devices is also displayworthy, 
              so flash-up the LED/display. */
           if (++disk_rw_in_progress == 1)
-             PS2_DISK_LED_ON (shpnt->host_no, cmd->target);
+             PS2_DISK_LED_ON (shpnt->host_no, target);
         break;
         }
       break;
     case INQUIRY:
+      IBM_DS.ldn_inquiry_access[ldn]++;
       scb->command = IM_DEVICE_INQUIRY_CMD;
       scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
       break;
@@ -1856,6 +1956,7 @@ DYN_ASSIGN:
     /* Commands that need write-only-mode (system -> device): */
     case MODE_SELECT:
     case MODE_SELECT_10:
+      IBM_DS.ldn_modeselect_access[ldn]++;
       scb->command = IM_OTHER_SCSI_CMD_CMD;      
       scb->enable |= IM_SUPRESS_EXCEPTION_SHORT; /*Select needs WRITE-enabled*/
       scb->u1.scsi_cmd_length = cmd->cmd_len;
@@ -1892,10 +1993,16 @@ ibmmca_abort (Scsi_Cmnd * cmd)
   unsigned int ldn;
   void (*saved_done) (Scsi_Cmnd *);
 
+#ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+  int target = 6 - cmd->target;
+#else
+  int target = cmd->target;
+#endif
+
   /*get logical device number, and disable system interrupts */
   printk ("IBM MCA SCSI: sending abort to device id=%d lun=%d.\n",
-         cmd->target, cmd->lun);
-  ldn = get_ldn[cmd->target][cmd->lun];
+         target, cmd->lun);
+  ldn = get_ldn[target][cmd->lun];
   cli ();
 
   /*if cmd for this ldn has already finished, no need to abort */
@@ -2027,12 +2134,32 @@ static int ldn_access_total_read_write(struct Scsi_Host *shpnt)
    return(a);
 }
 
+static int ldn_access_total_inquiry(struct Scsi_Host *shpnt)
+{
+   int a = 0;
+   int i;
+   
+   for (i=0; i<=MAX_LOG_DEV; i++)
+     a+=IBM_DS.ldn_inquiry_access[i];
+   return(a);
+}
+
+static int ldn_access_total_modeselect(struct Scsi_Host *shpnt)
+{
+   int a = 0;
+   int i;
+   
+   for (i=0; i<=MAX_LOG_DEV; i++)
+     a+=IBM_DS.ldn_modeselect_access[i];
+   return(a);
+}
+
 /* routine to display info in the proc-fs-structure (a deluxe feature) */
 int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
                      int hostno, int inout)
 {
    int len=0;
-   int i,id;
+   int i,id,lun;
    struct Scsi_Host *shpnt;
 
    for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
@@ -2047,6 +2174,11 @@ int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
    len += sprintf(buffer+len, "\n             IBM-SCSI-Subsystem-Linux-Driver, Version %s\n\n\n",
                  IBMMCA_SCSI_DRIVER_VERSION);
    len += sprintf(buffer+len, " SCSI Access-Statistics:\n");
+#ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+   len += sprintf(buffer+len, "               ANSI-SCSI-standard order.: Yes\n");
+#else
+   len += sprintf(buffer+len, "               ANSI-SCSI-standard order.: No\n");
+#endif
 #ifdef CONFIG_SCSI_MULTI_LUN
    len += sprintf(buffer+len, "               Multiple LUN probing.....: Yes\n");
 #else
@@ -2064,8 +2196,14 @@ int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
                  IBM_DS.total_accesses);
    len += sprintf(buffer+len, "                 Total SCSI READ/WRITE..: %d\n",
                  ldn_access_total_read_write(shpnt));
+   len += sprintf(buffer+len, "                 Total SCSI Inquiries...: %d\n",
+                 ldn_access_total_inquiry(shpnt));
+   len += sprintf(buffer+len, "                 Total SCSI Modeselects.: %d\n",
+                 ldn_access_total_modeselect(shpnt));
    len += sprintf(buffer+len, "                 Total SCSI other cmds..: %d\n\n",
-                 IBM_DS.total_accesses - ldn_access_total_read_write(shpnt));
+                 IBM_DS.total_accesses - ldn_access_total_read_write(shpnt)
+                 - ldn_access_total_modeselect(shpnt)
+                 - ldn_access_total_inquiry(shpnt));
    
    len += sprintf(buffer+len, " Logical-Device-Number (LDN) Access-Statistics:\n");
    len += sprintf(buffer+len, "         LDN | Accesses [%%] |   READ    |   WRITE   | ASSIGNMENTS\n");
@@ -2096,11 +2234,11 @@ int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
               ti_p(get_scsi[id][2]), ti_p(get_scsi[id][3]), 
               ti_p(get_scsi[id][4]), ti_p(get_scsi[id][5]), 
               ti_p(get_scsi[id][6]), ti_p(get_scsi[id][7]));
-       len += sprintf(buffer+len, "       %2d     %2s %2s %2s %2s %2s %2s %2s %2s\n",
-              id, ti_l(get_ldn[id][0]), ti_l(get_ldn[id][1]), 
-              ti_l(get_ldn[id][2]), ti_l(get_ldn[id][3]), 
-              ti_l(get_ldn[id][4]), ti_l(get_ldn[id][5]),
-              ti_l(get_ldn[id][6]), ti_l(get_ldn[id][7]));
+       
+       len += sprintf(buffer+len, "       %2d     ",id);
+       for (lun=0; lun<8; lun++)
+         len += sprintf(buffer+len,"%2s ",ti_l(get_ldn[id][lun]));
+       len += sprintf(buffer+len,"\n");
      }
    
    len += sprintf(buffer+len, "(A = IBM-Subsystem, D = Harddisk, T = Tapedrive, P = Processor, W = WORM,\n");
@@ -2125,3 +2263,6 @@ Scsi_Host_Template driver_template = IBMMCA;
 #endif
 
 /*--------------------------------------------------------------------*/
+
+
+
index c858b5935f8be24c79c5d256ec34b1bbacef266e..45ed9dad189f7fdc77b9c1965716fc1257a834ca 100644 (file)
@@ -19,22 +19,30 @@ int ibmmca_biosparam (Disk *, kdev_t, int *);
 extern struct proc_dir_entry proc_scsi_ibmmca;
 
 /*initialization for Scsi_host_template type */
-#define IBMMCA {                                                     \
-          proc_dir:       &proc_scsi_ibmmca,    /*proc_dir*/          \
-         proc_info:      ibmmca_proc_info,     /*proc info fn*/      \
-          name:           "IBMMCA",             /*name*/              \
-          detect:         ibmmca_detect,        /*detect fn*/         \
-          release:        ibmmca_release,       /*release fn*/        \
-          command:        ibmmca_command,       /*command fn*/        \
-          queuecommand:   ibmmca_queuecommand,  /*queuecommand fn*/   \
-          abort:          ibmmca_abort,         /*abort fn*/          \
-          reset:          ibmmca_reset,         /*reset fn*/          \
-          bios_param:     ibmmca_biosparam,     /*bios fn*/           \
-          can_queue:      16,                   /*can_queue*/         \
-          this_id:        7,                    /*set by detect*/     \
-          sg_tablesize:   16,                   /*sg_tablesize*/      \
-          cmd_per_lun:    1,                    /*cmd_per_lun*/       \
-          use_clustering: ENABLE_CLUSTERING     /*use_clustering*/    \
+#define IBMMCA {                                      \
+          NULL,                 /*next*/              \
+          NULL,                 /*usage_count*/       \
+          &proc_scsi_ibmmca,    /*proc_dir*/          \
+          ibmmca_proc_info,     /*proc info fn*/      \
+          "IBMMCA",             /*name*/              \
+          ibmmca_detect,        /*detect fn*/         \
+          ibmmca_release,       /*release fn*/        \
+          NULL,                 /*info fn*/           \
+          ibmmca_command,       /*command fn*/        \
+          ibmmca_queuecommand,  /*queuecommand fn*/   \
+          ibmmca_abort,         /*abort fn*/          \
+          ibmmca_reset,         /*reset fn*/          \
+          NULL,                 /*slave_attach fn*/   \
+          ibmmca_biosparam,     /*bios fn*/           \
+          16,                   /*can_queue*/         \
+          7,                    /*set by detect*/     \
+          16,                   /*sg_tablesize*/      \
+          1,                    /*cmd_per_lun*/       \
+          0,                    /*present*/           \
+          0,                    /*unchecked_isa_dma*/ \
+          ENABLE_CLUSTERING     /*use_clustering*/    \
         }
 
 #endif /* _IBMMCA_H */
+
+
index 60a3c6933b238821f1fb1a264441f3ade91caf18..7169bd075d002d46d73817119babe6ac362fa7db 100644 (file)
@@ -2,7 +2,7 @@
  *
  * linux/fs/autofs/dirhash.c
  *
- *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
  *
  * This file is part of the Linux kernel and is made available under
  * the terms of the GNU General Public License, version 2, or at your
@@ -84,11 +84,15 @@ void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
        ent->next = *dhnp;
        ent->back = dhnp;
        *dhnp = ent;
+       if ( ent->next )
+               ent->next->back = &(ent->next);
 }
 
 void autofs_hash_delete(struct autofs_dir_ent *ent)
 {
        *(ent->back) = ent->next;
+       if ( ent->next )
+               ent->next->back = ent->back;
 
        autofs_delete_usage(ent);
 
index 80562646faae77890455a612127a8a4d7fd8564f..28cc277f5bfde9cdb16d639f1d48aa884f2e4743 100644 (file)
@@ -757,6 +757,30 @@ char * d_path(struct dentry *dentry, char *buffer, int buflen)
        return retval;
 }
 
+/*
+ * Test whether new_dentry is a subdirectory of old_dentry.
+ *
+ * Trivially implemented using the dcache structure
+ */
+int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry)
+{
+       int result;
+
+       result = 0;
+       for (;;) {
+               if (new_dentry != old_dentry) {
+                       struct dentry * parent = new_dentry->d_parent;
+                       if (parent == new_dentry)
+                               break;
+                       new_dentry = parent;
+                       continue;
+               }
+               result = 1;
+               break;
+       }
+       return result;
+}
+
 /*
  * Check whether a dentry already exists for the given name,
  * and return the inode number if it has an inode.
index 83df5cd523070c5d21b69bb4a821b4ebc0e60bc1..3e344bd097779b6f2174ffcaf83a3a192c5c7080 100644 (file)
@@ -621,13 +621,6 @@ static struct proc_dir_entry proc_root_slab = {
        S_IFREG | S_IRUGO, 1, 0, 0,
        0, &proc_array_inode_operations
 };
-#ifdef CONFIG_OMIRR
-static struct proc_dir_entry proc_root_omirr = {
-       PROC_OMIRR, 5, "omirr",
-       S_IFREG | S_IRUSR, 1, 0, 0,
-       0, &proc_omirr_inode_operations
-};
-#endif
 #ifdef __powerpc__
 static struct proc_dir_entry proc_root_ppc_htab = {
        PROC_PPC_HTAB, 8, "ppc_htab",
index 090c328fed922f0afd687b7c1fa09f7109daa0d5..17d7de2438ebfbe2ac6185e041cc1e73a1f5320d 100644 (file)
@@ -7,3 +7,10 @@ Fri Jan 23 1998   Krzysztof G. Baranowski <kgb@manjak.knm.org.pl>
                      in detected_[xenix,sysv4,sysv2,coherent]. Thanks
                      to Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl>
                      for identifying the problem.
+
+Tue Jan 27 1998   Krzysztof G. Baranowski <kgb@manjak.knm.org.pl>
+        *    inode.c: added 2048-byte block support to SystemV FS.
+                     Merged detected_bs[512,1024,2048] into one function:
+                     void detected_bs (u_char type, struct super_block *sb).
+                     Thanks to Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl>
+                     for the patch.
index 9e53cb31758aee363d46e26e37c210402fad981e..de4e4d17cac6f7ba09e14d5520c526e234da1d74 100644 (file)
@@ -18,7 +18,7 @@ These filesystems are rather similar. Here is a comparison with Minix FS:
 * Size of a block or zone (data allocation unit on disk)
   - Minix FS     1024
   - Xenix FS     1024 (also 512 ??)
-  - SystemV FS   1024 (also 512)
+  - SystemV FS   1024 (also 512 and 2048)
   - Coherent FS   512
 
 * General layout: all have one boot block, one super block and
@@ -180,4 +180,3 @@ and not the disk driver's notion of "block".
 
 
 Bruno Haible  <haible@ma2s2.mathematik.uni-karlsruhe.de>
-
index 457a869f9ec3001eee81c39b0798bd97f22018af..b1e4c449960e03be9456b791d47b3ab243b63d47 100644 (file)
 
 #include <asm/uaccess.h>
 
+#if 0
+void sysv_print_inode(struct inode * inode)
+{
+        printk("ino %lu  mode 0%6.6o  lk %d  uid %d  gid %d"
+               "  sz %lu  blks %lu  cnt %u\n",
+               inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid,
+               inode->i_gid, inode->i_size, inode->i_blocks, inode->i_count);
+        printk("  db <0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx"
+               " 0x%lx 0x%lx>\n",
+                inode->u.sysv_i.i_data[0], inode->u.sysv_i.i_data[1],
+                inode->u.sysv_i.i_data[2], inode->u.sysv_i.i_data[3],
+                inode->u.sysv_i.i_data[4], inode->u.sysv_i.i_data[5],
+                inode->u.sysv_i.i_data[6], inode->u.sysv_i.i_data[7],
+                inode->u.sysv_i.i_data[8], inode->u.sysv_i.i_data[9]);
+        printk("  ib <0x%lx 0x%lx 0x%lx>\n",
+                inode->u.sysv_i.i_data[10],
+                inode->u.sysv_i.i_data[11],
+                inode->u.sysv_i.i_data[12]);
+}
+#endif
+
 void sysv_put_inode(struct inode *inode)
 {
        if (inode->i_nlink)
@@ -65,58 +86,35 @@ static struct super_operations sysv_sops = {
  * the time stamp is not < 01-01-1980.
  */
 
-static void detected_bs512 (struct super_block *sb)
-{
-       sb->sv_block_size = 512;
-       sb->sv_block_size_1 = 512-1;
-       sb->sv_block_size_bits = 9;
-       sb->sv_block_size_ratio = 2;
-       sb->sv_block_size_ratio_bits = 1;
-       sb->sv_inodes_per_block = 512/64;
-       sb->sv_inodes_per_block_1 = 512/64-1;
-       sb->sv_inodes_per_block_bits = 9-6;
-       sb->sv_toobig_block = 10 +
-         (sb->sv_ind_per_block = 512/4) +
-         (sb->sv_ind_per_block_2 = (512/4)*(512/4)) +
-         (sb->sv_ind_per_block_3 = (512/4)*(512/4)*(512/4));
-       sb->sv_ind_per_block_1 = 512/4-1;
-       sb->sv_ind_per_block_2_1 = (512/4)*(512/4)-1;
-       sb->sv_ind_per_block_2_bits = 2 *
-         (sb->sv_ind_per_block_bits = 9-2);
-       sb->sv_ind_per_block_block_size_1 = (512/4)*512-1;
-       sb->sv_ind_per_block_block_size_bits = (9-2)+9;
-       sb->sv_ind_per_block_2_block_size_1 = (512/4)*(512/4)*512-1;
-       sb->sv_ind_per_block_2_block_size_bits = (9-2)+(9-2)+9;
-       sb->sv_ind0_size = 10 * 512;
-       sb->sv_ind1_size = (10 + (512/4))* 512;
-       sb->sv_ind2_size = (10 + (512/4) + (512/4)*(512/4)) * 512;
-}
-
-static void detected_bs1024 (struct super_block *sb)
-{
-       sb->sv_block_size = 1024;
-       sb->sv_block_size_1 = 1024-1;
-       sb->sv_block_size_bits = 10;
-       sb->sv_block_size_ratio = 1;
-       sb->sv_block_size_ratio_bits = 0;
-       sb->sv_inodes_per_block = 1024/64;
-       sb->sv_inodes_per_block_1 = 1024/64-1;
-       sb->sv_inodes_per_block_bits = 10-6;
+static void detected_bs (u_char type, struct super_block *sb)
+{
+       u_char n_bits = type+8;
+       int bsize = 1 << n_bits;
+       int bsize_4 = bsize >> 2;
+       
+       sb->sv_block_size = bsize;
+       sb->sv_block_size_1 = bsize-1;
+       sb->sv_block_size_bits = n_bits;
+       sb->sv_block_size_dec_bits = (bsize==512) ? 1 : 0;
+       sb->sv_block_size_inc_bits = (bsize==2048) ? 1 : 0;
+       sb->sv_inodes_per_block = bsize >> 6;
+       sb->sv_inodes_per_block_1 = (bsize >> 6)-1;
+       sb->sv_inodes_per_block_bits = n_bits-6;
        sb->sv_toobig_block = 10 +
-         (sb->sv_ind_per_block = 1024/4) +
-         (sb->sv_ind_per_block_2 = (1024/4)*(1024/4)) +
-         (sb->sv_ind_per_block_3 = (1024/4)*(1024/4)*(1024/4));
-       sb->sv_ind_per_block_1 = 1024/4-1;
-       sb->sv_ind_per_block_2_1 = (1024/4)*(1024/4)-1;
+         (sb->sv_ind_per_block = bsize_4) +
+         (sb->sv_ind_per_block_2 = bsize_4*bsize_4) +
+         (sb->sv_ind_per_block_3 = bsize_4*bsize_4*bsize_4);
+       sb->sv_ind_per_block_1 = bsize_4-1;
+       sb->sv_ind_per_block_2_1 = bsize_4*bsize_4-1;
        sb->sv_ind_per_block_2_bits = 2 *
-         (sb->sv_ind_per_block_bits = 10-2);
-       sb->sv_ind_per_block_block_size_1 = (1024/4)*1024-1;
-       sb->sv_ind_per_block_block_size_bits = (10-2)+10;
-       sb->sv_ind_per_block_2_block_size_1 = (1024/4)*(1024/4)*1024-1;
-       sb->sv_ind_per_block_2_block_size_bits = (10-2)+(10-2)+10;
-       sb->sv_ind0_size = 10 * 1024;
-       sb->sv_ind1_size = (10 + (1024/4))* 1024;
-       sb->sv_ind2_size = (10 + (1024/4) + (1024/4)*(1024/4)) * 1024;
+         (sb->sv_ind_per_block_bits = n_bits-2);
+       sb->sv_ind_per_block_block_size_1 = bsize_4*bsize-1;
+       sb->sv_ind_per_block_block_size_bits = 2*n_bits-2;
+       sb->sv_ind_per_block_2_block_size_1 = bsize_4*bsize_4*bsize-1;
+       sb->sv_ind_per_block_2_block_size_bits = 3*n_bits-4;
+       sb->sv_ind0_size = 10 * bsize;
+       sb->sv_ind1_size = (10 + bsize_4)* bsize;
+       sb->sv_ind2_size = (10 + bsize_4 + bsize_4*bsize_4) * bsize;
 }
 
 static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh)
@@ -126,11 +124,9 @@ static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh)
        sbd = (struct xenix_super_block *) bh->b_data;
        if (sbd->s_magic != 0x2b5544)
                return NULL;
-       switch (sbd->s_type) {
-               case 1: detected_bs512(sb); break;
-               case 2: detected_bs1024(sb); break;
-               default: return NULL;
-       }
+       if (sbd->s_type > 2 || sbd->s_type < 1)
+               return NULL;
+       detected_bs(sbd->s_type, sb);
        sb->sv_type = FSTYPE_XENIX;
        return "Xenix";
 }
@@ -139,8 +135,8 @@ static struct super_block * detected_xenix (struct super_block *sb, struct buffe
        struct xenix_super_block * sbd1;
        struct xenix_super_block * sbd2;
 
-       if (sb->sv_block_size == BLOCK_SIZE)
-               /* block size = 1024, so bh1 = bh2 */
+       if (sb->sv_block_size >= BLOCK_SIZE)
+               /* block size >= 1024, so bh1 = bh2 */
                sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;
        else {
                /* block size = 512, so bh1 != bh2 */
@@ -184,11 +180,9 @@ static const char* detect_sysv4 (struct super_block *sb, struct buffer_head *bh)
                return NULL;
        if (sbd->s_time < 315532800) /* this is likely to happen on SystemV2 FS */
                return NULL;
-       switch (sbd->s_type) {
-               case 1: detected_bs512(sb); break;
-               case 2: detected_bs1024(sb); break;
-               default: return NULL;
-       }
+       if (sbd->s_type > 3 || sbd->s_type < 1)
+               return NULL;
+       detected_bs(sbd->s_type, sb);
        sb->sv_type = FSTYPE_SYSV4;
        return "SystemV";
 }
@@ -196,7 +190,7 @@ static struct super_block * detected_sysv4 (struct super_block *sb, struct buffe
 {
        struct sysv4_super_block * sbd;
 
-       if (sb->sv_block_size == BLOCK_SIZE)
+       if (sb->sv_block_size >= BLOCK_SIZE)
                sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
        else {
                sbd = (struct sysv4_super_block *) bh->b_data;
@@ -241,11 +235,9 @@ static const char* detect_sysv2 (struct super_block *sb, struct buffer_head *bh)
                return NULL;
        if (sbd->s_time < 315532800) /* this is likely to happen on SystemV4 FS */
                return NULL;
-       switch (sbd->s_type) {
-               case 1: detected_bs512(sb); break;
-               case 2: detected_bs1024(sb); break;
-               default: return NULL;
-       }
+       if (sbd->s_type > 3 || sbd->s_type < 1)
+               return NULL;
+       detected_bs(sbd->s_type, sb);
        sb->sv_type = FSTYPE_SYSV2;
        return "SystemV Release 2";
 }
@@ -253,7 +245,7 @@ static struct super_block * detected_sysv2 (struct super_block *sb, struct buffe
 {
        struct sysv2_super_block * sbd;
 
-       if (sb->sv_block_size == BLOCK_SIZE)
+       if (sb->sv_block_size >= BLOCK_SIZE)
                sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
        else {
                sbd = (struct sysv2_super_block *) bh->b_data;
@@ -297,7 +289,7 @@ static const char* detect_coherent (struct super_block *sb, struct buffer_head *
        if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
            || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
                return NULL;
-       detected_bs512(sb);
+       detected_bs(1, sb);
        sb->sv_type = FSTYPE_COH;
        return "Coherent";
 }
@@ -342,7 +334,8 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
        const char *found;
        kdev_t dev = sb->s_dev;
        struct inode *root_inode;
-
+       unsigned long blocknr;
+       
        if (1024 != sizeof (struct xenix_super_block))
                panic("Xenix FS: bad super-block size");
        if ((512 != sizeof (struct sysv4_super_block))
@@ -376,22 +369,29 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
        }
        /* Try to recognize SystemV superblock */
        /* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */
+       /* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */
+       /* Maybe we should also check the device geometry ? */
        {       static int offsets[] = { 9, 15, 18, };
                int i;
                for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)
                        if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {
                                /* Try to recognize SystemV superblock */
                                if ((found = detect_sysv4(sb,bh)) != NULL) {
-                                       sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits;
+                                       if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
+                                               goto bad_shift;
+                                       sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
                                        goto ok;
                                }
                                if ((found = detect_sysv2(sb,bh)) != NULL) {
-                                       sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits;
+                                       if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
+                                               goto bad_shift;
+                                       sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
                                        goto ok;
                                }
                                brelse(bh);
                        }
        }
+       bad_shift:
        sb->s_dev = 0;
        unlock_super(sb);
        if (!silent)
@@ -402,7 +402,14 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
        return NULL;
 
        ok:
-       if (sb->sv_block_size == BLOCK_SIZE) {
+       if (sb->sv_block_size >= BLOCK_SIZE) {
+               if (sb->sv_block_size != BLOCK_SIZE) {
+                       brelse(bh);
+                       set_blocksize(dev, sb->sv_block_size);
+                       blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
+                       if ((bh = bread(dev, blocknr, sb->sv_block_size)) == NULL)
+                               goto bad_superblock;
+               }
                switch (sb->sv_type) {
                        case FSTYPE_XENIX:
                                if (!detected_xenix(sb,bh,bh))
@@ -416,19 +423,21 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
                                if (!detected_sysv2(sb,bh))
                                        goto bad_superblock;
                                break;
-                       default:
-                       bad_superblock:
-                               brelse(bh);
-                               sb->s_dev = 0;
-                               unlock_super(sb);
-                               printk("SysV FS: cannot read superblock in 1024 byte mode\n");
-                               goto failed;
+                       default: goto bad_superblock;
+               goto superblock_ok;
+               bad_superblock:
+                       brelse(bh);
+                       sb->s_dev = 0;
+                       unlock_super(sb);
+                       printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size);
+                       goto failed;
+               superblock_ok:
                }
        } else {
-               /* Switch to another block size. Unfortunately, we have to
-                  release the 1 KB block bh and read it in two parts again. */
+               /* Switch to 512 block size. Unfortunately, we have to
+                  release the block bh and read it again. */
                struct buffer_head *bh1, *bh2;
-               unsigned long blocknr = bh->b_blocknr << sb->sv_block_size_ratio_bits;
+               unsigned long blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
 
                brelse(bh);
                set_blocksize(dev,sb->sv_block_size);
index f147967adcc96435b6cbbe637c6516cd501bbf36..47b0aebba4a68ac5e548832025ad2d00150427fa 100644 (file)
@@ -9,7 +9,6 @@
  *
  *  sysv/namei.c
  *  Copyright (C) 1993  Bruno Haible
- *
  */
 
 
index 79bf079ed1a6b0ab6175e4b4d657c89a8f5564a8..733216be92d9da8fffc72d87cb6924160e4e8b63 100644 (file)
@@ -4,7 +4,6 @@
 #include <linux/tasks.h>
 
 extern unsigned int local_irq_count[NR_CPUS];
-#define in_interrupt() (local_irq_count[smp_processor_id()] != 0)
 
 #ifndef __SMP__
 
index 3cf28cc1c1c9713691950fd57e4697aec3c14ca2..96be9ed43611ae47fd9b392ce1de14f769dcb58e 100644 (file)
@@ -5,7 +5,7 @@
  * is entirely private to an implementation, it should not be
  * referenced at all outside of this file.
  */
-extern atomic_t __alpha_bh_counter;
+extern unsigned int local_bh_count[NR_CPUS];
 
 #define get_active_bhs()       (bh_mask & bh_active)
 
@@ -42,52 +42,50 @@ extern inline void mark_bh(int nr)
        set_bit(nr, &bh_active);
 }
 
-/*
- * These use a mask count to correctly handle
- * nested disable/enable calls
- */
-extern inline void disable_bh(int nr)
-{
-       bh_mask &= ~(1 << nr);
-       bh_mask_count[nr]++;
-}
-
-extern inline void enable_bh(int nr)
-{
-       if (!--bh_mask_count[nr])
-               bh_mask |= 1 << nr;
-}
-
 /*
  * start_bh_atomic/end_bh_atomic also nest
  * naturally by using a counter
  */
 extern inline void start_bh_atomic(void)
 {
-#ifdef __SMP__
-       atomic_inc(&__alpha_bh_counter);
-       synchronize_irq();
-#else
-       atomic_inc(&__alpha_bh_counter);
-#endif
+       local_bh_count[smp_processor_id()]++;
+       barrier();
 }
 
 extern inline void end_bh_atomic(void)
 {
-       atomic_dec(&__alpha_bh_counter);
+       barrier();
+       local_bh_count[smp_processor_id()]--;
 }
 
 #ifndef __SMP__
 
 /* These are for the irq's testing the lock */
-#define softirq_trylock(cpu)   (atomic_read(&__alpha_bh_counter) ? \
-                               0 : \
-                               ((atomic_set(&__alpha_bh_counter,1)),1))
-#define softirq_endlock(cpu)   (atomic_set(&__alpha_bh_counter, 0))
+#define softirq_trylock(cpu) \
+  (local_bh_count[cpu] ? 0 : (local_bh_count[cpu] = 1))
+#define softirq_endlock(cpu) \
+  (local_bh_count[cpu] = 0)
 
 #else
 
 #error FIXME
 
 #endif /* __SMP__ */
+
+/*
+ * These use a mask count to correctly handle
+ * nested disable/enable calls
+ */
+extern inline void disable_bh(int nr)
+{
+       bh_mask &= ~(1 << nr);
+       bh_mask_count[nr]++;
+}
+
+extern inline void enable_bh(int nr)
+{
+       if (!--bh_mask_count[nr])
+               bh_mask |= 1 << nr;
+}
+
 #endif /* _ALPHA_SOFTIRQ_H */
index 4685ce27475a43f40242f312acc5407add78e3c0..e877574809cb7469c4c12f2e401ec3c6dfd49056 100644 (file)
@@ -728,6 +728,9 @@ extern void put_write_access(struct inode *inode);
 extern struct dentry * open_namei(const char * pathname, int flag, int mode);
 extern struct dentry * do_mknod(const char * filename, int mode, dev_t dev);
 extern int do_pipe(int *);
+
+/* fs/dcache.c -- generic fs support functions */
+extern int is_subdir(struct dentry *, struct dentry *);
 extern ino_t find_inode_number(struct dentry *, struct qstr *);
 
 /*
index c5a6054eea2107322fd0fa2b38078a318b5763d7..baec070117c6ca6d4747e187a5e2014f5f20b42a 100644 (file)
@@ -48,7 +48,6 @@ enum root_directory_inos {
        PROC_HARDWARE,
        PROC_SLABINFO,
        PROC_PARPORT,
-       PROC_OMIRR, /* whether enabled or not */
        PROC_PPC_HTAB,
        PROC_SOUND
 };
index 115b95bc67fcc97cb4849288e582c48b7e250346..99a7c125d981e0ef12d168200d0aadd73904cada 100644 (file)
@@ -15,8 +15,8 @@ struct sysv_sb_info {
        unsigned int   s_block_size;    /* zone size, = 512 or = 1024 */
        unsigned int   s_block_size_1;  /* block_size - 1 */
        unsigned int   s_block_size_bits;       /* log2(block_size) */
-       unsigned int   s_block_size_ratio;      /* BLOCK_SIZE / block_size */
-       unsigned int   s_block_size_ratio_bits; /* log2(block_size_ratio) */
+       unsigned int   s_block_size_inc_bits;   /* log2(block_size/BLOCK_SIZE) if >0 */
+       unsigned int   s_block_size_dec_bits;   /* log2(BLOCK_SIZE/block_size) if >0 */
        char           s_convert;       /* flag whether byte ordering requires conversion */
        char           s_kludge_symlinks; /* flag whether symlinks have a kludgey mode */
        char           s_truncate;      /* if 1: names > SYSV_NAMELEN chars are truncated */
@@ -66,15 +66,15 @@ struct sysv_sb_info {
        unsigned long  s_ndatazones;    /* total number of data zones */
        unsigned long  s_nzones;        /* same as s_sbd->s_fsize */
 };
-/* The fields s_block_size_ratio, s_ind_per_block_2_1, s_toobig_block are currently unused. */
+/* The fields s_ind_per_block_2_1, s_toobig_block are currently unused. */
 
 /* sv_ == u.sysv_sb.s_ */
 #define sv_type                                        u.sysv_sb.s_type
 #define sv_block_size                          u.sysv_sb.s_block_size
 #define sv_block_size_1                                u.sysv_sb.s_block_size_1
 #define sv_block_size_bits                     u.sysv_sb.s_block_size_bits
-#define sv_block_size_ratio                    u.sysv_sb.s_block_size_ratio
-#define sv_block_size_ratio_bits               u.sysv_sb.s_block_size_ratio_bits
+#define sv_block_size_inc_bits                 u.sysv_sb.s_block_size_inc_bits
+#define sv_block_size_dec_bits                 u.sysv_sb.s_block_size_dec_bits
 #define sv_convert                             u.sysv_sb.s_convert
 #define sv_kludge_symlinks                     u.sysv_sb.s_kludge_symlinks
 #define sv_truncate                            u.sysv_sb.s_truncate
index 319546d05bf669ce43eb2235966bdd781d8cdd56..f8e0c2085f8f2093df4ec1b3057078005fc8f325 100644 (file)
@@ -2,58 +2,26 @@
 #define _LINUX_TIMER_H
 
 /*
- * DON'T CHANGE THESE!! Most of them are hardcoded into some assembly language
- * as well as being defined here.
- */
-
-/*
- * The timers are:
- *
- * BLANK_TIMER         console screen-saver timer
- *
- * BEEP_TIMER          console beep timer
- *
- * RS_TIMER            timer for the RS-232 ports
- *
- * SWAP_TIMER          timer for the background pageout daemon
- * 
- * HD_TIMER            harddisk timer
- *
- * HD_TIMER2           (atdisk2 patches)
- *
- * FLOPPY_TIMER                floppy disk timer (not used right now)
- * 
- * NET_TIMER           tcp/ip timeout timer
- *
- * COPRO_TIMER         387 timeout for buggy hardware..
- *
- * QIC02_TAPE_TIMER    timer for QIC-02 tape driver (it's not hardcoded)
- *
- * MCD_TIMER           Mitsumi CD-ROM Timer
- *
- * GSCD_TIMER          Goldstar CD-ROM Timer
+ * Old-style timers. Please don't use for any new code.
  *
+ * Numbering of these timers should be consecutive to minimize
+ * processing delays. [MJ]
  */
 
-#define BLANK_TIMER    0
-#define BEEP_TIMER     1
-#define RS_TIMER       2
-#define SWAP_TIMER     3
-
-#define HD_TIMER       16
-#define FLOPPY_TIMER   17
-#define NET_TIMER      19
-#define SOUND_TIMER    20
-#define COPRO_TIMER    21
-
-#define QIC02_TAPE_TIMER       22      /* hhb */
-#define MCD_TIMER      23
-
-#define HD_TIMER2      24
-#define GSCD_TIMER     25
-#define COMTROL_TIMER  26
+#define BLANK_TIMER    0       /* Console screen-saver */
+#define BEEP_TIMER     1       /* Console beep */
+#define RS_TIMER       2       /* RS-232 ports */
+#define SWAP_TIMER     3       /* Background pageout */
+#define BACKGR_TIMER    4      /* io_request background I/O */
+#define HD_TIMER       5       /* Old IDE driver */
+#define FLOPPY_TIMER   6       /* Floppy */
+#define QIC02_TAPE_TIMER 7     /* QIC 02 tape */
+#define MCD_TIMER      8       /* Mitsumi CDROM */
+#define GSCD_TIMER     9       /* Goldstar CDROM */
+#define COMTROL_TIMER  10      /* Comtrol serial */
+#define DIGI_TIMER     11      /* Digi serial */
 
-#define DIGI_TIMER     29
+#define COPRO_TIMER    31      /* 387 timeout for buggy hardware (boot only) */
 
 struct timer_struct {
        unsigned long expires;
index d592ad3267afe9de6caab2fc911a48fd64cbb165..6cefea06f3d76c7d19d6644d36f2ef7d0c64ca68 100644 (file)
@@ -282,6 +282,10 @@ extern void ftape_setup(char *str, int *ints);
 extern void ipc_init(void);
 #endif
 
+#ifdef CONFIG_MD_BOOT
+extern void md_setup(char *str,int *ints) __init;
+#endif
+
 #ifdef __sparc__
 extern int serial_console;
 #endif
@@ -378,6 +382,9 @@ static struct dev_name_struct {
 #ifdef CONFIG_BLK_DEV_FD
        { "fd",      0x0200 },
 #endif
+#ifdef CONFIG_MD_BOOT
+       { "md",      0x0900 },       
+#endif     
 #ifdef CONFIG_BLK_DEV_XD
        { "xda",     0x0d00 },
        { "xdb",     0x0d40 },
@@ -419,7 +426,7 @@ static struct dev_name_struct {
        { NULL, 0 }
 };
 
-__initfunc(static void root_dev_setup(char *line, int *num))
+__initfunc(dev_t name_to_dev_t(char *line))
 {
        int base = 0;
        if (strncmp(line,"/dev/",5) == 0) {
@@ -435,7 +442,12 @@ __initfunc(static void root_dev_setup(char *line, int *num))
                        dev++;
                } while (dev->name);
        }
-       ROOT_DEV = to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
+       return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
+}
+
+__initfunc(static void root_dev_setup(char *line, int *num))
+{
+       ROOT_DEV = name_to_dev_t(line);
 }
 
 /*
@@ -713,6 +725,9 @@ static struct kernel_param cooked_params[] __initdata = {
 #endif
 #ifdef CONFIG_FTAPE
        { "ftape=", ftape_setup},
+#endif
+#ifdef CONFIG_MD_BOOT
+       { "md=", md_setup},
 #endif
        { 0, 0 }
 };
index 96db1f7176e5ae2919e0dc45dcea32ddd61d2d9c..f3125d1625f675457ca84ef34a8cb9258abda621 100644 (file)
@@ -143,6 +143,7 @@ EXPORT_SYMBOL(update_vm_cache);
 EXPORT_SYMBOL(vmtruncate);
 
 /* filesystem internal functions */
+EXPORT_SYMBOL(update_atime);
 EXPORT_SYMBOL(get_super);
 EXPORT_SYMBOL(getname);
 EXPORT_SYMBOL(putname);
@@ -203,6 +204,7 @@ EXPORT_SYMBOL(prune_dcache);
 EXPORT_SYMBOL(shrink_dcache_sb);
 EXPORT_SYMBOL(shrink_dcache_parent);
 EXPORT_SYMBOL(find_inode_number);
+EXPORT_SYMBOL(is_subdir);
 
 #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
 EXPORT_SYMBOL(do_nfsservctl);
diff --git a/net/ax25/Config.in b/net/ax25/Config.in
new file mode 100644 (file)
index 0000000..6bf4a9e
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Amateur Radio protocols and AX.25 device configuration
+#
+# 19971130     Now in an own category to make correct compilation of the 
+#              AX.25 stuff easier...
+#              Joerg Reuter DL1BKE <jreuter@poboxes.com>
+# 19980129     Moved to net/ax25/Config.in, sourcing device drivers.
+
+mainmenu_option next_comment
+comment 'Amateur Radio support'
+bool 'Amateur Radio support' CONFIG_HAMRADIO
+
+if [ "$CONFIG_HAMRADIO" != "n" ] ; then
+  if [ "$CONFIG_NET" != "n" ] ; then
+    comment 'Packet Radio protocols'
+    tristate 'Amateur Radio AX.25 Level 2 protocol' CONFIG_AX25
+    if [ "$CONFIG_AX25" != "n" ]; then
+      bool '   AX.25 DAMA Slave support' CONFIG_AX25_DAMA_SLAVE
+#     bool '   AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER
+      dep_tristate '   Amateur Radio NET/ROM protocol' CONFIG_NETROM $CONFIG_AX25
+      dep_tristate '   Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25
+    fi
+
+    if [ "$CONFIG_AX25" != "n" ]; then
+      source drivers/net/hamradio/Config.in
+    fi
+  fi
+
+  source drivers/char/hfmodem/Config.in
+fi
+
+endmenu
index 2d07e1c57a53919203b6f02b0f8e5d192a4ba4ab..8b8845e1c350b4da1a431f9f6ab32f73dd5ed028 100644 (file)
@@ -49,6 +49,7 @@
  *         Thomas Bogendoerfer :       Return ENODEV for dev_open, if there
  *                                     is no device open function.
  *             Andi Kleen      :       Fix error reporting for SIOCGIFCONF
+ *             RĂ©gis Duchesne  :       Fix the argument check in dev_ioctl()
  *
  */
 
@@ -1534,7 +1535,6 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
        return -EINVAL;
 }
 
-
 /*
  *     This function handles all "interface"-type I/O control requests. The actual
  *     'doing' part of this is dev_ifsioc above.
@@ -1566,25 +1566,19 @@ int dev_ioctl(unsigned int cmd, void *arg)
                return dev_ifname((struct ifreq *)arg);
        }
 
+       /*
+        *      Fetch the interface name from the info block. 
+        */
+
        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
                return -EFAULT;
-
        ifr.ifr_name[IFNAMSIZ-1] = 0;
-
 #ifdef CONFIG_NET_ALIAS
        colon = strchr(ifr.ifr_name, ':');
        if (colon)
                *colon = 0;
 #endif
 
-       /*
-        *      See which interface the caller is talking about. 
-        */
-        
-#ifdef CONFIG_KERNELD
-       dev_load(ifr.ifr_name);
-#endif 
-
        switch(cmd) 
        {
                /*
@@ -1602,6 +1596,9 @@ int dev_ioctl(unsigned int cmd, void *arg)
                case SIOCGIFMAP:
                case SIOCGIFINDEX:
                case SIOCGIFTXQLEN:
+#ifdef CONFIG_KERNELD
+                       dev_load(ifr.ifr_name);
+#endif 
                        ret = dev_ifsioc(&ifr, cmd);
                        if (!ret) {
 #ifdef CONFIG_NET_ALIAS
@@ -1632,6 +1629,9 @@ int dev_ioctl(unsigned int cmd, void *arg)
                case SIOCSIFTXQLEN:
                        if (!suser())
                                return -EPERM;
+#ifdef CONFIG_KERNELD
+                       dev_load(ifr.ifr_name);
+#endif 
                        rtnl_lock();
                        ret = dev_ifsioc(&ifr, cmd);
                        rtnl_unlock();
@@ -1652,6 +1652,9 @@ int dev_ioctl(unsigned int cmd, void *arg)
                default:
                        if (cmd >= SIOCDEVPRIVATE &&
                            cmd <= SIOCDEVPRIVATE + 15) {
+#ifdef CONFIG_KERNELD
+                               dev_load(ifr.ifr_name);
+#endif 
                                rtnl_lock();
                                ret = dev_ifsioc(&ifr, cmd);
                                rtnl_unlock();
@@ -1664,8 +1667,15 @@ int dev_ioctl(unsigned int cmd, void *arg)
                                if (IW_IS_SET(cmd)) {
                                        if (!suser())
                                                return -EPERM;
+#ifdef CONFIG_KERNELD
+                                       dev_load(ifr.ifr_name);
+#endif 
                                        rtnl_lock();
                                }
+#ifdef CONFIG_KERNELD
+                               else
+                                       dev_load(ifr.ifr_name);
+#endif 
                                ret = dev_ifsioc(&ifr, cmd);
                                if (IW_IS_SET(cmd))
                                        rtnl_unlock();
index 5a6d24c4017f0dbd6a476db9fda6b569b88496cd..d0d7d9eecc76ad7a17b6135d31490aa0473df05f 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/major.h>
 #include <linux/stat.h>
 #include <linux/socket.h>
+#include <linux/file.h>
 #include <linux/fcntl.h>
 #include <linux/net.h>
 #include <linux/interrupt.h>
@@ -44,6 +45,7 @@
 
 static __inline__ int scm_check_creds(struct ucred *creds)
 {
+       /* N.B. The test for suser should follow the credential check */
        if (suser())
                return 0;
        if (creds->pid != current->pid ||
@@ -58,11 +60,10 @@ static __inline__ int scm_check_creds(struct ucred *creds)
 
 static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
 {
-       int num;
+       int *fdp = (int*)CMSG_DATA(cmsg);
        struct scm_fp_list *fpl = *fplp;
        struct file **fpp;
-       int *fdp = (int*)CMSG_DATA(cmsg);
-       int i;
+       int i, num;
 
        num = (cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)))/sizeof(int);
 
@@ -86,41 +87,33 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
                return -EINVAL;
        
        /*
-        *      Verify the descriptors.
+        *      Verify the descriptors and increment the usage count.
         */
         
        for (i=0; i< num; i++)
        {
-               int fd;
-               
-               fd = fdp[i];
-               if (fd < 0 || fd >= NR_OPEN)
-                       return -EBADF;
-               if (current->files->fd[fd]==NULL)
+               int fd = fdp[i];
+               struct file *file;
+
+               if (fd < 0 || !(file = fget(fd)))
                        return -EBADF;
-               fpp[i] = current->files->fd[fd];
+               *fpp++ = file;
+               fpl->count++;
        }
-       
-        /* add another reference to these files */
-       for (i=0; i< num; i++, fpp++)
-               (*fpp)->f_count++;
-       fpl->count += num;
-       
        return num;
 }
 
 void __scm_destroy(struct scm_cookie *scm)
 {
-       int i;
        struct scm_fp_list *fpl = scm->fp;
+       int i;
 
-       if (!fpl)
-               return;
-
-       for (i=fpl->count-1; i>=0; i--)
-               close_fp(fpl->fp[i]);
-
-       kfree(fpl);
+       if (fpl) {
+               scm->fp = NULL;
+               for (i=fpl->count-1; i>=0; i--)
+                       close_fp(fpl->fp[i]);
+               kfree(fpl);
+       }
 }
 
 
@@ -223,14 +216,17 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
        cmhdr.cmsg_level = level;
        cmhdr.cmsg_type = type;
        cmhdr.cmsg_len = cmlen;
-       err = copy_to_user(cm, &cmhdr, sizeof cmhdr); 
-       if (!err)
-               err = copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr));
-       if (!err) {
-               cmlen = CMSG_SPACE(len);
-               msg->msg_control += cmlen;
-               msg->msg_controllen -= cmlen;
-       }
+
+       err = -EFAULT;
+       if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
+               goto out; 
+       if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr)))
+               goto out;
+       cmlen = CMSG_SPACE(len);
+       msg->msg_control += cmlen;
+       msg->msg_controllen -= cmlen;
+       err = 0;
+out:
        return err;
 }
 
@@ -240,21 +236,28 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
 
        int fdmax = (msg->msg_controllen - sizeof(struct cmsghdr))/sizeof(int);
        int fdnum = scm->fp->count;
-       int *cmfptr;
-       int err = 0;
-       int i;
        struct file **fp = scm->fp->fp;
+       int *cmfptr;
+       int err = 0, i;
 
        if (fdnum < fdmax)
                fdmax = fdnum;
 
        for (i=0, cmfptr=(int*)CMSG_DATA(cm); i<fdmax; i++, cmfptr++)
        {
-               int new_fd = get_unused_fd();
-               if (new_fd < 0)
+               int new_fd;
+               err = get_unused_fd();
+               if (err < 0)
                        break;
-               current->files->fd[new_fd] = fp[i];
+               new_fd = err;
                err = put_user(new_fd, cmfptr);
+               if (err) {
+                       put_unused_fd(new_fd);
+                       break;
+               }
+               /* Bump the usage count and install the file. */
+               fp[i]->f_count++;
+               current->files->fd[new_fd] = fp[i];
        }
 
        if (i > 0)
@@ -272,38 +275,30 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
                        msg->msg_controllen -= cmlen;
                }
        }
-
-       if (err)
-               i = 0;
+       if (i < fdnum)
+               msg->msg_flags |= MSG_CTRUNC;
 
        /*
-        *      Dump those that don't fit.
+        * All of the files that fit in the message have had their
+        * usage counts incremented, so we just free the list.
         */
-       for ( ; i < fdnum; i++) {
-               msg->msg_flags |= MSG_CTRUNC;
-               close_fp(fp[i]);
-       }
-
-       kfree (scm->fp);
-       scm->fp = NULL;
+       __scm_destroy(scm);
 }
 
 struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 {
-       int i;
        struct scm_fp_list *new_fpl;
+       int i;
 
        if (!fpl)
                return NULL;
 
-       new_fpl = kmalloc(fpl->count*sizeof(int) + sizeof(*fpl), GFP_KERNEL);
-       if (!new_fpl)
-               return NULL;
-
-       memcpy(new_fpl, fpl, fpl->count*sizeof(int) + sizeof(*fpl));
-
-       for (i=fpl->count-1; i>=0; i--)
-               fpl->fp[i]->f_count++;
+       new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
+       if (new_fpl) {
+               memcpy(new_fpl, fpl, sizeof(*fpl));
 
+               for (i=fpl->count-1; i>=0; i--)
+                       fpl->fp[i]->f_count++;
+       }
        return new_fpl;
 }
index 0fa8e90b79cf5363e21b2cfae393c010a57dd992..e297aefdc477f314cba2952d1f66b444f931580e 100644 (file)
@@ -767,7 +767,7 @@ __initfunc(static int ic_bootp_string(char *dest, char *src, int len, int max))
 /*
  *  Process BOOTP extension.
  */
-__initfunc(static void ic_do_bootp_ext(struct bootp_pkt *b, u8 *ext))
+__initfunc(static void ic_do_bootp_ext(u8 *ext))
 {
 #ifdef IPCONFIG_DEBUG
        u8 *c;
@@ -864,7 +864,7 @@ __initfunc(static void ic_bootp_recv(void))
                                opt = ext;
                                ext += ext[1] + 2;
                                if (ext <= end)
-                                       ic_do_bootp_ext(b, opt);
+                                       ic_do_bootp_ext(opt);
                        }
                }
        }
index 2f5092b0125c0b025005ce8f7677347936345364..b82aa1a8bde0119df2298e974f6b438218992a41 100644 (file)
@@ -1,9 +1,12 @@
 #! /usr/bin/perl
 #
 # checkconfig: find uses of CONFIG_* names without matching definitions.
+# Copyright abandoned, 1998, Michael Elizabeth Chastain <mailto:mec@shout.net>.
 
 use integer;
 
+$| = 1;
+
 foreach $file (@ARGV)
 {
     # Open this file.
@@ -24,15 +27,15 @@ foreach $file (@ARGV)
        # Pick up definitions.
        if ( m/^#/o )
        {
-           $iLinuxConfig      = $. if m/^#\s*include\s+<linux\/config\.h>/o;
-           $configList{uc $1} = 1  if m/^#\s*include\s+<config\/(\S*)\.h>/o;
+           $iLinuxConfig      = $. if m/^#\s*include\s*<linux\/config\.h>/o;
+           $configList{uc $1} = 1  if m/^#\s*include\s*<config\/(\S*)\.h>/o;
            $configList{$1}    = 1  if m/^#\s*define\s+CONFIG_(\w*)/o;
            $configList{$1}    = 1  if m/^#\s*undef\s+CONFIG_(\w*)/o;
        }
 
        # Look for usages.
        next unless m/CONFIG_/o;
-       WORD: while ( m/\bCONFIG_(\w*)/og )
+       WORD: while ( m/\bCONFIG_(\w+)/og )
        {
            $fUseConfig = 1;
            last LINE if $iLinuxConfig;