]> git.neil.brown.name Git - history.git/commitdiff
Import 1.3.78 1.3.78
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:10:43 +0000 (15:10 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:10:43 +0000 (15:10 -0500)
179 files changed:
CREDITS
Documentation/Configure.help
Documentation/cdrom/optcd
Documentation/devices.tex
Documentation/devices.txt
Documentation/framerelay.txt [new file with mode: 0644]
MAGIC
MAINTAINERS
Makefile
arch/alpha/config.in
arch/alpha/defconfig
arch/alpha/kernel/time.c
arch/alpha/math-emu/fp-emul.c
arch/alpha/math-emu/ieee-math.c
arch/i386/boot/setup.S
arch/i386/defconfig
arch/i386/kernel/entry.S
arch/i386/kernel/smp.c
arch/i386/mm/init.c
drivers/block/floppy.c
drivers/block/ide.c
drivers/block/ll_rw_blk.c
drivers/block/loop.c
drivers/block/md.c
drivers/cdrom/cdu31a.c
drivers/cdrom/mcdx.c
drivers/cdrom/optcd_isp16.h [deleted file]
drivers/char/cyclades.c
drivers/char/lp.c
drivers/char/pty.c
drivers/char/tga.c
drivers/net/Config.in
drivers/net/Makefile
drivers/net/Space.c
drivers/net/bsd_comp.c
drivers/net/de4x5.c
drivers/net/dlci.c [new file with mode: 0644]
drivers/net/ibmtr.c
drivers/net/ibmtr.h
drivers/net/loopback.c
drivers/net/net_init.c
drivers/net/new_tunnel.c
drivers/net/sdla.c [new file with mode: 0644]
drivers/pci/pci.c
drivers/scsi/NCR5380.c
drivers/scsi/README.g_NCR5380
drivers/scsi/fdomain.c
drivers/scsi/scsi.c
drivers/scsi/scsi.h
drivers/scsi/sd_ioctl.c
drivers/sound/.version
drivers/sound/CHANGELOG
drivers/sound/Makefile
drivers/sound/Readme
drivers/sound/Readme.cards
drivers/sound/ad1848.c
drivers/sound/audio.c
drivers/sound/configure.c
drivers/sound/dev_table.h
drivers/sound/dmabuf.c
drivers/sound/gus_wave.c
drivers/sound/mad16.c
drivers/sound/midibuf.c
drivers/sound/sb16_dsp.c
drivers/sound/sb_dsp.c
drivers/sound/sequencer.c
drivers/sound/sound_config.h
drivers/sound/sound_switch.c
drivers/sound/soundcard.c
drivers/sound/soundvers.h
drivers/sound/sscape.c
fs/binfmt_script.c
fs/dcache.c
fs/isofs/inode.c
fs/ncpfs/ioctl.c
fs/ncpfs/ncplib_kernel.c
fs/nfs/inode.c
fs/super.c
fs/umsdos/ioctl.c
include/asm-alpha/apecs.h
include/asm-alpha/atomic.h
include/asm-alpha/ioctl.h
include/asm-alpha/ioctls.h [new file with mode: 0644]
include/asm-alpha/param.h
include/asm-alpha/posix_types.h [new file with mode: 0644]
include/asm-alpha/socket.h
include/asm-alpha/sockios.h [new file with mode: 0644]
include/asm-alpha/statfs.h
include/asm-alpha/termbits.h [new file with mode: 0644]
include/asm-alpha/termios.h
include/asm-alpha/types.h
include/asm-i386/ioctls.h [new file with mode: 0644]
include/asm-i386/posix_types.h [new file with mode: 0644]
include/asm-i386/smp.h
include/asm-i386/socket.h
include/asm-i386/sockios.h [new file with mode: 0644]
include/asm-i386/string.h
include/asm-i386/termbits.h [new file with mode: 0644]
include/asm-i386/termios.h
include/asm-i386/types.h
include/asm-i386/unistd.h
include/linux/atalk.h
include/linux/binfmts.h
include/linux/blk.h
include/linux/blkdev.h
include/linux/fs.h
include/linux/if_arp.h
include/linux/if_ether.h
include/linux/if_frad.h [new file with mode: 0644]
include/linux/if_tr.h
include/linux/kd.h
include/linux/kerneld.h
include/linux/loop.h
include/linux/mcdx.h
include/linux/ncp_fs.h
include/linux/net.h
include/linux/netdevice.h
include/linux/optcd.h
include/linux/pci.h
include/linux/posix_types.h [new file with mode: 0644]
include/linux/sched.h
include/linux/sdla.h [new file with mode: 0644]
include/linux/smp.h
include/linux/socket.h
include/linux/sockios.h
include/linux/tty.h
include/linux/types.h
include/linux/vt.h
include/net/af_unix.h
include/net/gc.h [new file with mode: 0644]
include/net/ipx.h
include/net/p8022.h
include/net/psnap.h
include/net/sock.h
init/main.c
kernel/exit.c
kernel/fork.c
kernel/ksyms.c
kernel/module.c
kernel/sched.c
kernel/sys.c
mm/Makefile
mm/memory.c
mm/mmap.c
mm/mremap.c [new file with mode: 0644]
net/802/Makefile
net/802/p8022.c
net/802/p8023.c
net/802/psnap.c
net/Config.in
net/Makefile
net/appletalk/Makefile
net/appletalk/aarp.c
net/appletalk/ddp.c
net/ax25/af_ax25.c
net/core/dev.c
net/ethernet/pe2.c
net/ipv4/Config.in
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/ip_alias.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ip_input.c
net/ipv4/proc.c
net/ipx/Makefile
net/ipx/af_ipx.c
net/netrom/af_netrom.c
net/netrom/nr_dev.c
net/netsyms.c [new file with mode: 0644]
net/protocols.c
net/socket.c
net/unix/af_unix.c
net/unix/garbage.c
scripts/Configure
scripts/Menuconfig
scripts/README.Menuconfig
scripts/lxdialog/inputbox.c
scripts/lxdialog/menubox.c

diff --git a/CREDITS b/CREDITS
index 8a9c36f2f9949adaaf92c38201b5cf4e0d0681af..72202f8afff45c7847007a77d54e2a8b013142c6 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -298,6 +298,7 @@ S: USA
 
 N: Bjorn Ekwall
 E: bj0rn@blox.se
+W: http://www.pi.se/blox/
 D: Extended support for loadable modules
 D: D-Link pocket adapter drivers
 S: Myrstuguv. 83
@@ -736,6 +737,15 @@ D: XF86_Mach8
 D: XF86_8514
 D: cfdisk (curses based disk partitioning program)
 
+N: Mike McLagan
+E: mike.mclagan@linux.org
+W: http://www.invlogic.com/~mmclagan
+S: Innovative Logic Corp
+S: P.O. Box 1068
+S: Laurel, MD  20732
+S: USA
+D: DLCI/FRAD drivers for Sangoma SDLAs
+
 N: Bradley McLean
 E: brad@bradpc.gaylord.com
 D: Device driver hacker
index ef32aa1cf93917f1c4d68b541dca315a939f9751..8bbde9342fead0c1b8fc7bb0ff44b8b300284b2f 100644 (file)
@@ -654,6 +654,26 @@ CONFIG_KERNELD
   later on, such as a user level "beeper" and a generic screen blanker.
   The "kerneld" daemon is included in "modules-1.2.8" and later.
 
+ARP daemon support
+CONFIG_ARPD
+  Normally, the kernel maintains an internal cache which maps IP 
+  addresses to hardware addresses on the local network, so that
+  Ethernet/Token Ring/ etc. frames are sent to the proper address
+  on the physical networking layer.  For small networks having
+  a few hundred directly connected hosts or less, keeping  this
+  address resolution cache (ARP) inside the kernel works well.
+  However, maintaining an internal ARP cache does not work well for
+  very large switched networks, and will use a lot of kernel memory
+  if TCP/IP connections are made to many machines on the network.
+  By enabling this option, the kernel's internal ARP cache will
+  never grow to more than 256 entries (the oldest entries are 
+  expired in a LIFO manner) and communication will be attempted
+  with an external ARP daemon, arpd, via the kerneld message
+  queue.  This code is still experimental.  If you do enable
+  arpd support, you should obtain a copy of arpd from
+  http://www.loran.com/~layes/arpd/index.html.  If unsure,
+  say N.  
+
 TCP/IP networking
 CONFIG_INET
   These are the protocols used on the Internet and on most local
index 2d66a7301bfc8d15efe622febc4efdddba1b3176..23fcae349e358ac2d41674326fbc01618ba85127 100644 (file)
@@ -7,7 +7,7 @@ works with this driver, and that doesn't report itself as DOLPHIN,
 please drop me a mail.
 
 The support for multisession CDs is in ALPHA stage. If you use it,
-please mail me your experiences. Multisession support can be disables
+please mail me your experiences. Multisession support can be disabled
 at compile time.
 
 You can find some older versions of the driver at
index 88bad215fec236966035bf4dfe8583a279b38454..073bd83943fa259241ca3a796791cd903ef86b1a 100644 (file)
@@ -416,7 +416,7 @@ physical disks.
 \noindent
 The loopback devices are used to mount filesystems not associated with
 block devices.  The binding to the loopback devices is usually handled
-by mount(1).
+by mount(8).
 
 \begin{devicelist}
 \major{11}{}{char }{Raw keyboard device}
index c2ffd63ad7b7ff8f2181eb9def7a45161c914312..4e1b0ac381733907ae52af78c9a1567948146ab9 100644 (file)
@@ -194,7 +194,7 @@ an unreasonable effort.
 
                The loopback devices are used to mount filesystems not
                associated with block devices.  The binding to the
-               loopback devices is usually handled by mount(1).
+               loopback devices is usually handled by mount(8).
 
   8 block      SCSI disk devices
                  0 = /dev/sda          First SCSI disk whole disk
diff --git a/Documentation/framerelay.txt b/Documentation/framerelay.txt
new file mode 100644 (file)
index 0000000..a623957
--- /dev/null
@@ -0,0 +1,33 @@
+Frame Relay (FR) support for linux is built into a two tiered system of device 
+drivers.  The upper layer implements RFC1490 FR specification, and uses the
+Data Link Connection Identifier (DLCI) as it's hardware address.  Usually these
+are assigned by your network supplier, they give you the number/numbers of
+the Virtual Connections (VC) assigned to you.
+
+Each DLCI is a point-to-point link between your machine and a remote one.
+As such, a seperate device is needed to accomodate the routing.  Within the
+net-tools archives is 'dlcicfg'.  This program will communicate with the
+base "DLCI" device, and create new net devices named 'dlci00', 'dlci01'... 
+The configuration script will ask you how many DLCI's you need, as well as
+how many DLCI's you want to assign to each Frame Relay Access Device (FRAD).
+
+The DLCI uses a number of function calls to communicate with the FRAD, all
+of which are stored in the FRAD's private data area.  assoc/deassoc, 
+activate/deactivate and dlci_config.  The DLCI supplies a receive function
+to the FRAD to accept incoming packets.
+
+With this initial offering, only 1 FRAD driver is available.  With many thanks
+to Sangoma Technologies, David Mandelstam & Gene Kozin, the S502A, S502E & 
+S508 are supported.  This driver is currently set up for only FR, but as 
+Sangoma makes more firmware modules available, it can be updated to provide
+them as well.
+
+Configuration of the FRAD makes use of another net-tools program, 'fradcfg'.
+This program makes use of a configuration file (which dlcicfg can also read)
+to specify the types of boards to be configured as FRADs, as well as perform
+any board specific configuration.  The Sangoma module of fradcfg loads the
+FR firmware into the card, sets the irq/port/memory information, and provides
+an initial configuration.
+
+Additional FRAD device drivers can be added as hardware is available.
+
diff --git a/MAGIC b/MAGIC
index 157941bcf5a7219755aeca3e78fc03fa4422e30b..ff1bde3af0eb74b82b02f653ef61aa98bb41b7c1 100644 (file)
--- a/MAGIC
+++ b/MAGIC
@@ -94,6 +94,7 @@ Ioctl Include File            Comments
 'f'    linux/ext2_fs.h
 'm'    linux/mtio.h            conflict!
 'm'    linux/soundcard.h       conflict!
+'n'    linux/ncp_fs.h
 's'    linux/cdk.h
 't'    linux/if_ppp.h
 'u'    linux/smb_fs.h
index 048ed2fd47d8dc20ee978aa949aecc2153862712..ae96e6262862ece7fae80a6c9de886682f7722c2 100644 (file)
@@ -48,6 +48,7 @@ Maintainers List (try to look for most precise areas first)
 P: Person
 M: Mail patches to
 L: Mailing list that is relevant to this area
+W: Web-page with status/info
 S: Status
        Supported:      Someone is actually paid to look after this (wildly
                        improbable).
@@ -89,6 +90,12 @@ M:   Leonard N. Zubkoff <lnz@dandelion.com>
 L:     None
 S:     Maintained
 
+FRAME RELAY DLCI/FRAD (Sangoma drivers too)
+P:     Mike McLagan
+M:     mike.mclagan@linux.org
+L:     linux-net@vger.rutgers.edu
+S:     Maintained
+
 FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
 P:      Rik Faith
 M:      faith@cs.unc.edu
@@ -122,9 +129,16 @@ S: Maintained
 MODULE SUPPORT [GENERAL], KERNELD
 P:     Bjorn Ekwall
 M:     bj0rn@blox.se
+W:     http://www.pi.se/blox/modules/
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
+ARPD SUPPORT
+P:     Jonathan Layes
+M:     layes@loran.com
+L:     linux-net@vger.rutgers.edu
+S:     Maintained
+
 NCP FILESYSTEM:
 P:     Volker Lendecke
 M:     lendecke@namu01.gwdg.de
index d003e690d281c8c7e1fd42ae27cea899cd5264d8..d6dd788d15b65b580a57c481b841371074bbd0e0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 77
+SUBLEVEL = 78
 
 ARCH = i386
 
index bcf455feb8029d9e3d7916839ed7d2bb068fb73c..5f6be1c58510aca9d6a919161c47fc8bb3fe2d61 100644 (file)
@@ -55,6 +55,9 @@ then
        define_bool CONFIG_PCI y
        define_bool CONFIG_ALPHA_EV5 y
        define_bool CONFIG_ALPHA_ALCOR y
+else
+       # EV5 and newer supports all rounding modes in hw:
+       define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
 fi
 
 if [ "$CONFIG_ALPHA_JENSEN" = "y" ]
@@ -62,8 +65,6 @@ then
        bool 'Using SRM as bootloader' CONFIG_ALPHA_SRM
 fi
 
-define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
-
 bool 'Echo console messages on /dev/ttyS1' CONFIG_SERIAL_ECHO
 if [ "$CONFIG_PCI" = "y" ]; then
   bool 'TGA Console Support' CONFIG_TGA_CONSOLE
index 06290a597399d40078a620cc7ab138347c56dc6d..eb8348157226d55f05b42cf184615749a5b835f4 100644 (file)
@@ -24,7 +24,6 @@ CONFIG_ALPHA_EB164=y
 CONFIG_PCI=y
 CONFIG_ALPHA_EV5=y
 CONFIG_ALPHA_ALCOR=y
-CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y
 # CONFIG_SERIAL_ECHO is not set
 # CONFIG_TGA_CONSOLE is not set
 CONFIG_PCI_OPTIMIZE=y
@@ -134,6 +133,7 @@ CONFIG_DUMMY=m
 # CONFIG_SCC is not set
 # CONFIG_PLIP is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_FRAD is not set
 # CONFIG_NET_ALPHA is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_LANCE is not set
index 7352a6cd347fe8a36208330ab28caf10a0d8fc90..87b51e81f4c09920149cf1eb53b284e216891ffb 100644 (file)
 
 #include <asm/segment.h>
 #include <asm/io.h>
+#include <asm/hwrpb.h>
 
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
 
 #define TIMER_IRQ 0
 
+extern struct hwrpb_struct *hwrpb;
+
 static int set_rtc_mmss(unsigned long);
 
+
+/*
+ * Shift amount by which scaled_ticks_per_cycle is scaled.  Shifting
+ * by 48 gives us 16 bits for HZ while keeping the accuracy good even
+ * for large CPU clock rates.
+ */
+#define FIX_SHIFT      48
+
+/* lump static variables together for more efficient access: */
+static struct {
+       __u32           last_time;              /* cycle counter last time it got invoked */
+       __u32           max_cycles_per_tick;    /* more makes us think we lost an interrupt */
+       unsigned long   scaled_ticks_per_cycle; /* ticks/cycle * 2^48 */
+       long            last_rtc_update;        /* last time the cmos clock got updated */
+} state;
+
+
+static inline __u32 rpcc(void)
+{
+    __u32 result;
+
+    asm volatile ("rpcc %0" : "r="(result));
+    return result;
+}
+
+
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
 void timer_interrupt(struct pt_regs * regs)
 {
-       /* last time the cmos clock got updated */
-       static long last_rtc_update=0;
+       __u32 delta, now;
+
+       now = rpcc();
+       delta = now - state.last_time;
+       state.last_time = now;
+       if (delta > state.max_cycles_per_tick) {
+               int i, missed_ticks;
 
+               missed_ticks = ((delta * state.scaled_ticks_per_cycle) >> FIX_SHIFT) - 1;
+               for (i = 0; i < missed_ticks; ++i) {
+                       do_timer(regs);
+               }
+       }
        do_timer(regs);
 
        /*
@@ -44,13 +83,13 @@ void timer_interrupt(struct pt_regs * regs)
         * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
         * called as close as possible to 500 ms before the new second starts.
         */
-       if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
+       if (time_state != TIME_BAD && xtime.tv_sec > state.last_rtc_update + 660 &&
            xtime.tv_usec > 500000 - (tick >> 1) &&
            xtime.tv_usec < 500000 + (tick >> 1))
          if (set_rtc_mmss(xtime.tv_sec) == 0)
-           last_rtc_update = xtime.tv_sec;
+           state.last_rtc_update = xtime.tv_sec;
          else
-           last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+           state.last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
 }
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
@@ -130,6 +169,15 @@ void time_init(void)
                year += 100;
        xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
        xtime.tv_usec = 0;
+
+       if (HZ > (1<<16)) {
+               extern void __you_loose (void);
+               __you_loose();
+       }
+       state.last_time = rpcc();
+       state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq;
+       state.max_cycles_per_tick = (2 * hwrpb->cycle_freq) / HZ;
+       state.last_rtc_update = 0;
 }
 
 /*
index 0c0a5ac08b0382bdf0ca02213d72d84307c9c487..c7125f5c5e20c252996f21382a3f8263c10a2a4d 100644 (file)
@@ -175,7 +175,7 @@ alpha_fp_emul (unsigned long pc)
 
        insn = get_user((__u32*)pc);
        fc     = (insn >>  0) &  0x1f;  /* destination register */
-       func   = (insn >>  5) & 0x3ff;
+       func   = (insn >>  5) & 0x7ff;
        fb     = (insn >> 16) &  0x1f;
        fa     = (insn >> 21) &  0x1f;
        opcode = insn >> 26;
index 4f823f7d00f1e57d6948eed8948f42000bc043e3..51305b5a115e21579667f092a58bc49904b8882f 100644 (file)
@@ -501,7 +501,7 @@ round_s_ieee (int f, EXTENDED *a, unsigned long *b)
 
 
 static unsigned long
-round_t_ieee (EXTENDED *a, unsigned long *b, int f)
+round_t_ieee (int f, EXTENDED *a, unsigned long *b)
 {
        unsigned long diff1, diff2, res;
        EXTENDED z1, z2;
@@ -626,7 +626,7 @@ ieee_CVTST (int f, unsigned long a, unsigned long *b)
                }
                return 0;
        }
-       return round_s_ieee(f, &temp, b);
+       return round_t_ieee(f, &temp, b);
 }
 
 
@@ -717,7 +717,7 @@ ieee_CVTQT (int f, unsigned long a, unsigned long *b)
        }
        op_b.e = 55;
        normalize(&op_b);
-       return round_t_ieee(&op_b, b, f);
+       return round_t_ieee(f, &op_b, b);
 }
 
 
@@ -993,7 +993,7 @@ ieee_ADDT (int f, unsigned long a, unsigned long b, unsigned long *c)
        if (a_type == ZERO && b_type == ZERO)
                op_c.s = op_a.s && op_b.s;
 
-       return round_t_ieee(&op_c, c, f);       
+       return round_t_ieee(f, &op_c, c);
 }
 
 
@@ -1093,7 +1093,7 @@ ieee_SUBT (int f, unsigned long a, unsigned long b, unsigned long *c)
        if (a_type == ZERO && b_type == ZERO)
                op_c.s = op_a.s && op_b.s;
 
-       return round_t_ieee(&op_c, c, f);
+       return round_t_ieee(f, &op_c, c);
 }
 
 
@@ -1206,7 +1206,7 @@ ieee_MULT (int f, unsigned long a, unsigned long b, unsigned long *c)
        normalize(&op_c);
        op_c.e -= 55;   /* drop the 55 original bits. */
 
-       return round_t_ieee(&op_c, c, f);
+       return round_t_ieee(f, &op_c, c);
 }
 
 
@@ -1339,5 +1339,5 @@ ieee_DIVT (int f, unsigned long a, unsigned long b, unsigned long *c)
                op_c.f[0] |= STICKY_T;
        normalize(&op_c);
        op_c.e -= 9;            /* remove excess exp from original shift */
-       return round_t_ieee(&op_c, c, f);
+       return round_t_ieee(f, &op_c, c);
 }
index 4041d4acb2bd6663011a87d412ad9560519704e3..9f3bdd0eb5f707648ae1fbeab067b05e612ef6a2 100644 (file)
@@ -74,8 +74,10 @@ type_of_loader:      .byte   0               ! = 0, old one (LILO, Loadlin,
                                        !      Bootlin, SYSLX, bootsect...)
                                        ! else it is set by the loader:
                                        ! 0xTV: T=0 for LILO
-                                       !       T=1 for Loadlin
-                                       !       T=2 for bootsect-loader
+                                       !       T=1 for Loadlin
+                                       !       T=2 for bootsect-loader
+                                       !       T=3 for SYSLX
+                                       !       T=4 for ETHERBOOT
                                        !       V = version
 loadflags:     .byte   0       ! unused bits =0 (reserved for future development)
 LOADED_HIGH    = 1             ! bit within loadflags,
index c9f2464554ee883933d2625815128bd3f5965536..5775aa4d394b02fed656311d604b842139cf8800 100644 (file)
@@ -47,6 +47,7 @@ CONFIG_BLK_DEV_RZ1000=y
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_MD is not set
+
 #
 # Networking options
 #
@@ -90,6 +91,7 @@ CONFIG_DUMMY=m
 # CONFIG_SCC is not set
 # CONFIG_PLIP is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_FRAD is not set
 # CONFIG_NET_ALPHA is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_LANCE is not set
index dbfc1921d837bf587e02d2b634d50bb396a41b48..df6f7361d9ef49731b852ead2a6c7bd1e2919f1a 100644 (file)
@@ -688,4 +688,5 @@ ENTRY(sys_call_table)
        .long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
        .long SYMBOL_NAME(sys_sched_rr_get_interval)
        .long SYMBOL_NAME(sys_nanosleep)
+       .long SYMBOL_NAME(sys_mremap)
        .space (NR_syscalls-163)*4
index 3b06b61b0f04e1d73ff14bfec0abbc61a3c76724..9e416bf3c057770170cc62f4a4b15864cf97c145 100644 (file)
@@ -51,14 +51,14 @@ extern __inline int max(int a,int b)
 int smp_found_config=0;                                        /* Have we found an SMP box                             */
 
 unsigned long cpu_present_map = 0;                     /* Bitmask of existing CPU's                            */
-int smp_num_cpus;                                      /* Total count of live CPU's                            */
+int smp_num_cpus = 1;                                  /* Total count of live CPU's                            */
 int smp_threads_ready=0;                               /* Set when the idlers are all forked                   */
 volatile int cpu_number_map[NR_CPUS];                  /* which CPU maps to which logical number               */
+volatile int cpu_logical_map[NR_CPUS];                 /* which logical number maps to which CPU               */
 volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; /* We always use 0 the rest is ready for parallel delivery */
 volatile unsigned long smp_invalidate_needed;          /* Used for the invalidate map thats also checked in the spinlock */
 struct cpuinfo_x86 cpu_data[NR_CPUS];                  /* Per cpu bogomips and other parameters                */
 static unsigned int num_processors = 1;                        /* Internal processor count                             */
-int smp_top_cpu = 0;                                   /* Highest used APIC id                                 */
 static unsigned long io_apic_addr = 0xFEC00000;                /* Address of the I/O apic (not yet used)               */
 unsigned char boot_cpu_id = 0;                         /* Processor that is doing the boot up                  */
 static unsigned char *kstack_base,*kstack_end;         /* Kernel stack list pointers                           */
@@ -220,7 +220,6 @@ static int smp_read_mpc(struct mp_config_table *mpc)
                                        {
                                                SMP_PRINTK(("    Bootup CPU\n"));
                                                boot_cpu_id=m->mpc_apicid;
-                                               nlong = boot_cpu_id<<24;        /* Dummy 'self' for bootup */
                                        }
                                        else    /* Boot CPU already counted */
                                                num_processors++;
@@ -294,7 +293,7 @@ static int smp_read_mpc(struct mp_config_table *mpc)
  *     Scan the memory blocks for an SMP configuration block.
  */
  
-void smp_scan_config(unsigned long base, unsigned long length)
+int smp_scan_config(unsigned long base, unsigned long length)
 {
        unsigned long *bp=(unsigned long *)base;
        struct intel_mp_floating *mpf;
@@ -324,55 +323,19 @@ void smp_scan_config(unsigned long base, unsigned long length)
                                 *      Now see if we need to read further.
                                 */
                                if(mpf->mpf_feature1!=0)
-                               {
-                                       num_processors=2;
-                                       printk("I/O APIC at 0xFEC00000.\n");
-                                       printk("Bus#0 is ");
-                               }
-                               switch(mpf->mpf_feature1)
-                               {
-                                       case 1:
-                                       case 5:
-                                               printk("ISA\n");
-                                               break;
-                                       case 2:
-                                               printk("EISA with no IRQ8 chaining\n");
-                                               break;
-                                       case 6:
-                                       case 3:
-                                               printk("EISA\n");
-                                               break;
-                                       case 4:
-                                       case 7:
-                                               printk("MCA\n");
-                                               break;
-                                       case 0:
-                                               break;
-                                       default:
-                                               printk("???\nUnknown standard configuration %d\n",
-                                                       mpf->mpf_feature1);
-                                               return;
-                               }
-                               if(mpf->mpf_feature1>4)
-                                       printk("Bus #1 is PCI\n");
-                               /*
-                                *      Read the physical hardware table.
-                                */
-                               if(mpf->mpf_physptr)
-                                       smp_read_mpc((void *)mpf->mpf_physptr);
-                               else
                                {
                                        unsigned long cfg;
 
                                        /*
-                                        *      If no table present, determine
-                                        *      what the CPU mapping is.
+                                        *      We need to know what the local
+                                        *      APIC id of the boot CPU is!
                                         */
 
 /*
  *
  *     HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
  *
+ *     It's not just a crazy hack...  ;-)
  */
                                        /*
                                         *      Standard page mapping
@@ -386,7 +349,6 @@ void smp_scan_config(unsigned long base, unsigned long length)
                                        local_invalidate();
 
                                        boot_cpu_id = GET_APIC_ID(*((volatile unsigned long *) APIC_ID));
-                                       nlong = boot_cpu_id<<24;        /* Dummy 'self' for bootup */
 
                                        /*
                                         *      Give it back
@@ -400,26 +362,79 @@ void smp_scan_config(unsigned long base, unsigned long length)
  *     END OF HACK   END OF HACK   END OF HACK   END OF HACK   END OF HACK
  *
  */                                    
+                                       /*
+                                        *      2 CPUs, numbered 0 & 1.
+                                        */
+                                       cpu_present_map=3;
+                                       num_processors=2;
+                                       printk("I/O APIC at 0xFEC00000.\n");
+                                       printk("Bus#0 is ");
+                               }
+                               switch(mpf->mpf_feature1)
+                               {
+                                       case 1:
+                                       case 5:
+                                               printk("ISA\n");
+                                               break;
+                                       case 2:
+                                               printk("EISA with no IRQ8 chaining\n");
+                                               break;
+                                       case 6:
+                                       case 3:
+                                               printk("EISA\n");
+                                               break;
+                                       case 4:
+                                       case 7:
+                                               printk("MCA\n");
+                                               break;
+                                       case 0:
+                                               break;
+                                       default:
+                                               printk("???\nUnknown standard configuration %d\n",
+                                                       mpf->mpf_feature1);
+                                               return 1;
+                               }
+                               if(mpf->mpf_feature1>4)
+                               {
+                                       printk("Bus #1 is PCI\n");
 
                                        /*
-                                        *      If boot CPU != 0, other CPU
-                                        *      is 0, else other CPU is 1.
+                                        *      Set local APIC version to
+                                        *      the integrated form.
+                                        *      It's initialized to zero
+                                        *      otherwise, representing
+                                        *      a discrete 82489DX.
                                         */
-                                       if (boot_cpu_id)
-                                               cpu_present_map=1 | (1 << boot_cpu_id);
-                                       else
-                                               cpu_present_map=3;
+                                       apic_version[0] = 0x10;
+                                       apic_version[1] = 0x10;
                                }
+                               /*
+                                *      Read the physical hardware table.
+                                *      Anything here will override the
+                                *      defaults.
+                                */
+                               if(mpf->mpf_physptr)
+                                       smp_read_mpc((void *)mpf->mpf_physptr);
+
+                               /*
+                                *      Now that the boot CPU id is known,
+                                *      set some other information about it.
+                                */
+                               nlong = boot_cpu_id<<24;        /* Dummy 'self' for bootup */
+                               cpu_logical_map[0] = boot_cpu_id;
+
                                printk("Processors: %d\n", num_processors);
                                /*
-                                *      Only use the first one found.
+                                *      Only use the first configuration found.
                                 */
-                               return;
+                               return 1;
                        }
                }
                bp+=4;
                length-=16;
        }
+
+       return 0;
 }
 
 /*
@@ -565,7 +580,7 @@ void smp_callin(void)
  
 void smp_boot_cpus(void)
 {
-       int i,j;
+       int i;
        int cpucount=0;
        unsigned long cfg;
        void *stack;
@@ -667,15 +682,12 @@ void smp_boot_cpus(void)
                 *      Don't even attempt to start the boot CPU!
                 */
                if (i == boot_cpu_id)
-               {
-                       smp_top_cpu=max(smp_top_cpu,i);
                        continue;
-               }
                
                if (cpu_present_map & (1 << i))
                {
                        unsigned long send_status, accept_status;
-                       int timeout, num_starts;
+                       int timeout, num_starts, j;
                        
                        /*
                         *      We need a kernel stack for each processor.
@@ -719,8 +731,11 @@ void smp_boot_cpus(void)
                         *      Be paranoid about clearing APIC errors.
                         */
 
-                       apic_write(APIC_ESR, 0);
-                       accept_status = (apic_read(APIC_ESR) & 0xEF);
+                       if ( apic_version[i] & 0xF0 )
+                       {
+                               apic_write(APIC_ESR, 0);
+                               accept_status = (apic_read(APIC_ESR) & 0xEF);
+                       }
                        
                        /*
                         *      Status is now clean
@@ -777,8 +792,8 @@ void smp_boot_cpus(void)
                         *      Run STARTUP IPI loop.
                         */
 
-                       for (j = 0; !(send_status || accept_status)
-                                   && (j < num_starts) ; j++)
+                       for (j = 1; !(send_status || accept_status)
+                                   && (j <= num_starts) ; j++)
                        {
                                SMP_PRINTK(("Sending STARTUP #%d.\n",j));
 
@@ -826,8 +841,7 @@ void smp_boot_cpus(void)
                                        cpucount++;
                                        /* number CPUs logically, starting from 1 (BSP is 0) */
                                        cpu_number_map[i] = cpucount;
-                                       smp_top_cpu=max(smp_top_cpu,i);
-                                       
+                                       cpu_logical_map[cpucount] = i;
                                }
                                else
                                {
@@ -951,10 +965,12 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
        /*
         *      Sanity check we don't re-enter this across CPU's. Only the kernel
         *      lock holder may send messages. For a STOP_CPU we are bringing the
-        *      entire box to the fastest halt we can.. 
+        *      entire box to the fastest halt we can.. A reschedule carries
+        *      no data and can occur during an invalidate.. guess what panic
+        *      I got to notice this bug...
         */
         
-       if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU)
+       if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU && msg!=MSG_RESCHEDULE)
        {
                panic("CPU #%d: Message pass %d but pass in progress by %d of %d\n",
                        smp_processor_id(),msg,message_cpu, smp_msg_id);
index 7ce2c3ce5aae3194f0dc47fdc58fe14a4a8e702d..0b598463c7e82498de3a4a99aaa6d33ded4f38be 100644 (file)
@@ -128,13 +128,15 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
        memset((void *) 0, 0, PAGE_SIZE);
 #endif
 #ifdef __SMP__
-       smp_scan_config(0x0,0x400);     /* Scan the bottom 1K for a signature */
-       /*
-        *      FIXME: Linux assumes you have 640K of base ram.. this continues
-        *      the error...
-        */
-       smp_scan_config(639*0x400,0x400);       /* Scan the top 1K of base RAM */
-       smp_scan_config(0xF0000,0x10000);       /* Scan the 64K of bios */
+       if (!smp_scan_config(0x0,0x400))        /* Scan the bottom 1K for a signature */
+       {
+               /*
+                *      FIXME: Linux assumes you have 640K of base ram.. this continues
+                *      the error...
+                */
+               if (!smp_scan_config(639*0x400,0x400))  /* Scan the top 1K of base RAM */
+                       smp_scan_config(0xF0000,0x10000);       /* Scan the 64K of bios */
+       }
        /*
         *      If it is an SMP machine we should know now, unless the configuration
         *      is in an EISA/MCA bus machine with an extended bios data area. I don't
index 1468b011fd6f1a267535d64d478266cb01708bc0..4f1c9d2e3d0bdcc4c232f31a72c4d7154a26037f 100644 (file)
@@ -2597,7 +2597,7 @@ static void redo_fd_request(void)
        }
 
        while(1){
-               if (!CURRENT) {
+               if (!CURRENT || CURRENT_PLUGGED) {
                        CLEAR_INTR;
                        unlock_fdc();
                        return;
index ab406fcbd78334b64d6cd3cfae2f478b8ed37792..a714dda023ef79e4fb967b73cb99b06fd0dd4747 100644 (file)
@@ -1469,6 +1469,8 @@ void ide_do_request (ide_hwgroup_t *hwgroup)
                         */
                        hwif = hwgroup->next_hwif;
                        do {
+                               if (IS_PLUGGED(blk_dev + hwif->major))
+                                       continue;
                                rq = blk_dev[hwif->major].current_request;
                                if (rq != NULL && rq->rq_status != RQ_INACTIVE)
                                        goto got_rq;
index 946b59ec9c3e187ba3f7448b211bf327fc20399f..3c066a8a0ddcd62ee0a2da3fd15543e5893b90a7 100644 (file)
@@ -76,40 +76,30 @@ int * blksize_size[MAX_BLKDEV] = { NULL, NULL, };
 int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, };
 
 /*
- * "plug" the device if there are no outstanding requests: this will
- * force the transfer to start only after we have put all the requests
- * on the list.
+ * remove the plug and let it rip..
  */
-static inline void plug_device(struct blk_dev_struct * dev, struct request * plug)
+static void unplug_device(void * data)
 {
+       struct blk_dev_struct * dev = (struct blk_dev_struct *) data;
        unsigned long flags;
 
-       plug->rq_status = RQ_INACTIVE;
-       plug->cmd = -1;
-       plug->next = NULL;
        save_flags(flags);
        cli();
-       if (!dev->current_request)
-               dev->current_request = plug;
+       if (dev->current_request)
+               (dev->request_fn)();
        restore_flags(flags);
 }
 
 /*
- * remove the plug and let it rip..
+ * "plug" the device if there are no outstanding requests: this will
+ * force the transfer to start only after we have put all the requests
+ * on the list.
  */
-static inline void unplug_device(struct blk_dev_struct * dev)
+static inline void plug_device(struct blk_dev_struct * dev)
 {
-       struct request * req;
-       unsigned long flags;
-
-       save_flags(flags);
-       cli();
-       req = dev->current_request;
-       if (req && req->rq_status == RQ_INACTIVE && req->cmd == -1) {
-               dev->current_request = req->next;
-               (dev->request_fn)();
+       if (!dev->current_request && !IS_PLUGGED(dev)) {
+               queue_task_irq_off(&dev->plug_tq, &tq_scheduler);
        }
-       restore_flags(flags);
 }
 
 /*
@@ -154,7 +144,6 @@ static struct request * __get_request_wait(int n, kdev_t dev)
 
        add_wait_queue(&wait_for_request, &wait);
        for (;;) {
-               unplug_device(MAJOR(dev)+blk_dev);
                current->state = TASK_UNINTERRUPTIBLE;
                cli();
                req = get_request(n, dev);
@@ -261,7 +250,8 @@ void add_request(struct blk_dev_struct * dev, struct request * req)
        if (!(tmp = dev->current_request)) {
                dev->current_request = req;
                up (&request_lock);
-               (dev->request_fn)();
+               if (!IS_PLUGGED(dev))
+                       (dev->request_fn)();
                sti();
                return;
        }
@@ -276,7 +266,7 @@ void add_request(struct blk_dev_struct * dev, struct request * req)
 
        up (&request_lock);
 /* for SCSI devices, call request_fn unconditionally */
-       if (scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR)
+       if (!IS_PLUGGED(dev) && scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR)
                (dev->request_fn)();
 
        sti();
@@ -340,8 +330,8 @@ static void make_request(int major,int rw, struct buffer_head * bh)
        }
 
 /* look for a free request. */
-       cli();
        down (&request_lock);
+       cli();
 
 /* The scsi disk and cdrom drivers completely remove the request
  * from the queue when they start processing an entry.  For this reason
@@ -479,7 +469,6 @@ void ll_rw_page(int rw, kdev_t dev, unsigned long page, char * buffer)
 void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
 {
        unsigned int major;
-       struct request plug;
        int correct_size;
        struct blk_dev_struct * dev;
        int i;
@@ -531,8 +520,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
           from starting until we have shoved all of the blocks into the
           queue, and then we let it rip.  */
 
-       if (nr > 1)
-               plug_device(dev, &plug);
+       plug_device(dev);
        for (i = 0; i < nr; i++) {
                if (bh[i]) {
                        set_bit(BH_Req, &bh[i]->b_state);
@@ -543,7 +531,6 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
                        make_request(major, rw, bh[i]);
                }
        }
-       unplug_device(dev);
        return;
 
       sorry:
@@ -622,6 +609,8 @@ int blk_dev_init(void)
        for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) {
                dev->request_fn      = NULL;
                dev->current_request = NULL;
+               dev->plug_tq.routine = &unplug_device;
+               dev->plug_tq.data    = dev;
        }
 
        req = all_requests + NR_REQUEST;
index c96be91cbbe3d049ffe886b82e556b8031a49d2c..1f32436a3f7b60ccac4a6e858a2e5120b1c73a5d 100644 (file)
@@ -181,7 +181,10 @@ repeat:
                offset -= blksize;
        }
        len = CURRENT->current_nr_sectors << 9;
-       if ((CURRENT->cmd != WRITE) && (CURRENT->cmd != READ)) {
+       if (CURRENT->cmd == WRITE) {
+               if (lo->lo_flags & LO_FLAGS_READ_ONLY)
+                       goto error_out;
+       } else if (CURRENT->cmd != READ) {
                printk("unknown loop device command (%d)?!?", CURRENT->cmd);
                goto error_out;
        }
@@ -235,11 +238,11 @@ error_out:
        goto repeat;
 }
 
-static int loop_set_fd(struct loop_device *lo, unsigned int arg)
+static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
 {
        struct file     *file;
        struct inode    *inode;
-       
+
        if (arg >= NR_OPEN || !(file = current->files->fd[arg]))
                return -EBADF;
        if (lo->lo_inode)
@@ -261,7 +264,14 @@ static int loop_set_fd(struct loop_device *lo, unsigned int arg)
        } else
                return -EINVAL;
 
-       invalidate_inode_pages (inode);
+       if (IS_RDONLY (inode) || is_read_only(lo->lo_device)) {
+               lo->lo_flags |= LO_FLAGS_READ_ONLY;
+               set_device_ro(dev, 1);
+       } else {
+               invalidate_inode_pages (inode);
+               set_device_ro(dev, 0);
+       }
+
        lo->lo_inode = inode;
        lo->lo_inode->i_count++;
        lo->transfer = NULL;
@@ -274,7 +284,7 @@ static int loop_clr_fd(struct loop_device *lo, kdev_t dev)
 {
        if (!lo->lo_inode)
                return -ENXIO;
-       if (lo->lo_refcnt > 1)
+       if (lo->lo_refcnt > 1)  /* we needed one fd for the ioctl */
                return -EBUSY;
        if (S_ISBLK(lo->lo_inode->i_mode))
                blkdev_release (lo->lo_inode);
@@ -378,7 +388,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
        lo = &loop_dev[dev];
        switch (cmd) {
        case LOOP_SET_FD:
-               return loop_set_fd(lo, arg);
+               return loop_set_fd(lo, inode->i_rdev, arg);
        case LOOP_CLR_FD:
                return loop_clr_fd(lo, inode->i_rdev);
        case LOOP_SET_STATUS:
@@ -442,8 +452,6 @@ static void lo_release(struct inode *inode, struct file *file)
                lo->lo_refcnt--;
                MOD_DEC_USE_COUNT;
        }
-
-       return;
 }
 
 static struct file_operations lo_fops = {
index 78931f15b2b812ffba15342a505a7380ba541b0e..0476402f1b82ed7f8195ccfa97f11c996176dd33 100644 (file)
@@ -7,6 +7,8 @@
 
    A lot of inspiration came from hd.c ...
 
+   kerneld support by Boris Tobotras <boris@xtalk.msk.su>
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
@@ -29,6 +31,9 @@
 #include <linux/proc_fs.h>
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
 #include <errno.h>
 
 #define MAJOR_NR MD_MAJOR
@@ -92,14 +97,14 @@ static struct gendisk *find_gendisk (kdev_t dev)
 /* Picked up from genhd.c */
 char *partition_name (kdev_t dev)
 {
-  static char name[10];                /* This should be long
+  static char name[40];                /* This should be long
                                   enough for a device name ! */
-  struct gendisk *hd=find_gendisk (dev);
+  struct gendisk *hd = find_gendisk (dev);
 
   if (!hd)
   {
-    printk ("No gendisk entry for dev %04x\n", dev);
-    sprintf (name, "dev %04x", dev);
+    printk ("No gendisk entry for dev %s\n", kdevname(dev));
+    sprintf (name, "dev %s", kdevname(dev));
     return (name);
   }
 
@@ -197,10 +202,20 @@ static int md_ioctl (struct inode *inode, struct file *file,
     md_dev[minor].repartition=(int) arg;
     
     if ((index=PERSONALITY(md_dev+minor) >> (PERSONALITY_SHIFT))
-       >= MAX_PERSONALITY ||
-       !pers[index])
+       >= MAX_PERSONALITY)
       return -EINVAL;
 
+    if (!pers[index])
+    {
+#ifdef CONFIG_KERNELD
+      char module_name[80];
+      sprintf (module_name, "md-personality-%d", index);
+      request_module (module_name);
+      if (!pers[index])
+#endif
+       return -EINVAL;
+    }
+
     md_dev[minor].pers=pers[index];
 
     if ((err=md_dev[minor].pers->run (minor, md_dev+minor)))
@@ -404,7 +419,7 @@ static void do_md_request (void)
     minor = MINOR(req->rq_dev);
     if ((MAJOR(req->rq_dev) != MD_MAJOR) || (minor >= MAX_REAL))
     {
-      printk("md: bad device number: 0x%04x\n", req->rq_dev);
+      printk("md: bad device: %s\n", kdevname(req->rq_dev));
       end_request(0, req);
       continue;
     }
@@ -437,16 +452,17 @@ void make_md_request (struct request *pending, int n)
   kdev_t dev;
   struct buffer_head *bh;
   struct request *req;
+  long flags;
   
   down (&request_lock);
+  save_flags (flags);
+  cli();
 
   for (i=0; i<n; i++)
   {
     if (!pending[i].bh)
       continue;
 
-    cli();
-
     found=0;
     rw=pending[i].cmd;
     bh=pending[i].bh;
@@ -470,7 +486,7 @@ void make_md_request (struct request *pending, int n)
 
       while (req && !found)
       {
-       if (req->rq_status!=RQ_INACTIVE && req->rq_status!=RQ_ACTIVE)
+       if (req->rq_status!=RQ_ACTIVE)
          printk ("Saw bad status request !\n");
 
        if (req->rq_dev == dev &&
@@ -494,7 +510,7 @@ void make_md_request (struct request *pending, int n)
            (req->nr_sectors + pending[i].nr_sectors) < 245)
        {
          req->nr_sectors += pending[i].nr_sectors;
-         bh->b_reqnext = req->bh;
+         pending[i].bhtail->b_reqnext = req->bh;
          req->buffer = bh->b_data;
          req->current_nr_sectors = bh->b_size >> 9;
          req->sector = pending[i].sector;
@@ -511,6 +527,7 @@ void make_md_request (struct request *pending, int n)
       continue;
 
     up (&request_lock);
+    sti ();
     req=get_md_request (max_req, dev);
     
     /* Build it up... */
@@ -530,9 +547,11 @@ void make_md_request (struct request *pending, int n)
 
     add_request (blk_dev + MAJOR(dev), req);
     down (&request_lock);
+    cli ();
   }
 
   up (&request_lock);
+  restore_flags (flags);
   for (j=0; j<n; j++)
   {
     if (!pending[j].bh)
@@ -540,8 +559,6 @@ void make_md_request (struct request *pending, int n)
     
     pending[j].bh=NULL;
   }
-
-  sti ();
 }
 
 
@@ -656,7 +673,7 @@ int get_md_status (char *page)
     sz+=sprintf (page+sz, "\n");
     sz+=md_dev[i].pers->status (page+sz, i, md_dev+i);
   }
-  
+
   return (sz);
 }
 
index b20f1dda9484a4fd1385664c6153565e7b36a0b6..ad5d3ce546ed7ecb4a03d9da9a5bca620ab1f866 100644 (file)
@@ -1525,7 +1525,7 @@ cdu31a_request_startover:
        * The beginning here is stolen from the hard disk driver.  I hope
        * it's right.
        */
-      if (!(CURRENT) || CURRENT->rq_status == RQ_INACTIVE)
+      if (!(CURRENT) || CURRENT_PLUGGED || CURRENT->rq_status == RQ_INACTIVE)
       {
          goto end_do_cdu31a_request;
       }
index 80f08337af840fb26036f1d4f6d262d03d61002c..790819937b2daf5c43789e9016dc857c98ba0b6a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * The Mitsumi CDROM interface
  * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.8
+ * VERSION: 1.9
  *
  ****************** H E L P *********************************
  * If you ever plan to update your CD ROM drive and perhaps
@@ -44,7 +44,7 @@
 
 #if RCS
 static const char *mcdx_c_version
-               = "$Id: mcdx.c,v 1.39 1996/03/15 00:00:59 heiko Exp $";
+               = "mcdx.c,v 1.2 1996/03/22 01:14:59 heiko Exp";
 #endif
 
 #include <linux/version.h>
@@ -850,7 +850,7 @@ static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
        I wanna make this independend of cpu speed. [1 jiffie is 1/HZ] sec */
 {
     unsigned long tout = jiffies + jifs;
-       if (jifs < 0) printk ("********\n");
+    if (jifs < 0) return;
 
     /* TRACE((INIT, "mcdx_delay %d\n", jifs)); */
 
@@ -1102,12 +1102,12 @@ int mcdx_init(void)
        int drive;
 
 #ifdef MODULE
-       WARN(("Version 1.8 for %s\n", kernel_version));
+       WARN(("Version 1.9 for %s\n", kernel_version));
 #else
-       WARN(("Version 1.8\n"));
+       WARN(("Version 1.9\n"));
 #endif
 
-       WARN(("$Id: mcdx.c,v 1.39 1996/03/15 00:00:59 heiko Exp $\n"));
+       WARN(("mcdx.c,v 1.2 1996/03/22 01:14:59 heiko Exp\n"));
 
        /* zero the pointer array */
        for (drive = 0; drive < MCDX_NDRIVES; drive++)
diff --git a/drivers/cdrom/optcd_isp16.h b/drivers/cdrom/optcd_isp16.h
deleted file mode 100644 (file)
index f6bb76d..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/* linux/drivers/cdrom/optcd_isp16.h - ISP16 CDROM interface configuration
-   $Id: optcd_isp16.h,v 1.3 1996/01/15 18:43:11 root Exp root $
-
-   Extracts from linux/drivers/cdrom/sjcd.c
-   For copyrights see linux/drivers/cdrom/optcd.c
-*/
-
-
-/* Some (Media)Magic */
-/* define types of drive the interface on an ISP16 card may be looking at */
-#define ISP16_DRIVE_X 0x00
-#define ISP16_SONY  0x02
-#define ISP16_PANASONIC0 0x02
-#define ISP16_SANYO0 0x02
-#define ISP16_MITSUMI  0x04
-#define ISP16_PANASONIC1 0x06
-#define ISP16_SANYO1 0x06
-#define ISP16_DRIVE_NOT_USED 0x08  /* not used */
-#define ISP16_DRIVE_SET_MASK 0xF1  /* don't change 0-bit or 4-7-bits*/
-/* ...for port */
-#define ISP16_DRIVE_SET_PORT 0xF8D
-/* set io parameters */
-#define ISP16_BASE_340  0x00
-#define ISP16_BASE_330  0x40
-#define ISP16_BASE_360  0x80
-#define ISP16_BASE_320  0xC0
-#define ISP16_IRQ_X  0x00
-#define ISP16_IRQ_5  0x04  /* shouldn't be used due to soundcard conflicts */
-#define ISP16_IRQ_7  0x08  /* shouldn't be used due to soundcard conflicts */
-#define ISP16_IRQ_3  0x0C
-#define ISP16_IRQ_9  0x10
-#define ISP16_IRQ_10  0x14
-#define ISP16_IRQ_11  0x18
-#define ISP16_DMA_X  0x03
-#define ISP16_DMA_3  0x00
-#define ISP16_DMA_5  0x00
-#define ISP16_DMA_6  0x01
-#define ISP16_DMA_7  0x02
-#define ISP16_IO_SET_MASK  0x20  /* don't change 5-bit */
-/* ...for port */
-#define ISP16_IO_SET_PORT  0xF8E
-/* enable the card */
-#define ISP16_C928__ENABLE_PORT  0xF90  /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__ENABLE_PORT  0xF91  /* ISP16 with OPTi 82C929 chip */
-#define ISP16_ENABLE_CDROM  0x80  /* seven bit */
-
-/* the magic stuff */
-#define ISP16_CTRL_PORT  0xF8F
-#define ISP16_C928__CTRL  0xE2  /* ISP16 with OPTi 82C928 chip */
-#define ISP16_C929__CTRL  0xE3  /* ISP16 with OPTi 82C929 chip */
-
-static short isp16_detect(void);
-static short isp16_c928__detect(void);
-static short isp16_c929__detect(void);
-static short isp16_cdi_config( int base, u_char drive_type, int irq, int dma );
-static void isp16_sound_config( void );
-static short isp16_type; /* dependent on type of interface card */
-static u_char isp16_ctrl;
-static u_short isp16_enable_port;
-
-/*static int sjcd_present = 0;*/
-static u_char special_mask = 0;
-
-static unsigned char defaults[ 16 ] = {
-  0xA8, 0xA8, 0x18, 0x18, 0x18, 0x18, 0x8E, 0x8E,
-  0x03, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x00
-};
-/* ------------- */
-/*
- * -- ISP16 detection and configuration
- *
- *    Copyright (c) 1995, Eric van der Maarel <maarel@marin.nl>
- *
- *    Version 0.5
- *
- *    Detect cdrom interface on ISP16 soundcard.
- *    Configure cdrom interface.
- *    Configure sound interface.
- *
- *    Algorithm for the card with OPTi 82C928 taken
- *    from the CDSETUP.SYS driver for MSDOS,
- *    by OPTi Computers, version 2.03.
- *    Algorithm for the card with OPTi 82C929 as communicated
- *    to me by Vadim Model and Leo Spiekman.
- *
- *    Use, modifification or redistribution of this software is
- *    allowed under the terms of the GPL.
- *
- */
-
-
-#define ISP16_IN(p) (outb(isp16_ctrl,ISP16_CTRL_PORT), inb(p))
-#define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
-
-static short
-isp16_detect(void)
-{
-
-  if ( !( isp16_c929__detect() < 0 ) )
-    return(2);
-  else
-    return( isp16_c928__detect() );
-}
-
-static short
-isp16_c928__detect(void)
-{
-  u_char ctrl;
-  u_char enable_cdrom;
-  u_char io;
-  short i = -1;
-
-  isp16_ctrl = ISP16_C928__CTRL;
-  isp16_enable_port = ISP16_C928__ENABLE_PORT;
-
-  /* read' and write' are a special read and write, respectively */
-
-  /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
-  ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC;
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
-  /* read' 3,4 and 5-bit from the cdrom enable port */
-  enable_cdrom = ISP16_IN( ISP16_C928__ENABLE_PORT ) & 0x38;
-
-  if ( !(enable_cdrom & 0x20) ) {  /* 5-bit not set */
-    /* read' last 2 bits of ISP16_IO_SET_PORT */
-    io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03;
-    if ( ((io&0x01)<<1) == (io&0x02) ) {  /* bits are the same */
-      if ( io == 0 ) {  /* ...the same and 0 */
-        i = 0;
-        enable_cdrom |= 0x20;
-      }
-      else {  /* ...the same and 1 */  /* my card, first time 'round */
-        i = 1;
-        enable_cdrom |= 0x28;
-      }
-      ISP16_OUT( ISP16_C928__ENABLE_PORT, enable_cdrom );
-    }
-    else {  /* bits are not the same */
-      ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-      return(i); /* -> not detected: possibly incorrect conclusion */
-    }
-  }
-  else if ( enable_cdrom == 0x20 )
-    i = 0;
-  else if ( enable_cdrom == 0x28 )  /* my card, already initialised */
-    i = 1;
-
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
-  return(i);
-}
-
-static short
-isp16_c929__detect(void)
-{
-  u_char ctrl;
-  u_char tmp;
-
-  isp16_ctrl = ISP16_C929__CTRL;
-  isp16_enable_port = ISP16_C929__ENABLE_PORT;
-
-  /* read' and write' are a special read and write, respectively */
-
-  /* read' ISP16_CTRL_PORT and save */
-  ctrl = ISP16_IN( ISP16_CTRL_PORT );
-
-  /* write' zero to the ctrl port and get response */
-  ISP16_OUT( ISP16_CTRL_PORT, 0 );
-  tmp = ISP16_IN( ISP16_CTRL_PORT );
-
-  if ( tmp != 2 )  /* isp16 with 82C929 not detected */
-    return(-1);
-
-  /* restore ctrl port value */
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-  
-  return(2);
-}
-
-static short
-isp16_cdi_config( int base, u_char drive_type, int irq, int dma )
-{
-  u_char base_code;
-  u_char irq_code;
-  u_char dma_code;
-  u_char i;
-
-  if ( (drive_type == ISP16_MITSUMI) && (dma != 0) )
-    printk( "Mitsumi cdrom drive has no dma support.\n" );
-
-  switch (base) {
-  case 0x340: base_code = ISP16_BASE_340; break;
-  case 0x330: base_code = ISP16_BASE_330; break;
-  case 0x360: base_code = ISP16_BASE_360; break;
-  case 0x320: base_code = ISP16_BASE_320; break;
-  default:
-    printk( "Base address 0x%03X not supported by cdrom interface on ISP16.\n", base );
-    return(-1);
-  }
-  switch (irq) {
-  case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */
-  case 5: irq_code = ISP16_IRQ_5;
-          printk( "Irq 5 shouldn't be used by cdrom interface on ISP16,"
-            " due to possible conflicts with the soundcard.\n");
-          break;
-  case 7: irq_code = ISP16_IRQ_7;
-          printk( "Irq 7 shouldn't be used by cdrom interface on ISP16,"
-            " due to possible conflicts with the soundcard.\n");
-          break;
-  case 3: irq_code = ISP16_IRQ_3; break;
-  case 9: irq_code = ISP16_IRQ_9; break;
-  case 10: irq_code = ISP16_IRQ_10; break;
-  case 11: irq_code = ISP16_IRQ_11; break;
-  default:
-    printk( "Irq %d not supported by cdrom interface on ISP16.\n", irq );
-    return(-1);
-  }
-  switch (dma) {
-  case 0: dma_code = ISP16_DMA_X; break;  /* disable dma */
-  case 1: printk( "Dma 1 cannot be used by cdrom interface on ISP16,"
-            " due to conflict with the soundcard.\n");
-          return(-1); break;
-  case 3: dma_code = ISP16_DMA_3; break;
-  case 5: dma_code = ISP16_DMA_5; break;
-  case 6: dma_code = ISP16_DMA_6; break;
-  case 7: dma_code = ISP16_DMA_7; break;
-  default:
-    printk( "Dma %d not supported by cdrom interface on ISP16.\n", dma );
-    return(-1);
-  }
-
-  if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
-    drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
-    drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
-    drive_type != ISP16_DRIVE_X ) {
-    printk( "Drive type (code 0x%02X) not supported by cdrom"
-     " interface on ISP16.\n", drive_type );
-    return(-1);
-  }
-
-  /* set type of interface */
-  i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK;  /* clear some bits */
-  ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type );
-
-  /* enable cdrom on interface with 82C929 chip */
-  if ( isp16_type > 1 )
-    ISP16_OUT( isp16_enable_port, ISP16_ENABLE_CDROM );
-
-  /* set base address, irq and dma */
-  i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK;  /* keep some bits */
-  ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code );
-
-  return(0);
-}
-
-static void isp16_sound_config( void )
-{
-  int i;
-  u_char saved;
-
-  saved = ISP16_IN( 0xF8D ) & 0x8F;
-    
-  ISP16_OUT( 0xF8D, 0x40 );
-
-  /*
-   * Now we should wait for a while...
-   */
-  for( i = 16*1024; i--; );
-  
-  ISP16_OUT( 0xF8D, saved );
-
-  ISP16_OUT( 0xF91, 0x1B );
-
-  for( i = 5*64*1024; i != 0; i-- )
-    if( !( inb( 0x534 ) & 0x80 ) ) break;
-
-  if( i > 0 ) {
-    saved = ( inb( 0x534 ) & 0xE0 ) | 0x0A;
-    outb( saved, 0x534 );
-
-    special_mask = ( inb( 0x535 ) >> 4 ) & 0x08;
-
-    saved = ( inb( 0x534 ) & 0xE0 ) | 0x0C;
-    outb( saved, 0x534 );
-
-    switch( inb( 0x535 ) ) {
-      case 0x09:
-      case 0x0A:
-        special_mask |= 0x05;
-        break;
-      case 0x8A:
-        special_mask = 0x0F;
-        break;
-      default:
-        i = 0;
-    }
-  }
-  if ( i == 0 ) {
-    printk( "Strange MediaMagic, but\n" );
-  }
-  else {
-    printk( "Conf:" );
-    saved = inb( 0x534 ) & 0xE0;
-    for( i = 0; i < 16; i++ ) {
-      outb( 0x20 | ( u_char )i, 0x534 );
-      outb( defaults[i], 0x535 );
-    }
-    for ( i = 0; i < 16; i++ ) {
-      outb( 0x20 | ( u_char )i, 0x534 );
-      saved = inb( 0x535 );
-      printk( " %02X", saved );
-    }
-    printk( "\n" );
-  }
-
-  ISP16_OUT( 0xF91, 0xA0 | special_mask );
-
-  /*
-   * The following have no explaination yet.
-   */
-  ISP16_OUT( 0xF90, 0xA2 );
-  ISP16_OUT( 0xF92, 0x03 );
-
-  /*
-   * Turn general sound on and set total volume.
-   */
-  ISP16_OUT( 0xF93, 0x0A );
-
-/*
-  outb( 0x04, 0x224 );
-  saved = inb( 0x225 );
-  outb( 0x04, 0x224 );
-  outb( saved, 0x225 );
-*/
-
-}
index 2258ae1a5e63c347421efc5604a59e2db4808575..21dfc2e2f16a920117720f32b932a4dbbf2c0632 100644 (file)
@@ -2376,7 +2376,7 @@ cy_close(struct tty_struct * tty, struct file * filp)
     if (info->flags & ASYNC_CALLOUT_ACTIVE)
        info->callout_termios = *tty->termios;
     if (info->flags & ASYNC_INITIALIZED)
-       tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
+       tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
     shutdown(info);
     if (tty->driver.flush_buffer)
        tty->driver.flush_buffer(tty);
index 96a8532adbba9b48be37a6e0832eb173efb29737..8ddd95d53067906bc1c7330acc43c3a5ec7ce96a 100644 (file)
@@ -602,7 +602,9 @@ int lp_init(void)
 {
        int offset = 0;
        int count = 0;
+#ifdef MODULE
        int failed = 0;
+#endif
 
        if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) {
                printk("lp: unable to get major %d\n", LP_MAJOR);
index e798ebc7e43501d26e7c31032d12b35580e400e3..79e0d0bc916cce1b509b6a5d596c0c535bb31f49 100644 (file)
@@ -195,9 +195,13 @@ int pty_open(struct tty_struct *tty, struct file * filp)
        tty->driver_data = pty;
 
        if (!tmp_buf) {
-               tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
-               if (!tmp_buf)
-                       return -ENOMEM;
+               unsigned long page = get_free_page(GFP_KERNEL);
+               if (!tmp_buf) {
+                       if (!page)
+                               return -ENOMEM;
+                       tmp_buf = (unsigned char *) page;
+               } else
+                       free_page(page);
        }
 
        if (tty->driver.subtype == PTY_TYPE_SLAVE)
index f8ba50b12363e47365dc60a4fbe185201b898a29..9556fb45b74d8f35a9671ead93268a968c76b349 100644 (file)
@@ -328,7 +328,6 @@ get_scrmem(int currcons)
 {
        memcpyw((unsigned short *)vc_scrbuf[currcons],
                (unsigned short *)origin, video_screen_size);
-       __scrollback_mode = 0 ;
        origin = video_mem_start = (unsigned long)vc_scrbuf[currcons];
        scr_end = video_mem_end = video_mem_start + video_screen_size;
        pos = origin + y*video_size_row + (x<<1);
index 6160448c73e363407060cfffe679c13cd9597ce7..cb843d30f771a32514543a99901c07c923849b9c 100644 (file)
@@ -14,6 +14,14 @@ fi
 tristate 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC
 tristate 'PLIP (parallel port) support' CONFIG_PLIP
 tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
+
+tristate 'FRAD (Frame Relay Access Device) support' CONFIG_FRAD
+if [ "$CONFIG_FRAD" = "y" -o "$CONFIG_FRAD" = "m" ]; then
+  int '  Max open DLCI' CONFIG_DLCI_COUNT 24
+  int '  Max DLCI per device' CONFIG_DLCI_MAX 8
+  tristate '  Sangoma S502A FRAD support' CONFIG_SDLA
+fi
+
 bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA
 bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC
 if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
index b5c15b9d4da81cefacea07782f4b3ce3af5ccc84..be097cb21c6fb720a05c6d677c480e72499e4102 100644 (file)
@@ -419,6 +419,22 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_SDLA),y)
+L_OBJS += sdla.o
+else
+  ifeq ($(CONFIG_SDLA),m)
+  M_OBJS += sdla.o
+  endif
+endif
+
+ifeq ($(CONFIG_FRAD),y)
+L_OBJS += dlci.o 
+else
+  ifeq ($(CONFIG_FRAD),m)
+  M_OBJS += dlci.o
+  endif
+endif
+
 include $(TOPDIR)/Rules.make
 
 clean:
@@ -475,3 +491,8 @@ lance.o: lance.c CONFIG
        $(CC) $(CPPFLAGS) $(CFLAGS) $(LANCE_OPTS) -c $<
 
 8390.o: 8390.c 8390.h CONFIG
+
+sdla.o: sdla.c CONFIG 
+
+dlci.o: dlci.c CONFIG
+
index f6a7c17dd91bc2a20a12796b87d0a9571049268a..1da81e7858621f7ae6beef95deadc10f5dc91ca9 100644 (file)
@@ -188,6 +188,22 @@ ethif_probe(struct device *dev)
     return 0;
 }
 
+#ifdef CONFIG_SDLA
+    extern int sdla_init(struct device *);
+    static struct device sdla0_dev = { "sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sdla_init, };
+
+#   undef NEXT_DEV
+#   define NEXT_DEV    (&sdla0_dev)
+#endif
+
+/* This must be AFTER the various FRADs so it initializes FIRST! */
+       
+#ifdef CONFIG_FRAD
+    extern int dlci_init(struct device *);
+    static struct device dlci_dev = { "dlci", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, dlci_init, };
+#   undef NEXT_DEV
+#   define NEXT_DEV    (&dlci_dev)
+#endif
 
 #ifdef CONFIG_NETROM
        extern int nr_init(struct device *);
@@ -366,7 +382,7 @@ struct device eql_dev = {
 
 #endif 
 #endif
-       
+
 extern int loopback_init(struct device *dev);
 struct device loopback_dev = {
        "lo",                   /* Software Loopback interface          */
index 9aa8785e0dc2c70adf2605c7ee7701a775512cfa..0ed43d905d4282bb83ef4b91ed81090ad00a9349 100644 (file)
@@ -78,7 +78,7 @@
 #include <asm/bitops.h>
 #include <asm/segment.h>
 
-#include <net/if.h>
+#include <linux/if.h>
 
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
@@ -92,9 +92,9 @@
 #include <linux/netprotocol.h>
 #endif
 
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <net/if_arp.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/if_arp.h>
 
 #undef   PACKETPTR
 #define  PACKETPTR 1
index e446f8e929d5040dded25909a5e38d5ff992fe52..6c2578385c6e67a4d53e13469dac919e93957dd8 100644 (file)
                            Changed driver to autprobe as a module. No irq
                            checking is done now - assume BIOS is good!
                          Added SMC9332 detection <manabe@Roy.dsl.tutics.ac.jp>
+      0.41    21-Mar-96   Don't check for get_hw_addr checksum unless DEC card
+                          only <niles@axp745gsfc.nasa.gov>
+                         Fix for multiple PCI cards reported by <jos@xos.nl>
+                         Duh, put the SA_SHIRQ flag into request_interrupt().
+                         Fix SMC ethernet address in enet_det[].
+                         Print chip name instead of "UNKNOWN" during boot.
 
     =========================================================================
 */
 
-static const char *version = "de4x5.c:v0.40 96/3/5 davies@wanton.lkg.dec.com\n";
+static const char *version = "de4x5.c:v0.41 96/3/21 davies@wanton.lkg.dec.com\n";
 
 #include <linux/module.h>
 
@@ -255,7 +261,7 @@ static struct phy_table phy_info[] = {
 ** Define special SROM detection cases
 */
 static c_char enet_det[][ETH_ALEN] = {
-    {0x00, 0x00, 0x0c, 0x00, 0x00, 0x00}
+    {0x00, 0x00, 0xc0, 0x00, 0x00, 0x00}
 };
 
 #define SMC 1
@@ -897,7 +903,8 @@ de4x5_open(struct device *dev)
     
     de4x5_dbg_open(dev);
     
-    if (request_irq(dev->irq, (void *)de4x5_interrupt, 0, lp->adapter_name, dev)) {
+    if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ, 
+                                                    lp->adapter_name, dev)) {
        printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq);
        status = -EAGAIN;
     } else {
@@ -1577,7 +1584,7 @@ static void pci_probe(struct device *dev, u_long ioaddr)
     u_int iobase;
     struct bus_type *lp = &bus;
     
-    if (!ioaddr && autoprobed) return;       /* Been here before ! */
+    if ((!ioaddr || !loading_module) && autoprobed) return;
     
     if (!pcibios_present()) return;          /* No PCI bus in this machine! */
     
@@ -2811,8 +2818,11 @@ static int PCI_signature(char *name, struct bus_type *lp)
     if (i == siglen) {
        if (dec_only) {
            *name = '\0';
-       } else {
-           strcpy(name, "UNKNOWN");
+       } else {                        /* Use chip name to avoid confusion */
+           strcpy(name, (((lp->chipset == DC21040) ? "DC21040" :
+                          ((lp->chipset == DC21041) ? "DC21041" :
+                           ((lp->chipset == DC21140) ? "DC21140" : "UNKNOWN"
+                            )))));
        }
     }
     
@@ -2885,12 +2895,12 @@ static int get_hw_addr(struct device *dev)
            chksum = (u_char) tmp;
            while ((tmp = inl(DE4X5_APROM)) < 0);
            chksum |= (u_short) (tmp << 8);
-           if (k != chksum) status = -1;
+           if ((k != chksum) && (dec_only)) status = -1;
        }
     } else {
        chksum = (u_char) inb(EISA_APROM);
        chksum |= (u_short) (inb(EISA_APROM) << 8);
-       if (k != chksum) status = -1;
+       if ((k != chksum) && (dec_only)) status = -1;
     }
     
     return status;
diff --git a/drivers/net/dlci.c b/drivers/net/dlci.c
new file mode 100644 (file)
index 0000000..94213bd
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * DLCI                Implementation of Frame Relay protocol for Linux, according to
+ *             RFC 1490.  This generic device provides en/decapsulation for an
+ *             underlying hardware driver.  Routes & IPs are assigned to these
+ *             interfaces.  Requires 'dlcicfg' program to create usable 
+ *             interfaces, the initial one, 'dlci' is for IOCTL use only.
+ *
+ * Version:    @(#)dlci.c      0.10    23 Mar 1996
+ *
+ * Author:     Mike McLagan <mike.mclagan@linux.org>
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/errno.h>
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/if_frad.h>
+
+#include <net/sock.h>
+
+static const char *devname = "dlci";
+static const char *version = "DLCI driver v0.10, 23 Mar 1996, mike.mclagan@linux.org";
+
+static struct device *open_dev[CONFIG_DLCI_COUNT];
+
+static char *basename[16];
+
+int dlci_init(struct device *dev);
+
+/* allow FRAD's to register their name as a valid FRAD */
+int register_frad(const char *name)
+{
+   int i;
+
+   if (!name)
+      return(-EINVAL);
+
+   for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+   {
+      if (!basename[i])
+         break;
+
+      /* take care of multiple registrations */
+      if (strcmp(basename[i], name) == 0)
+         return(0);
+   }
+
+   if (i == sizeof(basename) / sizeof(char *))
+      return(-ENOMEM);
+
+   basename[i] = (char *) name;
+
+   return(0);
+}
+
+int unregister_frad(const char *name)
+{
+   int i;
+
+   if (!name)
+      return(-EINVAL);
+
+   for (i=0;i<sizeof(basename) / sizeof(char *);i++)
+      if (basename[i] && (strcmp(basename[i], name) == 0))
+         break;
+
+   if (i == sizeof(basename) / sizeof(char *))
+      return(-EINVAL);
+
+   basename[i] = NULL;
+
+   return(0);
+}
+
+/* 
+   these encapsulate the RFC 1490 requirements as well as 
+   deal with packet transmission and reception, working with
+   the upper network layers 
+ */
+
+static int dlci_header(struct sk_buff *skb, struct device *dev, 
+                           unsigned short type, void *daddr, void *saddr, 
+                           unsigned len)
+{
+   struct fradhdr    hdr;
+   struct dlci_local *dlp;
+   unsigned          hlen;
+   char              *dest;
+
+   dlp = dev->priv;
+
+   hdr.control = FRAD_I_UI;
+   switch(type)
+   {
+      case ETH_P_IP:
+         hdr.pad = FRAD_P_IP;
+         hlen = sizeof(hdr.control) + sizeof(hdr.pad);
+         break;
+
+      /* feel free to add other types, if necessary */
+
+      default:
+         hdr.pad = FRAD_P_PADDING;
+         hdr.NLPID = FRAD_P_SNAP;
+         memset(hdr.OUI, 0, sizeof(hdr.OUI));
+         hdr.PID = type;
+         hlen = sizeof(hdr);
+         break;
+   }
+
+   dest = skb_push(skb, hlen);
+   if (!dest)
+      return(0);
+
+   memcpy(dest, &hdr, hlen);
+
+   return(hlen);
+}
+
+static void dlci_receive(struct sk_buff *skb, struct device *dev)
+{
+   struct dlci_local *dlp;
+   struct fradhdr    *hdr;
+   int               process, header;
+
+   dlp = dev->priv;
+   hdr = (struct fradhdr *) skb->data;
+   process = 0;
+   header = 0;
+   skb->dev = dev;
+
+   if (hdr->control != FRAD_I_UI)
+   {
+      printk(KERN_NOTICE "%s: Invalid header flag 0x%02X.\n", dev->name, hdr->control);
+      dlp->stats.rx_errors++;
+   }
+   else
+      switch(hdr->pad)
+      {
+         case FRAD_P_PADDING:
+            if (hdr->NLPID != FRAD_P_SNAP)
+            {
+               printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->NLPID);
+               dlp->stats.rx_errors++;
+               break;
+            }
+    
+            if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0)
+            {
+               printk(KERN_NOTICE "%s: Unsupported organizationally unique identifier 0x%02X-%02X-%02X.\n", dev->name, hdr->OUI[0], hdr->OUI[1], hdr->OUI[2]);
+               dlp->stats.rx_errors++;
+               break;
+            }
+
+            /* at this point, it's an EtherType frame */
+            header = sizeof(struct fradhdr);
+            skb->protocol = htons(hdr->PID);
+            process = 1;
+            break;
+
+         case FRAD_P_IP:
+            header = sizeof(hdr->control) + sizeof(hdr->pad);
+            skb->protocol = htons(ETH_P_IP);
+            process = 1;
+            break;
+
+         case FRAD_P_SNAP:
+         case FRAD_P_Q933:
+         case FRAD_P_CLNP:
+            printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->pad);
+            dlp->stats.rx_errors++;
+            break;
+
+         default:
+            printk(KERN_NOTICE "%s: Invalid pad byte 0x%02X.\n", dev->name, hdr->pad);
+            dlp->stats.rx_errors++;
+            break;            
+      }
+
+   if (process)
+   {
+      /* we've set up the protocol, so discard the header */
+      skb->mac.raw = skb->data; 
+      skb_pull(skb, header);
+      netif_rx(skb);
+      dlp->stats.rx_packets++;
+   }
+   else
+      dev_kfree_skb(skb, FREE_WRITE);
+}
+
+static int dlci_transmit(struct sk_buff *skb, struct device *dev)
+{
+   struct dlci_local *dlp;
+   int               ret;
+
+   ret = 0;
+
+   if (!skb || !dev)
+      return(0);
+
+   if (dev->tbusy)
+      return(1);
+
+   dlp = dev->priv;
+
+   if (set_bit(0, (void*)&dev->tbusy) != 0)
+      printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
+   else
+   {
+      ret = dlp->slave->hard_start_xmit(skb, dlp->slave); 
+      if (ret)
+         dlp->stats.tx_errors++;
+      else 
+         dlp->stats.tx_packets++;
+
+      /* per Alan Cox, always return 0, let the slave free the packet */
+      ret = 0;
+      dev->tbusy = 0;
+   }
+
+   return(ret);
+}
+
+int dlci_add(struct dlci_add *new)
+{
+   struct device       *master, *slave;
+   struct dlci_local   *dlp;
+   struct frad_local   *flp;
+   struct dlci_add     dlci;
+   int                 err, i;
+   char                buf[10];
+
+   err = verify_area(VERIFY_READ, new, sizeof(*new));
+   if (err)
+      return(err);
+
+   memcpy_fromfs(&dlci, new, sizeof(dlci));
+
+   /* validate slave device */
+   slave = dev_get(dlci.devname);
+   if (!slave)
+      return(-ENODEV);
+
+   if (slave->type != ARPHRD_FRAD)
+      return(-EINVAL);
+
+   /* check for registration */
+   for (i=0;i<sizeof(basename) / sizeof(char *); i++)
+      if ((basename[i]) && 
+          (strncmp(dlci.devname, basename[i], strlen(basename[i])) == 0) && 
+          (strlen(dlci.devname) > strlen(basename[i])))
+         break;
+
+   if (i == sizeof(basename) / sizeof(char *))
+      return(-EINVAL);
+
+   /* check for too many open devices : should this be dynamic ? */
+   for(i=0;i<CONFIG_DLCI_COUNT;i++)
+      if (!open_dev[i])
+         break;
+
+   if (i == CONFIG_DLCI_COUNT)
+      return(-ENOSPC);  /*  #### Alan: Comments on this?? */
+
+   /* create device name */
+   sprintf(buf, "%s%02i", devname, i);
+
+   master = kmalloc(sizeof(*master), GFP_KERNEL);
+   if (!master)
+      return(-ENOMEM);
+
+   memset(master, 0, sizeof(*master));
+   master->name = kmalloc(strlen(buf), GFP_KERNEL);
+
+   if (!master->name)
+   {
+      kfree(master);
+      return(-ENOMEM);
+   }
+
+   strcpy(master->name, buf);
+   master->init = dlci_init;
+   master->flags = 0;
+
+   err = register_netdev(master);
+   if (err < 0)
+   {
+      kfree(master->name);
+      kfree(master);
+      return(err);
+   }
+
+   *(short *)(master->dev_addr) = dlci.dlci;
+
+   dlp = (struct dlci_local *) master->priv;
+   dlp->slave = slave;
+
+   flp = slave->priv;
+   err = flp ? (*flp->assoc)(slave, master) : -EINVAL;
+   if (err < 0)
+   {
+      unregister_netdev(master);
+      kfree(master->priv);
+      kfree(master->name);
+      kfree(master);
+      return(err);
+   }
+
+   memcpy_tofs(new->devname, buf, strlen(buf) + 1);
+   open_dev[i] = master;
+
+   MOD_INC_USE_COUNT;
+
+   return(0);
+}
+
+int dlci_del(struct device *master)
+{
+   struct dlci_local *dlp;
+   struct frad_local *flp;
+   struct device     *slave;
+   int               i, err;
+
+   if (master->start)
+      return(-EBUSY);
+
+   dlp = master->priv;
+   slave = dlp->slave;
+   flp = slave->priv;
+
+   err = (*flp->deassoc)(slave, master);
+   if (err)
+      return(err);
+
+   unregister_netdev(master);
+
+   for(i=0;i<CONFIG_DLCI_COUNT;i++)
+      if (master == open_dev[i])
+         break;
+
+   if (i<CONFIG_DLCI_COUNT)
+      open_dev[i] = NULL;
+
+   kfree(master->priv);
+   kfree(master->name);
+   kfree(master);
+
+   MOD_DEC_USE_COUNT;
+
+   return(0);
+}
+
+int dlci_config(struct device *dev, struct dlci_conf *conf, int get)
+{
+   struct dlci_conf  config;
+   struct dlci_local *dlp;
+   struct frad_local *flp;
+   int               err;
+
+   dlp = dev->priv;
+
+   flp = dlp->slave->priv;
+
+   if (!get)
+   {
+      memcpy_fromfs(&config, conf, sizeof(struct dlci_conf));
+      if (config.flags & ~DLCI_VALID_FLAGS)
+         return(-EINVAL);
+      memcpy(&dlp->config, &config, sizeof(struct dlci_conf));
+      dlp->configured = 1;
+   }
+
+   err = (*flp->dlci_conf)(dlp->slave, dev, get);
+   if (err)
+      return(err);
+
+   if (get)
+      memcpy_tofs(conf, &dlp->config, sizeof(struct dlci_conf));
+
+   return(0);
+}
+
+int dlci_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
+{
+   struct dlci_local *dlp;
+
+   if (!suser())
+      return(-EPERM);
+
+   dlp = dev->priv;
+
+   switch(cmd)
+   {
+      case DLCI_GET_SLAVE:
+         if (!*(short *)(dev->dev_addr))
+            return(-EINVAL);
+
+         strcpy(ifr->ifr_slave, dlp->slave->name);
+         break;
+
+      case DLCI_DEVADD:
+         /* can only add on the primary device */
+         if (*(short *)(dev->dev_addr))
+            return(-EINVAL);
+
+         return(dlci_add((struct dlci_add *) ifr->ifr_data));
+         break;
+
+      case DLCI_DEVDEL:
+         /* can't delete the primary device */
+         if (!*(short *)(dev->dev_addr))
+            return(-EINVAL);
+
+         if (dev->start)
+            return(-EBUSY);
+
+         return(dlci_del(dev));
+         break;
+
+      case DLCI_GET_CONF:
+      case DLCI_SET_CONF:
+         if (!*(short *)(dev->dev_addr))
+            return(-EINVAL);
+
+         return(dlci_config(dev, (struct dlci_conf *) ifr->ifr_data, cmd == DLCI_GET_CONF));
+         break;
+
+      default: 
+         return(-EOPNOTSUPP);
+   }
+   return(0);
+}
+
+static int dlci_change_mtu(struct device *dev, int new_mtu)
+{
+   struct dlci_local *dlp;
+
+   dlp = dev->priv;
+
+   return((*dlp->slave->change_mtu)(dlp->slave, new_mtu));
+}
+
+static int dlci_open(struct device *dev)
+{
+   struct dlci_local *dlp;
+   struct frad_local *flp;
+   int               err;
+
+   dlp = dev->priv;
+
+   if (!*(short *)(dev->dev_addr))
+      return(-EINVAL);
+
+   if (!dlp->slave->start)
+      return(-ENOTCONN);
+
+   dev->flags = 0;
+   dev->tbusy = 0;
+   dev->interrupt = 0;
+   dev->start = 1;
+
+   flp = dlp->slave->priv;
+   err = (*flp->activate)(dlp->slave, dev);
+   if (err)
+      return(err);
+
+   return 0;
+}
+
+static int dlci_close(struct device *dev)
+{
+   struct dlci_local *dlp;
+   struct frad_local *flp;
+   int               err;
+
+   dlp = dev->priv;
+
+   flp = dlp->slave->priv;
+   err = (*flp->deactivate)(dlp->slave, dev);
+
+   dev->start = 0;
+
+   return 0;
+}
+
+static struct enet_statistics *dlci_get_stats(struct device *dev)
+{
+   struct dlci_local *dlp;
+
+   dlp = dev->priv;
+
+   return(&dlp->stats);
+}
+
+int dlci_init(struct device *dev)
+{
+   struct dlci_local *dlp;
+   int i;
+
+   dev->priv = kmalloc(sizeof(struct dlci_local), GFP_KERNEL);
+   if (!dev->priv)
+      return(-ENOMEM);
+
+   memset(dev->priv, 0, sizeof(struct dlci_local));
+   dlp = dev->priv;
+
+   dev->flags           = 0;
+   dev->open            = dlci_open;
+   dev->stop            = dlci_close;
+   dev->do_ioctl        = dlci_ioctl;
+   dev->hard_start_xmit = dlci_transmit;
+   dev->hard_header     = dlci_header;
+   dev->get_stats       = dlci_get_stats;
+   dev->change_mtu     = dlci_change_mtu;
+
+   dlp->receive         = dlci_receive;
+
+   dev->type            = ARPHRD_DLCI;
+   dev->family          = AF_INET;
+   dev->hard_header_len = sizeof(struct fradhdr);
+   dev->pa_alen         = sizeof(unsigned long);
+
+   memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
+
+   for (i = 0; i < DEV_NUMBUFFS; i++) 
+      skb_queue_head_init(&dev->buffs[i]);
+
+   return(0);
+}
+
+int dlci_setup(void)
+{
+   int i;
+
+   printk("%s.\n", version);
+   
+   for(i=0;i<CONFIG_DLCI_COUNT;i++)
+      open_dev[i] = NULL;
+
+   for(i=0;i<sizeof(basename) / sizeof(char *);i++)
+      basename[i] = NULL;
+
+   return(0);
+}
+
+#ifdef MODULE
+static struct device dlci = {"dlci", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, dlci_init, };
+
+int init_module(void)
+{
+   dlci_setup();
+   return(register_netdev(&dlci));
+}
+
+void cleanup_module(void)
+{
+   struct dlci_local   *dlp;
+   struct frad_local   *flp;
+   int                 i;
+
+   unregister_netdev(&dlci);
+
+   for(i=0;i<CONFIG_DLCI_COUNT;i++)
+      if (open_dev[i])
+      {
+         dlp = open_dev[i]->priv;
+         flp = open_dev[i]->slave->priv;
+
+         if (open_dev[i]->start)
+         {
+            if (flp->deactivate)
+               (*flp->deactivate)(open_dev[i]->slave, open_dev[i]);
+            open_dev[i]->start = 0;
+         }
+
+         (*flp->deassoc)(open_dev[i]->slave, open_dev[i]);
+         kfree(open_dev[i]->priv);
+         kfree(open_dev[i]->name);
+         kfree(open_dev[i]);
+         open_dev[i] = NULL;
+      }
+
+   if (dlci.priv)
+      kfree(dlci.priv);
+}
+#endif /* MODULE */
index 34842d335ce80b7b9bf46cb32eb344fac904cf16..ebed939d70e06d4691c04356c81ec937cb055507 100644 (file)
@@ -1,14 +1,14 @@
 /* ibmtr.c:  A shared-memory IBM Token Ring 16/4 driver for linux */
 /*
-       Written 1993 by Mark Swanson and Peter De Schrijver.
-       This software may be used and distributed according to the terms
-       of the GNU Public License, incorporated herein by reference.
+  Written 1993 by Mark Swanson and Peter De Schrijver.
+  This software may be used and distributed according to the terms
+  of the GNU Public License, incorporated herein by reference.
 
-       This device driver should work with Any IBM Token Ring Card that does
-   not use DMA.
+  This device driver should work with Any IBM Token Ring Card that does
+  not use DMA.
 
-       I used Donald Becker's (becker@super.org) device driver work
-       as a base for most of my initial work.
+  I used Donald Becker's (becker@super.org) device driver work
+  as a base for most of my initial work.
 */
 
 /*
         - removed redundant information display
         - some code reworking
 
+   Changes by Michel Lespinasse (walken@via.ecp.fr), 
+     Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr)
+     (February 18, 1996) :
+       - modified shared memory and mmio access port the driver to 
+          alpha platform (structure access -> readb/writeb)
+
    Chagnes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com)
                            (January 18 1996):
         - swapped WWOR and WWCR in ibmtr.h
 
 /* changes the output format of driver initialisation */
 #define TR_NEWFORMAT   1
+#define TR_VERBOSE     0
 
 /* some 95 OS send many non UI frame; this allow removing the warning */
 #define TR_FILTERNONUI 1
 
 /* version and credits */
-static const char *version = "ibmtr.c: v1.3.24 8/7/94 Peter De Schrijver and Mark Swanson\n"
-"   modified 10/3/94 DW Morris, 3/9/95 F Farid and P Andre, 9/7/95 P Andre\n";
-
+static const char *version = 
+"ibmtr.c: v1.3.57 8/7/94 Peter De Schrijver and Mark Swanson\n"
+"  modified 10/3/94 DW Morris, modified at VIA, ECP, France\n"
+"  (3/9/95 F Farid and P Andre, 9/7/95 PA and 2/20/95 ML/PA/YD)\n";
 static char pcchannelid[]={0x05, 0x00, 0x04, 0x09,
-                        0x04, 0x03, 0x04, 0x0f,
-                        0x03, 0x06, 0x03, 0x01,
-                        0x03, 0x01, 0x03, 0x00,
-                        0x03, 0x09, 0x03, 0x09,
-                        0x03, 0x00, 0x02, 0x00};
+                          0x04, 0x03, 0x04, 0x0f,
+                          0x03, 0x06, 0x03, 0x01,
+                          0x03, 0x01, 0x03, 0x00,
+                          0x03, 0x09, 0x03, 0x09,
+                          0x03, 0x00, 0x02, 0x00};
 static char mcchannelid[]={0x04, 0x0d, 0x04, 0x01,
-                        0x05, 0x02, 0x05, 0x03,
-                        0x03, 0x06, 0x03, 0x03,
-                        0x05, 0x08, 0x03, 0x04,
-                        0x03, 0x05, 0x03, 0x01,
-                        0x03, 0x08, 0x02, 0x00};
+                          0x05, 0x02, 0x05, 0x03,
+                          0x03, 0x06, 0x03, 0x03,
+                          0x05, 0x08, 0x03, 0x04,
+                          0x03, 0x05, 0x03, 0x01,
+                          0x03, 0x08, 0x02, 0x00};
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -114,29 +123,21 @@ static char mcchannelid[]={0x04, 0x0d, 0x04, 0x01,
 #define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args)
 #define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args)
 
-#ifdef TR_NEWFORMAT
+#if TR_NEWFORMAT
 /* this allows displaying full adapter information */
 const char *channel_def[] = { "ISA", "MCA", "ISA P&P" };
+
 char *adapter_def(char type)
 {
-       switch (type)
-       {
-               case 0xF : return "Adapter/A";
-               case 0xE : return "16/4 Adapter/II";
-               default : return "adapter";
-       };
+       switch (type) {
+             case 0xF : return "Adapter/A";
+             case 0xE : return "16/4 Adapter/II";
+             default : return "adapter";
+       };
 };
 #endif
 
-#if 0
-struct tok_info tok_info1;   /*  WARNING: this area must be replicated
-                                 or 'malloced' to support > 1 adapter */
-
-static struct wait_queue *wait_for_tok_int=NULL, *wait_for_reset;
-void (*do_tok_int)(struct device *dev)=NULL;
-#endif
-
-#ifndef TR_NEWFORMAT
+#if !TR_NEWFORMAT
 unsigned char ibmtr_debug_trace=1;  /*  Patch or otherwise alter to
                                          control tokenring tracing.  */
 #else
@@ -145,8 +146,8 @@ unsigned char ibmtr_debug_trace=0;
 #define TRC_INIT 0x01              /*  Trace initialization & PROBEs */
 #define TRC_INITV 0x02             /*  verbose init trace points     */
 
-static short TokBaseAddrs[]={MMIOStartLocP, /* Addr-s to scan */
-                             MMIOStartLocA};
+/* addresses to scan */
+static short TokBaseAddrs[] = { MMIOStartLocP, MMIOStartLocA };
 
 
 int tok_probe(struct device *dev);
@@ -170,17 +171,29 @@ static struct enet_statistics * tok_get_stats(struct device *dev);
 
 static struct timer_list tr_timer={NULL,NULL,0,0L,tok_open_adapter};
 
+#if 0
 int DummyCallCount=0;
 
 /*  This routine combined with the #DEFINE DPRINTD serves
     to workaround the gcc apparent bug.   in tr_tx() */
 
-static void DummyCall(const char * fmt,...) {DummyCallCount++;return;}
+static void DummyCall(const char * fmt,...) 
+{ DummyCallCount++; return; }
+#endif
 
 static void PrtChanID(char *pcid, short stride) {
-  short i, j;
-  for (i=0,j=0;i<24;i++,j=j+stride) printk("%1x",((int) pcid[j])&0x0f);
-  printk("\n");
+       short i, j;
+       for (i=0, j=0; i<24; i++, j+=stride) 
+               printk("%1x", ((int) pcid[j]) & 0x0f);
+       printk("\n");
+}
+
+static void HWPrtChanID (__u32 pcid, short stride)
+{
+       short i, j;
+       for (i=0, j=0; i<24; i++, j+=stride)
+               printk("%1x", ((int)readb(pcid + j)) & 0x0f);
+       printk("\n");
 }
 
 /* tok_probe():  Routine specified in the network device structure
@@ -196,1147 +209,1232 @@ static void PrtChanID(char *pcid, short stride) {
 
 int tok_probe(struct device *dev)
 {
+       unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0;
+       __u32 t_mmio=0;
+       short PIOaddr=0, iAddr;
+       struct tok_info *ti=0;
+       static struct tok_info *badti=0;  /* if fail after kmalloc, reuse */
+       
+       static unsigned char Shared_Ram_Base = IBMTR_SHARED_RAM_BASE;
+       
+       /* this is the major adapter probe loop.  For each call to tok_probe,
+          we try each remaining entry in TokBaseAddrs[] as a possible
+          adapter.  Once an entry is rejected or assigned, we zero it to
+          avoid duplicate use or worthless trial for the tok probe call*/
+       
+       for (iAddr=0;
+            iAddr < (sizeof(TokBaseAddrs)/sizeof(short))&&PIOaddr==0; iAddr++) { 
+               
+               __u32 cd_chanid;
+               unsigned char *tchanid, ctemp;
+               
+               PIOaddr=TokBaseAddrs[iAddr];  /* address to try           */
+               TokBaseAddrs[iAddr] = 0;      /* (and marked already used */
+               if (PIOaddr == 0) continue;   /* already tried this addr */
+               
+               /* Make sure PIO address not already assigned
+                  elsewhere before we muck with IO address */
+               if (check_region(PIOaddr,TR_IO_EXTENT)) {
+                       if (ibmtr_debug_trace & TRC_INIT)
+                               DPRINTK("check_region(%4hx,%d) failed.\n", PIOaddr, TR_IO_EXTENT);
+                       PIOaddr = 0; 
+                       continue; /* clear to flag fail and try next */
+               }
+               /* Query the adapter PIO base port which will return
+                  indication of where MMIO was placed (per tech ref
+                  this assignment is done by BIOS - what is rational for
+                  where it is?).  We also have a coded interrupt address. */
+               
+               segment = inb(PIOaddr);
+               /* out of range values so we'll assume non-existant IO device */
+               if (segment < 0x40 || segment > 0xe0) { 
+                       PIOaddr = 0; 
+                       continue; /* clear to flag fail and try next */
+               }
+               
+               /* Compute the linear base address of the MMIO area
+                  as LINUX doesn't care about segments          */
+               t_mmio=(((__u32)(segment & 0xfc) << 11) + 0x80000);
+               intr = segment & 0x03;   /* low bits is coded interrupt # */
+               if (ibmtr_debug_trace & TRC_INIT)
+                       DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %08X intr: %d\n", PIOaddr, (int)segment, t_mmio, (int)intr);
+               
+               /* Now we will compare expected 'channelid' strings with
+                  what we is there to learn of ISA/MCA or not TR card */
+               /* !!!WARNING:!!!! It seems pretty silly to blunder ahead
+                  w/o verification that the mmio address we have found
+                  is valid storage -- perhaps this is tolerable for current
+                  hardware state??? */
+               
+               cd_chanid = (CHANNEL_ID + t_mmio);  /* for efficiency */
+               tchanid=pcchannelid; 
+               cardpresent=TR_ISA;  /* try ISA */
+
+               /* suboptimize knowing first byte different */
+               ctemp = readb(cd_chanid) & 0x0f;
+               if (ctemp != *tchanid) { /* NOT ISA card, try MCA */
+                       tchanid=mcchannelid; 
+                       cardpresent=TR_MCA;
+                       if (ctemp != *tchanid)  /* Neither ISA nor MCA */
+                               cardpresent=NOTOK;
+               }
+               
+               if (cardpresent != NOTOK) { /* know presumed type, try rest of ID */
+                       for (i=2,j=1; i<=46; i=i+2,j++) {
+                               if ((readb(cd_chanid+i) & 0x0f) != tchanid[j]) {
+                                       cardpresent=NOTOK;   /* match failed, not TR card */
+                                       break;
+                               }
+                       }
+               }
+               
+               /* If we have an ISA board check for the ISA P&P version,
+                  as it has different IRQ settings */
+               if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio)==0x0e))
+                       cardpresent=TR_ISAPNP;
+               
+               if (cardpresent == NOTOK) { /* "channel_id" did not match, report */
+                       if (ibmtr_debug_trace & TRC_INIT) {
+                               DPRINTK("Channel ID string not found for PIOaddr: %4hx\n", PIOaddr);
+                               DPRINTK("Expected for ISA: ");  PrtChanID(pcchannelid,1);
+                               DPRINTK("           found: ");  HWPrtChanID(cd_chanid,2);
+                               DPRINTK("Expected for MCA: ");  PrtChanID(mcchannelid,1);
+                       }
+                       PIOaddr = 0;  /* all to know not found yet */
+                       continue;
+               }
+               
+       /* !!!! we could tighten validation by checking the HW Address
+          against the 1-s complement..  Move the get HW logic to here */
+               
+       }
+       
+       /* The search loop has either completed with a presumed TR adapter
+          or none found.  Check situation ... march on if possible */
+       
+       if (PIOaddr == 0) { /* failed to find a valid TR adapter */
+               if (ibmtr_debug_trace & TRC_INIT)
+                       DPRINTK("Unable to assign adapter to device.\n");
+               return ENODEV;
+       }
+       
+       /*?? Now, allocate some of the pl0 buffers for this driver.. */
+       
+       if (!badti) {
+               ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
+               if (ti == NULL) return -ENOMEM;
+       } else {
+               ti = badti; 
+               badti = NULL;
+       } /*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */
+       
+       memset(ti, 0, sizeof(struct tok_info));
 
-  unsigned char segment=0, intr=0, irq=0, i=0, j=0,
-                cardpresent=NOTOK,temp=0;
-  unsigned char *t_mmio=0;
-  short PIOaddr=0, iAddr;
-  struct tok_info *ti=0;
-  static struct tok_info *badti=0;  /* if fail after kmalloc, reuse */
-
-  static unsigned char Shared_Ram_Base = IBMTR_SHARED_RAM_BASE;
-
-  /*  this is the major adapter probe loop.  For each call to tok_probe,
-      we try each remaining entry in TokBaseAddrs[] as a possible
-      adapter.  Once an entry is rejected or assigned, we zero it to
-      avoid duplicate use or worthless trial for the tok probe call*/
-
-  for (iAddr=0;
-       iAddr < (sizeof(TokBaseAddrs)/sizeof(short))&&PIOaddr==0;
-       iAddr++) { char *tchanid, *cd_chanid, ctemp;
-    PIOaddr=TokBaseAddrs[iAddr];  /* address to try           */
-    TokBaseAddrs[iAddr] = 0;      /* (and marked already used */
-    if (PIOaddr == 0) continue;   /* already tried this addr */
-    if ( check_region(PIOaddr,TR_IO_EXTENT) ) { /* Make sure PIO address not
-                                                  already assigned elsewhere
-                                                  before we muck with I/O
-                                                  addresses */
-      if (ibmtr_debug_trace & TRC_INIT)
-       DPRINTK("check_region(%4hx,%d) failed.\n",PIOaddr, TR_IO_EXTENT);
-      PIOaddr = 0; continue; /* clear to flag fail and try next */
-    }
-           /*  Query the adapter PIO base port which will return
-               indication of where MMIO was placed (per tech ref
-               this assignment is done by BIOS - what is rational for
-               where it is?).  We also have a coded interrupt address.*/
-
-    segment = inb(PIOaddr);
-    if (segment < 0x40 || segment > 0xe0) { /* out of range values
-                            so we will assume non-existant IO dev */
-      PIOaddr = 0; continue; /* clear to flag fail and try next */
-    }
-
-                 /*  Compute the linear base address of the MMIO area
-                     as LINUX doesn't care about segments          */
-    t_mmio=(char *) (((segment & 0xfc) << 11) + 0x80000);
-    intr = segment & 0x03;   /* low bits is coded interrupt # */
-    if (ibmtr_debug_trace & TRC_INIT)
-      DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p intr: %d\n",
-              PIOaddr, (int) segment,t_mmio,(int) intr);
-    /*  Now we will compare expected 'channelid' strings with
-        what we is there to learn of ISA/MCA or not TR card */
-        /*  !!!WARNING:!!!! It seems pretty silly to blunder ahead
-            w/o verification that the mmio address we have found
-            is valid storage -- perhaps this is tolerable for current
-            hardware state??? */
-    cd_chanid = (char *)(CHANNEL_ID + t_mmio);  /* for efficiency */
-    tchanid=pcchannelid; cardpresent=TR_ISA;  /* try ISA ? */
-                       /* suboptimize knowing first byte different */
-    ctemp = (* cd_chanid) & 0x0f;
-    if (  ctemp != *tchanid) { /* NOT ISA card, try MCA */
-      tchanid=mcchannelid; cardpresent=TR_MCA;
-      if (  ctemp != *tchanid)  /* Neither ISA nor MCA */
-        cardpresent=NOTOK;
-    }
-    if (cardpresent != NOTOK) { /* know presumed type, try rest of ID */
-      for (i=2,j=1; i<=46; i=i+2,j++) {
-        if ( (cd_chanid[i] & 0x0f) != tchanid[j]) {
-          cardpresent=NOTOK;   /* match failed, not TR card */
-          break;
-        }
-      }
-    }
-
-    /* If we have an ISA board check for the ISA P&P version, as it has
-       different IRQ settings */
-    if (cardpresent == TR_ISA && (*(AIPFID + t_mmio)==0x0e))
-       cardpresent=TR_ISAPNP;
-
-    if (cardpresent == NOTOK) { /* "channel_id" did not match, report */
-      if (ibmtr_debug_trace & TRC_INIT) {
-        DPRINTK("Channel ID string not found for PIOaddr: %4hx\n",
-                PIOaddr);
-        DPRINTK("Expected for ISA: ");  PrtChanID(pcchannelid,1);
-        DPRINTK("           found: ");  PrtChanID(cd_chanid,2);
-        DPRINTK("Expected for MCA: ");  PrtChanID(mcchannelid,1);
-      }
-      PIOaddr = 0;  /* all to know not found yet */
-      continue;
-    }
-
-   /* !!!! we could tighten validation by checking the HW Address
-      against the 1-s complement..  Move the get HW logic to here */
-
-  }
-
-  /*   The search loop has either completed with a presumed TR adapter
-       or none found.  Check situation ... march on if possible */
-
-  if (PIOaddr == 0) { /* failed to find a valid TR adapter */
-    if (ibmtr_debug_trace & TRC_INIT)
-         DPRINTK("Unable to assign adapter to device.\n");
-    return ENODEV;
-  }
-
-  /*?? Now, allocate some of the pl0 buffers for this driver.. */
-
-  if (!badti) {
-    ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
-    if (ti == NULL)
-          return -ENOMEM;
-  } else {
-    ti = badti; badti = NULL;
-  }/*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */
-
-  memset(ti,0,sizeof(struct tok_info));
-
-  ti->mmio= t_mmio;
-
-  dev->priv = ti;     /* this seems like the logical use of the
+       ti->mmio= t_mmio;
+
+       dev->priv = ti;     /* this seems like the logical use of the
                          field ... lets try some empirical tests
                          using the token-info structure -- that
                          should fit with out future hope of multiple
                          adapter support as well /dwm   */
 
-  switch (cardpresent) {
-    case TR_ISA:
-      if (intr==0) irq=9; /* irq2 really is irq9 */
-      if (intr==1) irq=3;
-      if (intr==2) irq=6;
-      if (intr==3) irq=7;
-      ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq);
-      ti->sram=NULL;
-#ifndef TR_NEWFORMAT
-      DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable);
+       switch (cardpresent) {
+             case TR_ISA:
+               if (intr==0) irq=9; /* irq2 really is irq9 */
+               if (intr==1) irq=3;
+               if (intr==2) irq=6;
+               if (intr==3) irq=7;
+               ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq);
+               ti->sram=0;
+#if !TR_NEWFORMAT
+               DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable);
 #endif
-      break;
-    case TR_MCA:
-      if (intr==0) irq=9;
-      if (intr==1) irq=3;
-      if (intr==2) irq=10;
-      if (intr==3) irq=11;
-      ti->global_int_enable=0;
-      ti->sram=(unsigned char *)((inb(PIOaddr+ADAPTRESETREL) & 0xfe)
-                                  << 12);
-      break;
-    case TR_ISAPNP:
-      if (intr==0) irq=9;
-      if (intr==1) irq=3;
-      if (intr==2) irq=10;
-      if (intr==3) irq=11;
-      while(!(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN));
-      ti->sram=(unsigned char *)((unsigned long)(*(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)) <<12);
-      ti->global_int_enable=PIOaddr+ADAPTINTREL;
-      break;
+               break;
+             case TR_MCA:
+               if (intr==0) irq=9;
+               if (intr==1) irq=3;
+               if (intr==2) irq=10;
+               if (intr==3) irq=11;
+               ti->global_int_enable=0;
+               ti->sram=((__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12);
+               break;
+             case TR_ISAPNP:
+               if (intr==0) irq=9;
+               if (intr==1) irq=3;
+               if (intr==2) irq=10;
+               if (intr==3) irq=11;
+               while(!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN));
+               ti->sram=((__u32)readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)<<12);
+               ti->global_int_enable=PIOaddr+ADAPTINTREL;
+               break;
       
-  }
-
-  if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
-    DPRINTK("irq=%d",irq);
-    if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */
-      DPRINTK(", ti->mmio=%p",ti->mmio);
-      printk(", segment=%02X",segment);
-    }
-    printk(".\n");
-  }
-
-  /* Get hw address of token ring card */
-#ifndef TR_NEWFORMAT 
-  DPRINTK("hw address: ");
+       }
+
+       if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
+               DPRINTK("irq=%d",irq);
+               if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */
+                       DPRINTK(", ti->mmio=%08X",ti->mmio);
+                       printk(", segment=%02X",segment);
+               }
+               printk(".\n");
+       }
+
+       /* Get hw address of token ring card */
+#if !TR_NEWFORMAT 
+       DPRINTK("hw address: ");
 #endif
-  j=0;
-  for (i=0; i<0x18; i=i+2) {
-    temp = *(char *)((ulong)AIP + (ulong)i + ti->mmio) & 0x0f; /* Tech ref states must do this */
-#ifndef TR_NEWFORMAT
-    printk("%1X",ti->hw_address[j]=temp);
+       j=0;
+       for (i=0; i<0x18; i=i+2) {
+               /* technical reference states to do this */
+               temp = readb(ti->mmio + AIP + i) & 0x0f;
+#if !TR_NEWFORMAT
+               printk("%1X",ti->hw_address[j]=temp);
 #else
-    ti->hw_address[j]=temp;
+               ti->hw_address[j]=temp;
 #endif
-    if(j&1)
-      dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);
-    ++j;
-  }
+               if(j&1)
+                       dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);
+               ++j;
+       }
 #ifndef TR_NEWFORMAT
-  printk("\n");
+       printk("\n");
 #endif
 
+       /* get Adapter type:  'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/
+       ti->adapter_type = readb(ti->mmio + AIPADAPTYPE);
 
-  /* get Adapter type:  'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/
-  ti->adapter_type = *(char *)(ti->mmio + AIPADAPTYPE);
-
-  /* get Data Rate:  F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */
-  ti->data_rate = *(char *)(ti->mmio + AIPDATARATE);
+       /* get Data Rate:  F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */
+       ti->data_rate = readb(ti->mmio + AIPDATARATE);
 
-  /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */
-  ti->token_release = *(char *)(ti->mmio + AIPEARLYTOKEN);
+       /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */
+       ti->token_release = readb(ti->mmio + AIPEARLYTOKEN);
 
-  /* How much shared RAM is on adapter ? */
-  ti->avail_shared_ram = get_sram_size(ti);
+       /* How much shared RAM is on adapter ? */
+       ti->avail_shared_ram = get_sram_size(ti);
 
-  /* We need to set or do a bunch of work here based on previous results.. */
-  /* Support paging?  What sizes?:  F=no, E=16k, D=32k, C=16 & 32k */
-  ti->shared_ram_paging = *(char *)(ti->mmio + AIPSHRAMPAGE);
+       /* We need to set or do a bunch of work here based on previous results.. */
+       /* Support paging?  What sizes?:  F=no, E=16k, D=32k, C=16 & 32k */
+       ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE);
 
   /* Available DHB  4Mb size:   F=2048, E=4096, D=4464 */
-  ti->dhb_size4mb = *(char *) (ti->mmio + AIP4MBDHB);
+       ti->dhb_size4mb = readb(ti->mmio + AIP4MBDHB);
 
-  /* Available DHB 16Mb size:  F=2048, E=4096, D=8192, C=16384, B=17960 */
-  ti->dhb_size16mb = *(char *)(ti->mmio + AIP16MBDHB);
+       /* Available DHB 16Mb size:  F=2048, E=4096, D=8192, C=16384, B=17960 */
+       ti->dhb_size16mb = readb(ti->mmio + AIP16MBDHB);
 
-#ifndef TR_NEWFORMAT
-  DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type,
-         ti->data_rate, ti->token_release, ti->avail_shared_ram/2, ti->shared_ram_paging,
-         ti->dhb_size4mb, ti->dhb_size16mb);
+#if !TR_NEWFORMAT
+       DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, "
+               "dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type,
+               ti->data_rate, ti->token_release, ti->avail_shared_ram/2, 
+               ti->shared_ram_paging, ti->dhb_size4mb, ti->dhb_size16mb);
 #endif
 
-  /* We must figure out how much shared memory space this adapter
-     will occupy so that if there are two adapters we can fit both
-     in.  Given a choice, we will limit this adapter to 32K.  The
-     maximum space will will use for two adapters is 64K so if the
-     adapter we are working on demands 64K (it also doesn't support
-     paging), then only one adapter can be supported.  */
-
-  /* determine how much of total RAM is mapped into PC space */
-  ti->mapped_ram_size=1<<(((*(unsigned char *)
-                       (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4);
-  ti->page_mask=0;
-  if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */
-    ti->mapped_ram_size = ti->avail_shared_ram;
-  } else {
+       /* We must figure out how much shared memory space this adapter
+          will occupy so that if there are two adapters we can fit both
+          in.  Given a choice, we will limit this adapter to 32K.  The
+          maximum space will will use for two adapters is 64K so if the
+          adapter we are working on demands 64K (it also doesn't support
+          paging), then only one adapter can be supported.  */
+       
+       /* determine how much of total RAM is mapped into PC space */
+       ti->mapped_ram_size=1<<(((readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)) >>2) +4);
+       ti->page_mask=0;
+       if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */
+               ti->mapped_ram_size = ti->avail_shared_ram;
+       } else {
 #ifdef ENABLE_PAGING
-    unsigned char pg_size;
+               unsigned char pg_size;
 #endif
 
-#ifndef TR_NEWFORMAT
-    DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2);
+#if !TR_NEWFORMAT
+               DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2);
 #endif
 #ifdef ENABLE_PAGING
-    switch(ti->shared_ram_paging) {
-      case 0xf:
-        break;
-      case 0xe:
-       ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
-       pg_size=32;   /* 16KB page size */
-       break;
-      case 0xd:
-       ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
-       pg_size=64;   /* 32KB page size */
-       break;
-      case 0xc:
-       ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
-       ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
-       DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n");
-       /* nb/dwm: I did this because RRR (3,2) bits are documented as
-        * R/O and I can't find how to select which page size
-        * Also, the above conditional statement sequence is invalid
-        *       as page_mask will always be set by the second stmt
-        */
-       badti=ti;
-       break;
-      default:
-       DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging);
-       badti=ti;    /* bail out if bad code */
-       break;
-    }
-    if(ti->page_mask) {
-      if(pg_size > ti->mapped_ram_size) {
-       DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",
-               pg_size, ti->mapped_ram_size);
-       ti->page_mask = 0;    /* reset paging */
-      } else {
-       ti->mapped_ram_size=ti->avail_shared_ram; /****** ?????????? *******/
-       DPRINTK("Shared RAM paging enabled. Page size : %uK\n",((ti->page_mask^ 0xff)+1)>>2);
-      }
-    }
-#else
-#endif
-  }
-
-  if (cardpresent==TR_ISA) { /* finish figuring the shared RAM address */
-    static unsigned char ram_bndry_mask[]={0xfe, 0xfc, 0xf8, 0xf0};
-    unsigned char new_base, rrr_32, chk_base, rbm;
-    rrr_32 = (*(unsigned char *)
-                       (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2;
-    rbm = ram_bndry_mask[rrr_32];
-    new_base = (Shared_Ram_Base + (~rbm)) & rbm; /* up to boundary */
-    chk_base = new_base + (ti->mapped_ram_size>>3);
-    if (chk_base > (IBMTR_SHARED_RAM_BASE+IBMTR_SHARED_RAM_SIZE)) {
-      DPRINTK("Shared RAM for this adapter (%05x) exceeds driver"
-              " limit (%05x), adapter not started.\n",
-              chk_base<<12, (IBMTR_SHARED_RAM_BASE+
-                              IBMTR_SHARED_RAM_SIZE)<<12);
-      badti=ti;
-    } else {  /* seems cool, record what we have figured out */
-      ti->sram_base = new_base;
-      Shared_Ram_Base = new_base;
-    }
-  }
-
-  /* dwm: irq and other final setup moved here so if we find other
-        unrecognized values OR shared ram conflicts, we can still
-        bail out in a rather benign fashion.    */
-
-  if (badti) return ENODEV;
-#ifndef TR_NEWFORMAT
-  DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
+       switch(ti->shared_ram_paging) {
+             case 0xf:
+               break;
+             case 0xe:
+               ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
+               pg_size=32;   /* 16KB page size */
+               break;
+             case 0xd:
+               ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
+               pg_size=64;   /* 32KB page size */
+               break;
+             case 0xc:
+               ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
+               ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
+               DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n");
+               /* nb/dwm: I did this because RRR (3,2) bits are documented as
+                  R/O and I can't find how to select which page size
+                  Also, the above conditional statement sequence is invalid
+                  as page_mask will always be set by the second stmt */
+               badti=ti;
+               break;
+             default:
+               DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging);
+               badti=ti;    /* bail out if bad code */
+               break;
+       }
+       if (ti->page_mask) {
+               if (pg_size > ti->mapped_ram_size) {
+                       DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",
+                               pg_size, ti->mapped_ram_size);
+                               ti->page_mask = 0;    /* reset paging */
+               } else {
+                       ti->mapped_ram_size=ti->avail_shared_ram; 
+                       DPRINTK("Shared RAM paging enabled. Page size : %uK\n",
+                               ((ti->page_mask^ 0xff)+1)>>2);
+               }
 #endif
+       }
+
+       /* finish figuring the shared RAM address */
+       if (cardpresent==TR_ISA) {
+               static unsigned char ram_bndry_mask[]={0xfe, 0xfc, 0xf8, 0xf0};
+               unsigned char new_base, rrr_32, chk_base, rbm;
+               rrr_32 = (readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2;
+               rbm = ram_bndry_mask[rrr_32];
+               new_base = (Shared_Ram_Base + (~rbm)) & rbm; /* up to boundary */
+               chk_base = new_base + (ti->mapped_ram_size>>3);
+               if (chk_base > (IBMTR_SHARED_RAM_BASE+IBMTR_SHARED_RAM_SIZE)) {
+                       DPRINTK("Shared RAM for this adapter (%05x) exceeds driver"
+                               " limit (%05x), adapter not started.\n",
+                               chk_base<<12, (IBMTR_SHARED_RAM_BASE+
+                                              IBMTR_SHARED_RAM_SIZE)<<12);
+                       badti=ti;
+               } else {  /* seems cool, record what we have figured out */
+                       ti->sram_base = new_base;
+                       Shared_Ram_Base = new_base;
+               }
+       }
 
-  if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) {
-    DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",irq);
-    badti = ti;    /*  keep track of unused tok_info */
-    return ENODEV;
-  }
-  irq2dev_map[irq]=dev;
+       /* dwm: irq and other final setup moved here so if we find other
+           unrecognized values OR shared ram conflicts, we can still
+           bail out in a rather benign fashion.    */
 
-  /*?? Now, allocate some of the PIO PORTs for this driver.. */
-  request_region(PIOaddr,TR_IO_EXTENT,"ibmtr");  /* record PIOaddr range
-                                                   as busy */
-#ifndef TR_NEWFORMAT
-   DPRINTK("%s",version); /* As we have passed card identification,
-                             let the world know we're here! */
-#else
-  printk("%s",version);
-  DPRINTK("%s %s found using irq %d, PIOaddr %4hx, %dK shared RAM.\n",
-       channel_def[cardpresent-1], adapter_def(ti->adapter_type), irq,
-        PIOaddr, ti->mapped_ram_size/2);
-  DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",
-       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-        dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+       if (badti) return ENODEV;
+#if !TR_NEWFORMAT
+       DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
 #endif
 
-  dev->base_addr=PIOaddr; /* set the value for device */
-
-  trdev_init(dev);
-  tok_init_card(dev);
+       if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) {
+               DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",irq);
+               badti = ti;    /*  keep track of unused tok_info */
+               return ENODEV;
+       }
+       irq2dev_map[irq]=dev;
+
+ /*?? Now, allocate some of the PIO PORTs for this driver.. */
+       request_region(PIOaddr,TR_IO_EXTENT,"ibmtr");  /* record PIOaddr range
+                                                                 as busy */
+#if !TR_NEWFORMAT
+       DPRINTK("%s",version); /* As we have passed card identification,
+                                  let the world know we're here! */
+#else
+       printk("%s",version);
+       DPRINTK("%s %s found using irq %d, PIOaddr %4hx, %dK shared RAM.\n",
+               channel_def[cardpresent-1], adapter_def(ti->adapter_type), irq,
+               PIOaddr, ti->mapped_ram_size/2);
+       DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",
+               dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+               dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+#endif
 
-  return 0;  /* Return 0 to indicate we have found a Token Ring card. */
+       dev->base_addr=PIOaddr; /* set the value for device */
+       
+       dev->open=tok_open;
+       dev->stop=tok_close;
+       dev->hard_start_xmit=tok_send_packet;
+       dev->get_stats = NULL;
+       dev->get_stats = tok_get_stats;
+       dev->set_multicast_list = NULL;
+       tr_setup(dev);
+       tok_init_card((unsigned long)dev);
+       
+       return 0;  /* Return 0 to indicate we have found a Token Ring card. */
 }
 
 /* query the adapter for the size of shared RAM  */
 
-unsigned char get_sram_size(struct tok_info *adapt_info) {
-
+unsigned char get_sram_size(struct tok_info *adapt_info)
+{
+               
        unsigned char avail_sram_code;
        static unsigned char size_code[]={ 0,16,32,64,127,128 };
-
-           /*  Adapter gives
-                'F' -- use RRR bits 3,2
-                'E' -- 8kb   'D' -- 16kb
-                'C' -- 32kb  'A' -- 64KB
-                'B' - 64KB less 512 bytes at top
-                      (WARNING ... must zero top bytes in INIT */
-
-       avail_sram_code=0xf-*(adapt_info->mmio + AIPAVAILSHRAM);
-       if(avail_sram_code)
+       
+       /* Adapter gives
+          'F' -- use RRR bits 3,2
+          'E' -- 8kb   'D' -- 16kb
+          'C' -- 32kb  'A' -- 64KB
+          'B' - 64KB less 512 bytes at top
+          (WARNING ... must zero top bytes in INIT */
+
+       avail_sram_code=0xf-readb(adapt_info->mmio + AIPAVAILSHRAM);
+       if (avail_sram_code) 
                return size_code[avail_sram_code];
        else  /* for code 'F', must compute size from RRR(3,2) bits */
-
-               return 1<<(((*(unsigned char *)
-              (adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4);
+               return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);
 }
 
-
-int trdev_init(struct device *dev)
+static int tok_open(struct device *dev) 
 {
-  struct tok_info *ti=(struct tok_info *)dev->priv;
-
-  ti->open_status=CLOSED;
-
-  dev->init=tok_init_card;
-  dev->open=tok_open;
-  dev->stop=tok_close;
-  dev->hard_start_xmit=tok_send_packet;
-  dev->get_stats = NULL;
-  dev->get_stats = tok_get_stats;
-  dev->set_multicast_list = NULL;
-  tr_setup(dev);
-
-  return 0;
-}
-
-
-static int tok_open(struct device *dev) {
-
-   struct tok_info *ti=(struct tok_info *)dev->priv;
-
-   if(ti->open_status==CLOSED) {
-      tok_init_card(dev);
-   }
-
-       if(ti->open_status==IN_PROGRESS) {
-      sleep_on(&ti->wait_for_reset);
-       }
+       struct tok_info *ti=(struct tok_info *)dev->priv;
+       
+       if (ti->open_status==CLOSED) tok_init_card((unsigned long)dev);
+       
+       if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
+       
+       if (ti->open_status==SUCCES) {
+               dev->tbusy=0;
+               dev->interrupt=0;
+               dev->start=1;
+               /* NEED to see smem size *AND* reset high 512 bytes if needed */
+               
+               MOD_INC_USE_COUNT;
+               
+               return 0;
+       } else return -EAGAIN;
        
-   if(ti->open_status==SUCCES) {
-      dev->tbusy=0;
-      dev->interrupt=0;
-      dev->start=1;
-      /*  NEED to see smem size *AND* reset high 512 bytes if
-          needed */
-
-      MOD_INC_USE_COUNT;
-
-      return 0;
-   }
-       else 
-      return -EAGAIN;
-
 }
 
-static int tok_close(struct device *dev) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-
-       struct srb_close_adapter *close_adapter=(struct srb_close_adapter *)ti->srb;
-
-       close_adapter->command=DIR_CLOSE_ADAPTER;
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
-
-   ti->open_status=CLOSED;
-
+static int tok_close(struct device *dev) 
+{
+       
+       struct tok_info *ti=(struct tok_info *) dev->priv;
+       
+       writeb(DIR_CLOSE_ADAPTER, 
+              ti->srb + offsetof(struct srb_close_adapter, command));
+       writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+       
+       ti->open_status=CLOSED;
+       
        sleep_on(&ti->wait_for_tok_int);                
-
-       if(close_adapter->ret_code)
-               DPRINTK("close adapter failed: %02X\n",close_adapter->ret_code);
        
+       if (readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)))
+               DPRINTK("close adapter failed: %02X\n",
+                       (int)readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));
+               
        MOD_DEC_USE_COUNT;
-
+       
        return 0;
 }
 
 void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 {
-
        unsigned char status;
-  struct tok_info *ti;
-/*   int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); */
-   struct device *dev = (struct device *)(irq2dev_map[irq]);
-#if 0
-   DPRINTK("Int from tok_driver, dev : %p\n",dev);
-#endif
-  ti=(struct tok_info *) dev->priv;
-
-  switch (ti->do_tok_int) {
-    case NOT_FIRST:
-
-        /*  Begin the regular interrupt handler HERE inline to avoid
-            the extra levels of logic and call depth for the
-            original solution.   */
-
-
-       dev->interrupt=1;
-
-       /* Disable interrupts till processing is finished */
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE);
-
-       /* Reset interrupt for ISA boards */
-       if(ti->global_int_enable)
-               outb(0,ti->global_int_enable);
+       struct tok_info *ti;
+       struct device *dev = (struct device *)(irq2dev_map[irq]);
        
-       status=*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
-
-#ifdef PCMCIA
-       /* Check if the PCMCIA card was pulled. */
-       if (status == 0xFF)
-       {
-          DPRINTK("PCMCIA card removed.\n");
-          dev->interrupt = 0;
-          return;
-       }
-
-       /* Check ISRP EVEN too. */
-       if ( *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF)
-       {
-          DPRINTK("PCMCIA card removed.\n");
-          dev->interrupt = 0;
-          return;
-       }
+#if TR_VERBOSE
+       DPRINTK("Int from tok_driver, dev : %p\n",dev);
 #endif
-
-       if(status & ADAP_CHK_INT) {
-               int i;
-                unsigned char *check_reason=ti->sram + ntohs(*(unsigned short *)(ti->mmio + ACA_OFFSET + ACA_RW +WWCR_EVEN));
-
-               DPRINTK("adapter check interrupt\n");
-
-               DPRINTK("8 reason bytes follow: ");
-               for(i=0;i<      8;i++,check_reason++)
-                       printk("%02X ",*check_reason);  
-               printk("\n");
-
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=(~ADAP_CHK_INT);
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN)=INT_ENABLE;
-               dev->interrupt=0;
-       }       
-
-       else if((*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)) & (TCR_INT + ERR_INT + ACCESS_INT)) {
-
-               DPRINTK("adapter error: ISRP_EVEN : %02x\n",
-                               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
+       
+       ti=(struct tok_info *) dev->priv;
+       
+       switch (ti->do_tok_int) {
+               
+             case NOT_FIRST:
+               
+               /*  Begin the regular interrupt handler HERE inline to avoid
+                   the extra levels of logic and call depth for the
+                   original solution.   */
+               
+               dev->interrupt=1;
+               
+               /* Disable interrupts till processing is finished */
+               writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+
+               /* Reset interrupt for ISA boards */
+               if (ti->global_int_enable)
+                       outb(0, ti->global_int_enable);
+               
+               status=readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
+               
+               if (status & ADAP_CHK_INT) {
+                       
+                       int i;
+                       __u32 check_reason;
+
+                       check_reason=ti->mmio + ntohs(readw(ti->mmio + ACA_OFFSET + ACA_RW +WWCR_EVEN));
+                       
+                       DPRINTK("Adapter check interrupt\n");
+                       DPRINTK("8 reason bytes follow: ");
+                       for(i=0; i<8; i++, check_reason++)
+                               printk("%02X ", (int)readb(check_reason));      
+                       printk("\n");
+                       
+                       writeb((~ADAP_CHK_INT), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+                       writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
+                       dev->interrupt=0;
+                       
+               }       else if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)
+                                & (TCR_INT | ERR_INT | ACCESS_INT)) {
+                       
+                       DPRINTK("adapter error: ISRP_EVEN : %02x\n", 
+                               (int)readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
+                       writeb(~(TCR_INT | ERR_INT | ACCESS_INT),
+                              ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+                       writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
+                       dev->interrupt=0;
+
+               } else if (status 
+                          & (SRB_RESP_INT | ASB_FREE_INT | ARB_CMD_INT | SSB_RESP_INT)) {
+                       /* SRB, ASB, ARB or SSB response */
+                       
+                       if (status & SRB_RESP_INT) { /* SRB response */
                                
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(TCR_INT + ERR_INT + ACCESS_INT);
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN)=INT_ENABLE;
-               dev->interrupt=0;
-       }
+                               switch(readb(ti->srb)) { /* SRB command check */
                                        
-       else if(status & (SRB_RESP_INT + ASB_FREE_INT + ARB_CMD_INT + SSB_RESP_INT)) {
-
-               if(status & SRB_RESP_INT) {
-                       switch(*ti->srb) {
-                               case XMIT_DIR_FRAME: {
-                                       struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb);
-                                       if(xmit->ret_code!=0xff) {
-                                               DPRINTK("error on xmit_dir_frame request: %02X\n",xmit->ret_code);
-                                               if(ti->current_skb) {
-                                                       dev_kfree_skb(ti->current_skb, FREE_WRITE);
-                                                       ti->current_skb=NULL;
-                                               }
-                                               dev->tbusy=0;
-                                       }                                                                                               
-                               }
-                               break;
-                               
-                               case XMIT_UI_FRAME: {
-                                       struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb);
-                                       if(xmit->ret_code!=0xff) {
-                                               DPRINTK("error on xmit_ui_frame request: %02X\n",xmit->ret_code);
-                                               if(ti->current_skb) {
-                                                       dev_kfree_skb(ti->current_skb, FREE_WRITE);
-                                                       ti->current_skb=NULL;
-                                               }
-                                               dev->tbusy=0;
-                                       }                                                                                               
-                               }
-                               break;
-       
-                               case DIR_OPEN_ADAPTER: {
-                                       struct srb_open_response *open_response=(struct srb_open_response *)(ti->init_srb);
-
-                                       ti->srb=ti->sram+ntohs(open_response->srb_addr);
-                                       ti->ssb=ti->sram+ntohs(open_response->ssb_addr);
-                                       ti->arb=ti->sram+ntohs(open_response->arb_addr);
-                                       ti->asb=ti->sram+ntohs(open_response->asb_addr);
-                                       ti->current_skb=NULL;
-
-                                       if(open_response->ret_code==7) {
-                                               if(!ti->auto_ringspeedsave && (open_response->error_code==0x24)) {
-                                                       DPRINTK("open failed: Adapter speed must match ring speed if Automatic Ring Speed Save is disabled\n");
-                                                       ti->open_status=FAILURE;
-                                                       wake_up(&ti->wait_for_reset);
-                                               }
-                                               else if(open_response->error_code==0x24) 
-                                                       DPRINTK("retrying open to adjust to ring speed\n");
-
-                                               else if((open_response->error_code==0x2d) && ti->auto_ringspeedsave)
-                                                       DPRINTK("No signal detected for Auto Speed Detection\n");
-                                               else DPRINTK("Unrecoverable error: error code = %02X\n",open_response->error_code);
-                                       }
-                                       else if(!open_response->ret_code) {
-#ifndef TR_NEWFORMAT
-                                               DPRINTK("board opened...\n");
+                                     case XMIT_DIR_FRAME: {
+                                             unsigned char xmit_ret_code;
+                                             
+                                             xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
+                                             if (xmit_ret_code != 0xff) {
+                                                     DPRINTK("error on xmit_dir_frame request: %02X\n", 
+                                                             xmit_ret_code);
+                                                     if (ti->current_skb) {
+                                                             dev_kfree_skb(ti->current_skb, FREE_WRITE);
+                                                             ti->current_skb=NULL;
+                                                     }
+                                                     dev->tbusy=0;
+                                             }
+                                     }
+                                     break;
+                                     
+                                     case XMIT_UI_FRAME: {
+                                             unsigned char xmit_ret_code;
+                                             
+                                             xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
+                                             if (xmit_ret_code != 0xff) {
+                                                     DPRINTK("error on xmit_ui_frame request: %02X\n",
+                                                             xmit_ret_code);
+                                                     if (ti->current_skb) {
+                                                             dev_kfree_skb(ti->current_skb, FREE_WRITE);
+                                                             ti->current_skb=NULL;
+                                                     }
+                                                     dev->tbusy=0;
+                                             }
+                                     }
+                                     break;
+                                     
+                                     case DIR_OPEN_ADAPTER: {
+                                             unsigned char open_ret_code;
+                                             __u16 open_error_code;
+                                             
+                                             ti->srb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr)));
+                                             ti->ssb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr)));
+                                             ti->arb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr)));
+                                             ti->asb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr)));
+                                             ti->current_skb=NULL;
+                                             
+                                             open_ret_code = readb(ti->init_srb +offsetof(struct srb_open_response, ret_code));
+                                             open_error_code = readw(ti->init_srb +offsetof(struct srb_open_response, error_code));
+
+                                             if (open_ret_code==7) {
+                                                     
+                                                     if (!ti->auto_ringspeedsave && (open_error_code==0x24)) {
+                                                             DPRINTK("open failed: Adapter speed must match ring "
+                                                                     "speed if Automatic Ring Speed Save is disabled\n");
+                                                             ti->open_status=FAILURE;
+                                                             wake_up(&ti->wait_for_reset);
+                                                     } else if (open_error_code==0x24)
+                                                             DPRINTK("retrying open to adjust to ring speed\n");
+                                                     else if ((open_error_code==0x2d) && ti->auto_ringspeedsave)
+                                                             DPRINTK("No signal detected for Auto Speed Detection\n");
+                                                     else DPRINTK("Unrecoverable error: error code = %02X\n", 
+                                                                  open_error_code);
+                                                     
+                                             } else if (!open_ret_code) {
+#if !TR_NEWFORMAT
+                                                     DPRINTK("board opened...\n");
 #else
-                                               DPRINTK("Adapter initialized and opened.\n");
+                                                     DPRINTK("Adapter initialized and opened.\n");
 #endif
-                                               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
-                                               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
-                                               open_sap(EXTENDED_SAP,dev);
-/* YdW probably hates me */
-                                               goto skip_reset;
-                                       }
-                                       else {  
-                                               DPRINTK("open failed: ret_code = %02X, retrying\n",open_response->ret_code);
-                                       }
-                                       if(ti->open_status!=FAILURE) {
-                                               tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
-                                               tr_timer.data=(unsigned long)dev;
-                                               tr_timer.next=tr_timer.prev=NULL;
-                                               add_timer(&tr_timer);
-                                       }
-                               }
-                               break;
-
-                               case DIR_CLOSE_ADAPTER:
+                                                     writeb(~(SRB_RESP_INT), 
+                                                            ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+                                                     writeb(~(CMD_IN_SRB), 
+                                                            ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
+                                                     open_sap(EXTENDED_SAP,dev);
+                                                     
+                                                     /* YdW probably hates me */
+                                                     goto skip_reset;
+                                             } else
+                                                     DPRINTK("open failed: ret_code = %02X, retrying\n",
+                                                             open_ret_code);
+                                             
+                                             if (ti->open_status != FAILURE) {
+                                                     tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
+                                                     tr_timer.data=(unsigned long)dev;
+                                                     tr_timer.next=tr_timer.prev=NULL;
+                                                     add_timer(&tr_timer);
+                                             }
+                                             
+                                     }
+                                     break;
+                                     
+                                     case DIR_CLOSE_ADAPTER:
                                        wake_up(&ti->wait_for_tok_int);
                                        break;
-                               case DLC_OPEN_SAP: {
-                                       struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb;
-                                       if(open_sap->ret_code) {
-                                               DPRINTK("open_sap failed: ret_code = %02X,retrying\n",open_sap->ret_code);
+                                       
+                                     case DLC_OPEN_SAP:
+                                       if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {
+                                               DPRINTK("open_sap failed: ret_code = %02X,retrying\n",
+                                                       (int)readb(ti->srb+offsetof(struct dlc_open_sap, ret_code)));
                                                tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
                                                tr_timer.data=(unsigned long)dev;
                                                tr_timer.next=tr_timer.prev=NULL;
                                                add_timer(&tr_timer);
-                                       }
-                                       else {
-                                               ti->exsap_station_id=open_sap->station_id;
+                                       } else {
+                                               ti->exsap_station_id=
+                                                       readw(ti->srb+offsetof(struct dlc_open_sap, station_id));
                                                ti->open_status=SUCCES; /* TR adapter is now available */
                                                wake_up(&ti->wait_for_reset);
                                        }
-                               }
-                               break;
-
-                               case DIR_INTERRUPT:
-                               case DIR_MOD_OPEN_PARAMS:       
-                               case DIR_SET_GRP_ADDR:
-                               case DIR_SET_FUNC_ADDR:
-                               case DLC_CLOSE_SAP: {
-                                       struct srb_interrupt *intr=(struct srb_interrupt *)(ti->srb);
-                                       if(intr->ret_code)
-                                               DPRINTK("error on %02X: %02X\n",intr->command,intr->ret_code);  
-                               }
-                               break;
-
-                               case DIR_READ_LOG: {
-                                       struct srb_read_log *read_log=(struct srb_read_log *)(ti->srb);
-                                       if(read_log->ret_code)
-                                               DPRINTK("error on dir_read_log: %02X\n",read_log->ret_code);
-                                       else {
-                                               DPRINTK("Line errors %02X, Internal errors %02X, Burst errors %02X\n",
-                          read_log->line_errors,read_log->internal_errors,read_log->burst_errors);
-                                               DPRINTK("A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n",
-                          read_log->A_C_errors,read_log->abort_delimiters,read_log->lost_frames);
-                                               DPRINTK("Receive congestion count %02X, Frame copied errors %02X, Frequency errors %02X\n",
-                          read_log->recv_congest_count,read_log->frame_copied_errors,read_log->frequency_errors);
-                                               DPRINTK("Token errors %02X\n",read_log->token_errors);
-                                       }
+                                       break;
+                                       
+                                     case DIR_INTERRUPT:
+                                     case DIR_MOD_OPEN_PARAMS: 
+                                     case DIR_SET_GRP_ADDR:
+                                     case DIR_SET_FUNC_ADDR:
+                                     case DLC_CLOSE_SAP:
+                                       if (readb(ti->srb+offsetof(struct srb_interrupt, ret_code)))
+                                               DPRINTK("error on %02X: %02X\n",
+                                                       (int)readb(ti->srb+offsetof(struct srb_interrupt, command)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_interrupt, ret_code)));
+                                       break;
+                                       
+                                     case DIR_READ_LOG:
+                                       if (readb(ti->srb+offsetof(struct srb_read_log, ret_code)))
+                                               DPRINTK("error on dir_read_log: %02X\n",
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, ret_code)));
+                                       else
+                                               DPRINTK(
+                                                       "Line errors %02X, Internal errors %02X, Burst errors %02X\n"
+                                                       "A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n"
+                                                       "Receive congestion count %02X, Frame copied errors %02X\n"
+                                                       "Frequency errors %02X, Token errors %02X\n",
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                                                   line_errors)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                                                   internal_errors)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                                                   burst_errors)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, A_C_errors)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                                                   abort_delimiters)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                                                   lost_frames)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                                                                   recv_congest_count)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                                                   frame_copied_errors)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                                                   frequency_errors)),
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                                                                   token_errors)));
                                        dev->tbusy=0;
-                               }
-                               break;
-
-                               default:
-                                       DPRINTK("Unknown command %02X encountered\n",*(ti->srb));
-                       }
-                       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
-                       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
-skip_reset:
-               }
-
-               if(status & ASB_FREE_INT) {
-                       switch(*ti->asb) {
-                               case REC_DATA:
-                               case XMIT_UI_FRAME:
-                               case XMIT_DIR_FRAME:
-                                       if(*(ti->asb+2)!=0xff)
-                                               DPRINTK("ASB error %02X in cmd %02X\n", *(ti->asb+2),*(ti->asb));
                                        break;
-                               default:
-                                       DPRINTK("unknown command in asb %02X\n",*ti->asb);
-                       }
-                       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ASB_FREE_INT);
-               }
-
-               if(status & ARB_CMD_INT) {
-                       switch(*ti->arb) {
-                               case DLC_STATUS: {
-                                       struct arb_dlc_status *dlc_status=(struct arb_dlc_status *)(ti->arb);                   
-                                       DPRINTK("DLC_STATUS new status: %02X on station %02X\n",ntohs(dlc_status->status),ntohs(dlc_status->station_id));
-                               }
-                               break;
-
-                               case REC_DATA:
+                                       
+                                     default:
+                                       DPRINTK("Unknown command %02X encountered\n",
+                                               (int)readb(ti->srb));
+                                       
+                               } /* SRB command check */
+                               
+                               writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
+                               writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+                               
+                         skip_reset:
+                       } /* SRB response */
+                       
+                       if (status & ASB_FREE_INT) { /* ASB response */
+                               
+                               switch(readb(ti->asb)) { /* ASB command check */
+                                       
+                                     case REC_DATA:
+                                     case XMIT_UI_FRAME:
+                                     case XMIT_DIR_FRAME:
+                                       if (readb(ti->asb+2)!=0xff) /* checks ret_code */
+                                               DPRINTK("ASB error %02X in cmd %02X\n", 
+                                                       (int)readb(ti->asb+2), 
+                                                                       (int)readb(ti->asb));
+                                       break;
+                                       
+                                     default:
+                                       DPRINTK("unknown command in asb %02X\n",
+                                               (int)readb(ti->asb));
+                                       
+                               } /* ASB command check */
+                               
+                               writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+                               
+                       } /* ASB response */
+                       
+                       if (status & ARB_CMD_INT) { /* ARB response */
+                               
+                               switch (readb(ti->arb)) { /* ARB command check */
+                                       
+                                     case DLC_STATUS:
+                                       DPRINTK("DLC_STATUS new status: %02X on station %02X\n", 
+                                               ntohs(readw(ti->arb + offsetof(struct arb_dlc_status, status))),
+                                               ntohs(readw(ti->arb 
+                                                                           +offsetof(struct arb_dlc_status, station_id))));
+                                       break;
+                                       
+                                     case REC_DATA:
                                        tr_rx(dev);
                                        break;
-
-                               case RING_STAT_CHANGE: {
-                                       struct arb_ring_stat_change *ring_stat_change=(struct arb_ring_stat_change *)(ti->arb);
-                                       unsigned short ring_status=ntohs(ring_stat_change->ring_status);
-
-                                       if(ring_status & (SIGNAL_LOSS + LOBE_FAULT)) {
-                                               DPRINTK("Signal loss/Lobe fault\n");
-                                               DPRINTK("We try to reopen the adapter.\n");     
-                                               tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
-                                               tr_timer.data=(unsigned long)dev;
-                                               tr_timer.next=tr_timer.prev=NULL;
-                                               add_timer(&tr_timer);
-                                       } else if (ring_status & (HARD_ERROR + XMIT_BEACON +
-                                                                 AUTO_REMOVAL + REMOVE_RECV + RING_RECOVER))
-                                               DPRINTK("New ring status: %02X\n",ring_status);
-
-                                       if(ring_status & LOG_OVERFLOW) {
-                                               *(ti->srb)=DIR_READ_LOG;
-                                               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
-                                               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
-                                               dev->tbusy=1; /* really srb busy... */
-                                       }
-                               }
-                               break;
-
-                               case XMIT_DATA_REQ:
+                                       
+                                     case RING_STAT_CHANGE: {
+                                             unsigned short ring_status;
+                                             
+                                             ring_status=ntohs(readw(ti->arb
+                                                                     +offsetof(struct arb_ring_stat_change, ring_status)));
+                                             
+                                             if (ring_status & (SIGNAL_LOSS | LOBE_FAULT)) {
+                                                     
+                                                     DPRINTK("Signal loss/Lobe fault\n");
+                                                     DPRINTK("We try to reopen the adapter.\n");       
+                                                     tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
+                                                     tr_timer.data=(unsigned long)dev;
+                                                     tr_timer.next=tr_timer.prev=NULL;
+                                                     add_timer(&tr_timer);
+                                                     
+                                             } else if (ring_status & (HARD_ERROR | XMIT_BEACON 
+                                                                                       | AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))
+                                                     DPRINTK("New ring status: %02X\n", ring_status);
+                                             
+                                             if (ring_status & LOG_OVERFLOW) {
+                                                     
+                                                     writeb(DIR_READ_LOG, ti->srb);
+                                                     writeb(INT_ENABLE, 
+                                                            ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+                                                     writeb(CMD_IN_SRB, 
+                                                            ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+                                                     dev->tbusy=1; /* really srb busy... */
+                                                     
+                                             }
+                                     }
+                                     break;
+                                     
+                                     case XMIT_DATA_REQ:
                                        tr_tx(dev);
                                        break;
-
-                               default:
-                                       DPRINTK("Unknown command %02X in arb\n",*(ti->arb));
+                                       
+                                     default:
+                                       DPRINTK("Unknown command %02X in arb\n", 
+                                               (int)readb(ti->arb));
                                        break;
-                       }
-                       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ARB_CMD_INT);
-                       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=ARB_FREE;
-               }
-
-               if(status & SSB_RESP_INT) {
-                       switch(*ti->ssb) {
-                               case XMIT_DIR_FRAME:
-                               case XMIT_UI_FRAME:
-                                       if(*(ti->ssb+2))
-                                               DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",*(ti->ssb+2),*(ti->ssb+6));               
-                                       else
-                                               ti->tr_stats.tx_packets++;
+                                       
+                               } /* ARB command check */
+                               
+                               writeb(~ARB_CMD_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+                               writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+                               
+                       } /* ARB response */
+                       
+                       if (status & SSB_RESP_INT) { /* SSB response */
+                                               
+                               switch (readb(ti->ssb)) { /* SSB command check */
+                                       
+                                     case XMIT_DIR_FRAME:
+                                     case XMIT_UI_FRAME:
+                                       if (readb(ti->ssb+2)) /* checks ret_code */
+                                               DPRINTK("xmit ret_code: %02X xmit error code: %02X\n", 
+                                                       (int)readb(ti->ssb+2), (int)readb(ti->ssb+6));          
+                                       else ti->tr_stats.tx_packets++;
                                        break;
+                                       
+                                     case XMIT_XID_CMD:
+                                       DPRINTK("xmit xid ret_code: %02X\n", (int)readb(ti->ssb+2));
+                                       
+                                     default:
+                                       DPRINTK("Unknown command %02X in ssb\n", (int)readb(ti->ssb));
+                                       
+                               } /* SSB command check */
                                
-                               case XMIT_XID_CMD:
-                                       DPRINTK("xmit xid ret_code: %02X\n",*(ti->ssb+2));
+                               writeb(~SSB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+                               writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
                                
-                               default:
-                                       DPRINTK("Unknown command %02X in ssb\n",*(ti->ssb));
-                       }
-                       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SSB_RESP_INT);
-                       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=SSB_FREE;
-               }
-       }       
-
-       dev->interrupt=0;
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
-
-       return;
+                       } /* SSB response */
+                       
+               }        /* SRB, ARB, ASB or SSB response */
+               
+               dev->interrupt=0;
+               writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+               break;
 
-      break;
-    case FIRST_INT:
-      initial_tok_int(dev);
-      break;
-    default:
-      DPRINTK("Unexpected interrupt from tr adapter\n");
-  }
+             case FIRST_INT:
+               initial_tok_int(dev);
+               break;
+               
+             default:
+               DPRINTK("Unexpected interrupt from tr adapter\n");
 
+       }
 }
 
-static void initial_tok_int(struct device *dev) {
-
-#ifndef TR_NEWFORMAT
-  int i;
-#endif
-  unsigned char *encoded_addr;
-  struct tok_info *ti;
-
-  ti=(struct tok_info *) dev->priv;
+static void initial_tok_int(struct device *dev) 
+{
 
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE);
+       __u32 encoded_addr;
+       __u32 hw_encoded_addr;
+       struct tok_info *ti;
+       
+       ti=(struct tok_info *) dev->priv;
+       
+       writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
        
        /* Reset interrupt for ISA boards */
-       if(ti->global_int_enable)
-               outb(0,ti->global_int_enable);
-
+       if (ti->global_int_enable) outb(0,ti->global_int_enable);
+       
        ti->do_tok_int=NOT_FIRST;
-
+       
 #ifndef TR_NEWFORMAT
        DPRINTK("Initial tok int received\n");
 #endif
 
-       if(!ti->sram) {  /* we assign the address for ISA devices */
-                       /* set RRR even to D000 for shared ram address */
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)=
-                                      ti->sram_base;
-               ti->sram=(char *)(ti->sram_base << 12);
+       /* we assign the address for ISA devices; set RRR even to D000 for 
+          shared RAM address */
+       if(!ti->sram) {
+               writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);
+               ti->sram=((__u32)ti->sram_base << 12);
+       }
+       ti->init_srb=ti->sram
+               +ntohs((unsigned short)readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN));
+       SET_PAGE(ntohs((unsigned short)readw(ti->mmio+ACA_OFFSET + WRBR_EVEN)));
+       
+#if TR_VERBOSE
+       {
+               int i;
+               DPRINTK("init_srb(%p):", ti->init_srb);
+               for (i=0;i<17;i++) printk("%02X ", (int)readb(ti->init_srb+i));
+               printk("\n");
        }
-       ti->init_srb=ti->sram+ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN));
-       SET_PAGE(ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN)));
-
-#if 0
-       DPRINTK("init_srb(%p):",ti->init_srb);
-       for(i=0;i<17;i++)
-               printk("%02X ",*(ti->init_srb+i));
-       printk("\n");
 #endif
-
-#ifndef TR_NEWFORMAT           
-       DPRINTK("srb_init_response->encoded_address: %04X\n",((struct srb_init_response *)ti->init_srb)->encoded_address);
-       DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address));
+       
+       hw_encoded_addr = readw(ti->init_srb 
+                               + offsetof(struct srb_init_response, encoded_address));
+       
+#if !TR_NEWFORMAT              
+       DPRINTK("srb_init_response->encoded_address: %04X\n", hw_encoded_addr);
+       DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",
+               ntohs(hw_encoded_addr));
 #endif
-       encoded_addr=(unsigned char *)(ti->sram + ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address));
-
-#ifndef TR_NEWFORMAT
-       DPRINTK("encoded addr (%04X,%04X,%p): ",
-                       ((struct srb_init_response *)ti->init_srb)->encoded_address,
-                       ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address),     
-                       encoded_addr);
+       
+       encoded_addr=(ti->sram + ntohs(hw_encoded_addr));
+       
+#if !TR_NEWFORMAT
+       DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr, 
+               ntohs(hw_encoded_addr), encoded_addr);
 #else
-       DPRINTK("Initial interrupt : shared RAM located at %p.\n", encoded_addr);
-#endif
-       ti->auto_ringspeedsave=((struct srb_init_response *)ti->init_srb)->init_status_2 & 0x4 ? TRUE : FALSE;
-
-#ifndef TR_NEWFORMAT
-       for(i=0;i<TR_ALEN;i++)
-               printk("%02X%s",dev->dev_addr[i]=encoded_addr[i],(i==TR_ALEN-1) ? "" : ":" );
+       DPRINTK("Initial interrupt : shared RAM located at %08X.\n", encoded_addr);
+#endif 
+       
+       ti->auto_ringspeedsave=readb(ti->init_srb
+                                    +offsetof(struct srb_init_response, init_status_2)) & 0x4 ? TRUE : FALSE;
+       
+#if !TR_NEWFORMAT
+       for(i=0;i<TR_ALEN;i++) {
+               dev->dev_addr[i]=readb(encoded_addr + i);
+               printk("%02X%s", dev->dev_addr[i], (i==TR_ALEN-1) ? "" : ":" );
+       }
        printk("\n");
 #endif
-
+       
        tok_open_adapter((unsigned long)dev);
-
 }
 
-static int tok_init_card(struct device *dev) {
-
-   struct tok_info *ti;
+static void tok_init_card(unsigned long dev_addr) 
+{
+       struct tok_info *ti;
        short PIOaddr;
-        PIOaddr = dev->base_addr;
-        ti=(struct tok_info *) dev->priv;
-
-      /* Special processing for first interrupt after reset */
+       int i;
+       struct device *dev=(struct device *)dev_addr;
+       PIOaddr = dev->base_addr;
+       ti=(struct tok_info *) dev->priv;
+       
+       /* Special processing for first interrupt after reset */
        ti->do_tok_int=FIRST_INT;
-
+       
        /* Reset adapter */
-
        dev->tbusy=1; /* nothing can be done before reset and open completed */
-
+       
 #ifdef ENABLE_PAGING
-       if(ti->page_mask) {
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)=SRPR_ENABLE_PAGING;
-       }
+       if(ti->page_mask)
+               writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
 #endif
-
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(INT_ENABLE);
-#ifndef TR_NEWFORMAT
+       
+       writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
+       
+#if !TR_NEWFORMAT
        DPRINTK("resetting card\n");
 #endif
-       outb(0,PIOaddr+ADAPTRESET);
-        udelay(50000);
+       
+       outb(0, PIOaddr+ADAPTRESET);
+       for (i=jiffies+TR_RESET_INTERVAL; jiffies<=i;); /* wait 50ms */
        outb(0,PIOaddr+ADAPTRESETREL);
-#ifndef TR_NEWFORMAT
+       
+#if !TR_NEWFORMAT
        DPRINTK("card reset\n");
 #endif
-
-        ti->open_status=IN_PROGRESS;
-
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
-        return 0;
+       
+       ti->open_status=IN_PROGRESS;
+       writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+               
 }
 
-static void open_sap(unsigned char type,struct device *dev) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-       struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb;
-
+static void open_sap(unsigned char type,struct device *dev) 
+{
+       int i;
+       struct tok_info *ti=(struct tok_info *) dev->priv;
+       
        SET_PAGE(ti->srb);
-       memset(open_sap,0,sizeof(struct dlc_open_sap));
-
-       open_sap->command=DLC_OPEN_SAP;
-       open_sap->max_i_field=htons(MAX_I_FIELD);
-       open_sap->sap_options=SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY;
-       open_sap->station_count=SAP_OPEN_STATION_CNT;
-       open_sap->sap_value=type;
-
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
+       for (i=0; i<sizeof(struct dlc_open_sap); i++)
+               writeb(0, ti->srb+i);
+       
+       writeb(DLC_OPEN_SAP, ti->srb + offsetof(struct dlc_open_sap, command));
+       writew(htons(MAX_I_FIELD), 
+              ti->srb + offsetof(struct dlc_open_sap, max_i_field));
+       writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, 
+              ti->srb + offsetof(struct dlc_open_sap, sap_options));
+       writeb(SAP_OPEN_STATION_CNT, 
+              ti->srb + offsetof(struct dlc_open_sap, station_count));
+       writeb(type, ti->srb + offsetof(struct dlc_open_sap, sap_value));
+       
+       writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 
 }
 
-void tok_open_adapter(unsigned long dev_addr) {
-
+void tok_open_adapter(unsigned long dev_addr) 
+{
+       
        struct device *dev=(struct device *)dev_addr;
-       struct dir_open_adapter *open_adapter;
-  struct tok_info *ti;
-  ti=(struct tok_info *) dev->priv;
-
-#ifndef TR_NEWFORMAT
+       struct tok_info *ti;
+       int i;
+       
+       ti=(struct tok_info *) dev->priv;
+       
+#if !TR_NEWFORMAT
        DPRINTK("now opening the board...\n");
 #endif
-
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
-
-       open_adapter=(struct dir_open_adapter *)(ti->init_srb);
-       memset(open_adapter,0,sizeof(struct dir_open_adapter));
-
-       open_adapter->command=DIR_OPEN_ADAPTER;
-       open_adapter->open_options=htons(OPEN_PASS_BCON_MAC);
-       open_adapter->num_rcv_buf=htons(NUM_RCV_BUF);
-       open_adapter->rcv_buf_len=htons(RCV_BUF_LEN);
-       open_adapter->dhb_length=htons(DHB_LENGTH);
-       open_adapter->num_dhb=NUM_DHB;
-       open_adapter->dlc_max_sap=DLC_MAX_SAP;
-       open_adapter->dlc_max_sta=DLC_MAX_STA;
-
+       
+       writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
+       writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
+       
+       for (i=0; i<sizeof(struct dir_open_adapter); i++)
+               writeb(0, ti->init_srb+i);
+       
+       writeb(DIR_OPEN_ADAPTER, 
+              ti->init_srb + offsetof(struct dir_open_adapter, command));
+       writew(htons(OPEN_PASS_BCON_MAC), 
+              ti->init_srb + offsetof(struct dir_open_adapter, open_options));
+       writew(htons(NUM_RCV_BUF), 
+              ti->init_srb + offsetof(struct dir_open_adapter, num_rcv_buf));
+       writew(htons(RCV_BUF_LEN), 
+              ti->init_srb + offsetof(struct dir_open_adapter, rcv_buf_len));
+       writew(htons(DHB_LENGTH), 
+              ti->init_srb + offsetof(struct dir_open_adapter, dhb_length));
+       writeb(NUM_DHB, 
+              ti->init_srb + offsetof(struct dir_open_adapter, num_dhb));
+       writeb(DLC_MAX_SAP, 
+              ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sap));
+       writeb(DLC_MAX_STA, 
+              ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sta));
+       
        ti->srb=ti->init_srb; /* We use this one in the interrupt handler */
-
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
-
+       
+       writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+       writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+       
 }
 
-static void tr_tx(struct device *dev) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-       struct asb_xmit_resp *xmit_resp=(struct asb_xmit_resp *)ti->asb;
-       struct arb_xmit_req *xmit_req=(struct arb_xmit_req *)ti->arb;
-       struct srb_xmit *xmit=(struct srb_xmit *)ti->srb;
+static void tr_tx(struct device *dev) 
+{
+       struct tok_info *ti=(struct tok_info *) dev->priv;
        struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data;
        unsigned int hdr_len;
-       unsigned char *dhb;
-
-/* */
-  DPRINTD("ti=%p asb=(%p,%p) arb=(%p,%p) srb=(%p,%p)\n",
-       ti , ti->asb, xmit_resp, ti->arb, xmit_req, ti->srb, xmit);
-/* */
-
-#if 0
-DPRINTK("transmitting...\n");
-#endif
-
-       if(xmit_resp->ret_code!=0xff)  DPRINTK("ASB not free !!!\n");
-
-                     /*  in providing the transmit interrupts,
-                         is telling us it is ready for data and
-                         providing a shared memory address for us
-                         to stuff with data.  Here we compute the
-                         effective address where we will place data.*/
-  dhb=ti->sram+ntohs(xmit_req->dhb_address);
-
-       xmit_resp->command=xmit->command;
-       xmit_resp->station_id=xmit_req->station_id;
-       xmit_resp->rsap_value=EXTENDED_SAP;
-       xmit_resp->cmd_corr=xmit_req->cmd_corr;
-       xmit_resp->ret_code=0;
-
-       if((xmit->command==XMIT_XID_CMD) || (xmit->command==XMIT_TEST_CMD)) {
-               xmit_resp->frame_length=htons(0x11);
-               xmit_resp->hdr_length=0x0e;
-               dhb[0]=AC;
-               dhb[1]=LLC_FRAME;
-               memset(dhb+2,(int)0x0ff,TR_ALEN);
-               memset(dhb+2+TR_ALEN,0,TR_ALEN);
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET
-                                                        + ISRA_ODD)=RESP_IN_ASB;
+       __u32 dhb;
+       unsigned char xmit_command;
+       int i;
+       
+       if (readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF)
+               DPRINTK("ASB not free !!!\n");
+       
+       /* in providing the transmit interrupts,
+          is telling us it is ready for data and
+          providing a shared memory address for us
+          to stuff with data.  Here we compute the
+          effective address where we will place data.*/
+       dhb=ti->sram 
+               +ntohs(readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address)));
+       
+       xmit_command = readb(ti->srb + offsetof(struct srb_xmit, command));
+       
+       writeb(xmit_command, ti->asb + offsetof(struct asb_xmit_resp, command));
+       writew(readb(ti->srb + offsetof(struct srb_xmit, station_id)),
+              ti->asb + offsetof(struct asb_xmit_resp, station_id));
+       writeb(EXTENDED_SAP, ti->asb + offsetof(struct asb_xmit_resp, rsap_value));
+       writeb(readb(ti->srb + offsetof(struct srb_xmit, cmd_corr)),
+              ti->asb + offsetof(struct asb_xmit_resp, cmd_corr));
+       writeb(0, ti->asb + offsetof(struct asb_xmit_resp, ret_code));
+       
+       if ((xmit_command==XMIT_XID_CMD) || (xmit_command==XMIT_TEST_CMD)) {
+               
+               writew(htons(0x11), 
+                      ti->asb + offsetof(struct asb_xmit_resp, frame_length));
+               writeb(0x0e, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
+               writeb(AC, dhb);
+               writeb(LLC_FRAME, dhb+1);
+               
+               for (i=0; i<TR_ALEN; i++) writeb((int)0x0FF, dhb+i+2);
+               for (i=0; i<TR_ALEN; i++) writeb(0, dhb+i+TR_ALEN+2);
+               
+               writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
                return;
+               
        }
-
-     /* the token ring packet is copied from sk_buff to the adapter
-        buffer identified in the command data received with the
-        interrupt.  The sk_buff area was set up with a maximum
-        sized route information field so here we must compress
-        out the extra (all) rif fields.   */
-     /* nb/dwm .... I re-arranged code here to avoid copy of extra
-        bytes, ended up with fewer statements as well             */
-
-     /*  TR arch. identifies if RIF present by high bit of source
-         address.  So here we check if RIF present */
-  if(!(trhdr->saddr[0] & 0x80)) {
-    hdr_len=sizeof(struct trh_hdr)-18;
-#if 0
-DPRINTK(("hdr_length: %d, frame length: %ld\n",hdr_len,
-      ti->current_skb->len-18));
-#endif
-  }   /*  TR packet includes RIF data ... preserve it */
-  else {
-    hdr_len=((ntohs(trhdr->rcf)
-             & TR_RCF_LEN_MASK)>>8)+sizeof(struct trh_hdr)-18;
-#if 0
-/* rework the following if activated, hdr_len <> rif_len */
-DPRINTK("rcf: %02X rif_len: %d\n", trhdr->rcf,wrk_len);
-DPRINTK("hdr_length: %d, frame length: %ld\n",sizeof(struct trh_hdr)-18+hdr_len,
-      ti->current_skb->len-18+hdr_len);
+       
+       /* the token ring packet is copied from sk_buff to the adapter
+          buffer identified in the command data received with the
+          interrupt.  The sk_buff area was set up with a maximum
+          sized route information field so here we must compress
+          out the extra (all) rif fields.   */
+       /* nb/dwm .... I re-arranged code here to avoid copy of extra
+          bytes, ended up with fewer statements as well. */
+       
+       /* TR arch. identifies if RIF present by high bit of source
+          address.  So here we check if RIF present */
+
+       if (!(trhdr->saddr[0] & 0x80)) { /* RIF present : preserve it */
+               hdr_len=sizeof(struct trh_hdr)-18;
+               
+#if TR_VERBOSE
+               DPRINTK("hdr_length: %d, frame length: %ld\n", hdr_len,
+                       ti->current_skb->len-18);
 #endif
-  }
-
-  /* header length including rif is computed above, now move the data
-     and set fields appropriately.     */
-
-  memcpy(dhb,ti->current_skb->data,hdr_len);
-  dhb+=hdr_len;
-  xmit_resp->hdr_length= hdr_len;
-  xmit_resp->frame_length=htons(ti->current_skb->len
-                                -sizeof(struct trh_hdr)+hdr_len);
-
-                  /*  now copy the actual packet data next to hdr */
-  memcpy(dhb,ti->current_skb->data+sizeof(struct trh_hdr),
-             ti->current_skb->len-sizeof(struct trh_hdr));
-
-  *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)
-             =RESP_IN_ASB;
-  dev->tbusy=0;
-  dev_kfree_skb(ti->current_skb,FREE_WRITE);
-  ti->current_skb=NULL;
-  mark_bh(NET_BH);
+       } else hdr_len=((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK)>>8)
+                 +sizeof(struct trh_hdr)-18;
+       
+       /* header length including rif is computed above, now move the data
+          and set fields appropriately. */
+       for (i=0; i<hdr_len; i++)
+               writeb(*(unsigned char *)(ti->current_skb->data +i), dhb++);
+       
+       writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
+       writew(htons(ti->current_skb->len-sizeof(struct trh_hdr)+hdr_len),
+              ti->asb + offsetof(struct asb_xmit_resp, frame_length));
+       
+       /*  now copy the actual packet data next to hdr */
+       for (i=0; i<ti->current_skb->len-sizeof(struct trh_hdr); i++)
+               writeb(*(unsigned char *)(ti->current_skb->data +sizeof(struct trh_hdr)+i),
+                      dhb+i);
+       
+       writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+       dev->tbusy=0;
+       dev_kfree_skb(ti->current_skb,FREE_WRITE);
+       ti->current_skb=NULL;
+       mark_bh(NET_BH);
 }
 
-static void tr_rx(struct device *dev) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-
-       struct arb_rec_req *rec_req=(struct arb_rec_req *)ti->arb;
-       struct asb_rec *rec_resp=(struct asb_rec *)ti->asb;
-       struct rec_buf *rbuffer;        
-       struct trllc *llc;
+static void tr_rx(struct device *dev) 
+{
+       int i;
+       struct tok_info *ti=(struct tok_info *) dev->priv;
+       __u32 rbuffer;  
+       __u32 llc;
        unsigned char *data;
-       unsigned int rbuffer_len,lan_hdr_len;
+       unsigned int rbuffer_len, lan_hdr_len;
+       unsigned int arb_frame_len;
        struct sk_buff *skb;
-
-       rbuffer=(struct rec_buf *)(ti->sram+ntohs(rec_req->rec_buf_addr));
-
-       if(rec_resp->ret_code!=0xff) DPRINTK("ASB not free !!!\n");
-
-       rec_resp->command=REC_DATA;
-       rec_resp->station_id=rec_req->station_id;
-       rec_resp->rec_buf_addr=rec_req->rec_buf_addr;
-
-       lan_hdr_len=rec_req->lan_hdr_len;
-
-       llc=(struct trllc *)((unsigned char *)rbuffer+offsetof(struct rec_buf,data)+lan_hdr_len);
-
-#if 0
-DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",offsetof(struct rec_buf,data),lan_hdr_len);
-DPRINTK("llc: %p rec_buf_addr: %04X ti->sram: %p\n",llc,ntohs(rec_req->rec_buf_addr),ti->sram);
-DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, ethertype: %04X\n",
-                       llc->dsap,llc->ssap,llc->llc,llc->protid[0],llc->protid[1],llc->protid[2],llc->ethertype);
-#endif
-
-       if(llc->llc!=UI_CMD) {
-#ifndef TR_FILTERNONUI         
-               DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",llc->llc);
-#endif
-               rec_resp->ret_code=DATA_LOST;
-               ti->tr_stats.rx_dropped++;
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
-               return;
-       }
-
-#if 0
-       if((llc->dsap!=0xaa) || (llc->ssap!=0xaa)) {
-
-       struct trh_hdr *trhdr=(struct trh_hdr *)((unsigned char *)rbuffer+offsetof(struct rec_buf,data));
-
-DPRINTK("Probably non-IP frame received.\n");
-DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
-                       llc->ssap,llc->dsap,trhdr->saddr[0],trhdr->saddr[1],trhdr->saddr[2],trhdr->saddr[3],trhdr->saddr[4],trhdr->saddr[5],
-                       trhdr->daddr[0],trhdr->daddr[1],trhdr->daddr[2],trhdr->daddr[3],trhdr->daddr[4],trhdr->daddr[5]);
-       }
+       
+       rbuffer=(ti->sram
+                +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))));
+       
+       if(readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF)
+               DPRINTK("ASB not free !!!\n");
+       
+       writeb(REC_DATA, 
+              ti->asb + offsetof(struct asb_rec, command));
+       writew(readw(ti->arb + offsetof(struct arb_rec_req, station_id)),
+              ti->asb + offsetof(struct asb_rec, station_id));
+       writew(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)),
+              ti->asb + offsetof(struct asb_rec, rec_buf_addr));
+       
+       lan_hdr_len=readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len));
+       
+       llc=(rbuffer+offsetof(struct rec_buf, data) + lan_hdr_len);
+       
+#if TR_VERBOSE
+       DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",
+               (unsigned int)offsetof(struct rec_buf,data), (unsigned int)lan_hdr_len);
+       DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %p\n", llc,
+               ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))), 
+               ti->sram);
+       DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, "
+               "ethertype: %04X\n",
+               (int)readb(llc + offsetof(struct trllc, dsap)),
+               (int)readb(llc + offsetof(struct trllc, ssap)),
+               (int)readb(llc + offsetof(struct trllc, protid)),
+               (int)readb(llc + offsetof(struct trllc, protid)+1),
+               (int)readb(llc + offsetof(struct trllc, protid)+2),
+               (int)readw(llc + offsetof(struct trllc, ethertype)));
 #endif
-
-
-       if(!(skb=dev_alloc_skb(ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr)))) {
-               DPRINTK("out of memory. frame dropped.\n");     
-               ti->tr_stats.rx_dropped++;
-               rec_resp->ret_code=DATA_LOST;
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
-               return;
-       }
-
-       skb_put(skb,ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr));
-       skb->dev=dev;
-
-#if 0
-DPRINTK("Now copying data...\n");
+       
+       if (readb(llc + offsetof(struct trllc, llc))!=UI_CMD) {
+#if !TR_FILTERNONUI            
+               DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",
+                       (int)readb(llc + offsetof(struct trllc, llc))
 #endif
-
-
-       data=skb->data;
-       memcpy(data,&(rbuffer->data),lan_hdr_len);
-
-
-       if(lan_hdr_len<sizeof(struct trh_hdr))
-               memset(data+lan_hdr_len,0,sizeof(struct trh_hdr)-lan_hdr_len);
-
-       data+=sizeof(struct trh_hdr);
-       rbuffer_len=ntohs(rbuffer->buf_len)-lan_hdr_len;
-#if 0
-DPRINTK("rbuffer_len: %d, data: %p\n",rbuffer_len,data);
+                       writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+                       ti->tr_stats.rx_dropped++;
+                       writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+                       return;
+                       }
+               
+#if TR_VERBOSE
+               if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
+                   (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
+                       
+                       __u32 trhhdr;
+                       
+                       trhhdr=(rbuffer+offsetof(struct rec_buf,data));
+                       
+                       DPRINTK("Probably non-IP frame received.\n");
+                       DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X "
+                               "daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
+                               (int)readb(llc + offsetof(struct trllc, ssap)),
+                               (int)readb(llc + offsetof(struct trllc, dsap)),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+1),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+2),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+3),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+4),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+5),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+1),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+2),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+3),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+4),
+                               (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+5));
+               }
 #endif
-       memcpy(data,(unsigned char *)(&(rbuffer->data))+lan_hdr_len,rbuffer_len);
-       data+=rbuffer_len;
-
-
-       if(rbuffer->buf_ptr)
-               for(rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2);
-                               memcpy(data,&(rbuffer->data),rbuffer_len=ntohs(rbuffer->buf_len)),rbuffer->buf_ptr;
-                               data+=rbuffer_len,rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2))
-#if 0
-       DPRINTK("buf_ptr: %d,data =%p\n",ntohs(rbuffer->buf_ptr),data);
+               
+               arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
+               
+               if (!(skb=dev_alloc_skb(arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr)))) {
+                       DPRINTK("out of memory. frame dropped.\n");     
+                       ti->tr_stats.rx_dropped++;
+                       writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
+                       writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+                       return;
+               }
+               
+               skb_put(skb, arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr));
+               skb->dev=dev;
+               
+               data=skb->data;
+               for (i=0; i<lan_hdr_len; i++) 
+                       data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
+               
+               if (lan_hdr_len<sizeof(struct trh_hdr))
+                       memset(data+lan_hdr_len, 0, sizeof(struct trh_hdr)-lan_hdr_len);
+               
+               data+=sizeof(struct trh_hdr);
+               rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)))
+                       -lan_hdr_len;
+               
+#if TR_VERBOSE
+               DPRINTK("rbuffer_len: %d, data: %p\n", rbuffer_len, data);
 #endif
-
-       rec_resp->ret_code=0;
-
-       *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
-
-       ti->tr_stats.rx_packets++;
-
-       skb->protocol=tr_type_trans(skb,dev);
-       netif_rx(skb);
-
-       return;
-}
-
-static int tok_send_packet(struct sk_buff *skb, struct device *dev) {
-
-  struct tok_info *ti=(struct tok_info *) dev->priv;
-
-#if 0
-DPRINTK("tada: sending packet...\n");
+               
+               for (i=0; i<rbuffer_len; i++)
+                       data[i]=readb(rbuffer+ offsetof(struct rec_buf, data)+lan_hdr_len+i);
+               data+=rbuffer_len;
+               
+               while (readw(rbuffer + offsetof(struct rec_buf, buf_ptr))) {
+                       rbuffer=(ti->sram
+                                +ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_ptr)))-2);
+                       rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
+                       for (i=0; i<rbuffer_len; i++)
+                               data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
+                       data+=rbuffer_len;
+                       
+#if TR_VERBOSE
+                       DPRINTK("buf_ptr: %d, data =%p\n", 
+                               ntohs((rbuffer + offsetof(struct rec_buf, buf_ptr))), data);
 #endif
+               } 
+               
+               writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
+               
+               writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+               
+               ti->tr_stats.rx_packets++;
+               
+               skb->protocol=tr_type_trans(skb,dev);
+               netif_rx(skb);
+               
+       }
 
+static int tok_send_packet(struct sk_buff *skb, struct device *dev) 
+{
+       struct tok_info *ti;
+       ti=(struct tok_info *) dev->priv;
+       
        if (dev->tbusy) {
-               int ticks_waited=jiffies - dev->trans_start;
-               if(ticks_waited<TX_TIMEOUT)
-                       return 1;
-               DPRINTK("Arrg. Transmitter busy for more than 50 msec. Donald resets adapter, but resetting\n \
-the IBM tokenring adapter takes a long time. It might not even help when the\n \
-ring is very busy, so we just wait a little longer and hope for the best.\n");         
+               int ticks_waited;
+               
+               ticks_waited=jiffies - dev->trans_start;
+               if (ticks_waited<TR_BUSY_INTERVAL) return 1;
+               
+               DPRINTK("Arrg. Transmitter busy for more than 50 msec. "
+                       "Donald resets adapter, but resetting\n"
+                       "the IBM tokenring adapter takes a long time."
+                       " It might not even help when the\n"
+                       "ring is very busy, so we just wait a little longer "
+                       "and hope for the best.\n");            
                dev->trans_start+=5; /* we fake the transmission start time... */
                return 1;
        }
-
+       
        /* Donald does this, so we do too. */
-
-       if(skb==NULL) {
+       if (skb==NULL) {
                dev_tint(dev);
                return 0;
        }
-
-       if(set_bit(0,(void *)&dev->tbusy)!=0)
+       
+       if (set_bit(0,(void *)&dev->tbusy)!=0)
                DPRINTK("Transmitter access conflict\n");
        else {
-               struct srb_xmit *xmit=(struct srb_xmit *)ti->srb;
-
-               ti->current_skb=skb; /* save skb. We will need it when the adapter
-                                  asks for the data */
-               xmit->command=XMIT_UI_FRAME;
-               xmit->station_id=ti->exsap_station_id;
-               *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
+               /* Save skb; we'll need it when the adapter asks for the data */
+               ti->current_skb=skb; 
+               writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
+               writew(ti->exsap_station_id, ti->srb 
+                      +offsetof(struct srb_xmit, station_id));
+               writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
                dev->trans_start=jiffies;
        }
-
+       
        return 0;
 }      
 
 /* tok_get_stats():  Basically a scaffold routine which will return
-         the address of the tr_statistics structure associated with
-         this device -- the tr.... structure is a ethnet look-alike
-         so at least for this iteration may suffice.   */
+   the address of the tr_statistics structure associated with
+   this device -- the tr.... structure is a ethnet look-alike
+   so at least for this iteration may suffice.   */
 
 static struct enet_statistics * tok_get_stats(struct device *dev) {
 
-  struct tok_info *toki;
-  toki=(struct tok_info *) dev->priv;
-  return (struct enet_statistics *) &toki->tr_stats;
+       struct tok_info *toki;
+       toki=(struct tok_info *) dev->priv;
+       return (struct enet_statistics *) &toki->tr_stats;
 }
 
 #ifdef MODULE
+
+
 static char devicename[9] = { 0, };
 static struct device dev_ibmtr = {
        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
@@ -1348,10 +1446,11 @@ static int io = 0xa20;
 
 int init_module(void)
 {
-       if (io == 0)
+       if (io == 0) 
                printk("ibmtr: You should not use auto-probing with insmod!\n");
        dev_ibmtr.base_addr = io;
        dev_ibmtr.irq       = 0;
+       
        if (register_netdev(&dev_ibmtr) != 0) {
                printk("ibmtr: register_netdev() returned non-zero.\n");
                return -EIO;
@@ -1359,11 +1458,10 @@ int init_module(void)
        return 0;
 }
 
-void
-cleanup_module(void)
+void cleanup_module(void)
 {
        unregister_netdev(&dev_ibmtr);
-
+       
        /* If we don't do this, we can't re-insmod it later. */
        free_irq(dev_ibmtr.irq, NULL);
        irq2dev_map[dev_ibmtr.irq] = NULL;
index b92146835e0a5977cb2a22f318e453c88cb65f15..9c7d02e54a3eac647fccc5535fc849d41c596c17 100644 (file)
@@ -1,23 +1,18 @@
 /* Definitions for an IBM Token Ring card. */
 /* This file is distributed under the GNU GPL   */
 
-#define TR_RETRY_INTERVAL 500
+/* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */
+
+#define TR_RETRY_INTERVAL (5*HZ) /* 500 on PC = 5 s */
+#define TR_RESET_INTERVAL (HZ/20) /* 5 on PC = 50 ms */
+#define TR_BUSY_INTERVAL (HZ/5) /* 5 on PC = 200 ms */
+
 #define TR_ISA 1
 #define TR_MCA 2
 #define TR_ISAPNP 3
 #define NOTOK 0
 #define TOKDEBUG 1
 
-/* Mike Eckhoff -- 96/02/08 */
-/* This defines the minimum timeout. If a transmission takes */
-/* longer then TX_TIMEOUT to send, we will wait and retry. */
-/* On large networks, this value may need to be increased. */
-/* We will start at .2s because that is what most drivers seem to be doing */
-/* now and the original value of .05s was not nearly enough for large nets. */
-
-#define TX_TIMEOUT (HZ/5)
-
-
 #ifndef IBMTR_SHARED_RAM_BASE
 #define IBMTR_SHARED_RAM_BASE 0xD0
 #define IBMTR_SHARED_RAM_SIZE 0x10
 #define ACA_RW 0x00
 
 #ifdef ENABLE_PAGING
-#define SET_PAGE(x) (*(unsigned char *) \
-                         (ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)\
-                                                = (x>>8)&ti.page_mask)
+#define SET_PAGE(x) (writeb(((x>>8)&ti.page_mask), \
+  ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN))
 #else
 #define SET_PAGE(x)
 #endif
 
 typedef enum { IN_PROGRESS, SUCCES, FAILURE, CLOSED } open_state;
 
-struct tok_info {
-        unsigned char irq;
-        unsigned char *mmio;
-        unsigned char hw_address[32];
-        unsigned char adapter_type;
-        unsigned char data_rate;
-        unsigned char token_release;
-        unsigned char avail_shared_ram;
-        unsigned char shared_ram_paging;
-        unsigned char dhb_size4mb;
-        unsigned char dhb_size16mb;
-/* Additions by David Morris       */
-        unsigned char do_tok_int;
+/* do_tok_int possible values */
 #define FIRST_INT 1
 #define NOT_FIRST 2
-        struct wait_queue *wait_for_tok_int;
-        struct wait_queue *wait_for_reset;
-        unsigned char sram_base;
-/* Additions by Peter De Schrijver */
-        unsigned char page_mask;     /* mask to select RAM page to Map*/
-        unsigned char mapped_ram_size;  /* size of RAM page */
-        unsigned char *sram; /* Shared memory base address */
-        unsigned char *init_srb;  /* Initial System Request Block address */
-        unsigned char *srb;  /* System Request Block address */
-        unsigned char *ssb;  /* System Status Block address */
-        unsigned char *arb;  /* Adapter Request Block address */
-        unsigned char *asb;  /* Adapter Status Block address */
-        unsigned short exsap_station_id;
-        unsigned short global_int_enable;
-        struct sk_buff *current_skb;
-        struct tr_statistics tr_stats;
-        unsigned char auto_ringspeedsave;
-       open_state open_status;
-       
-};
 
-struct srb_init_response {
-        unsigned char command;
-        unsigned char init_status;
-       unsigned char init_status_2;
-        unsigned char reserved[3];
-        unsigned short bring_up_code;
-        unsigned short encoded_address;
-        unsigned short level_address;
-        unsigned short adapter_address;
-        unsigned short parms_address;
-        unsigned short mac_address;
-};
-
-#define DIR_OPEN_ADAPTER 0x03
-
-struct dir_open_adapter {
-        unsigned char command;
-        char reserved[7];
-        unsigned short open_options;
-        unsigned char node_address[6];
-        unsigned char group_address[4];
-        unsigned char funct_address[4];
-        unsigned short num_rcv_buf;
-        unsigned short rcv_buf_len;
-        unsigned short dhb_length;
-        unsigned char num_dhb;
-        char reserved2;
-        unsigned char dlc_max_sap;
-        unsigned char dlc_max_sta;
-        unsigned char dlc_max_gsap;
-        unsigned char dlc_max_gmem;
-        unsigned char dlc_t1_tick_1;
-        unsigned char dlc_t2_tick_1;
-        unsigned char dlc_ti_tick_1;
-        unsigned char dlc_t1_tick_2;
-        unsigned char dlc_t2_tick_2;
-        unsigned char dlc_ti_tick_2;
-        unsigned char product_id[18];
+struct tok_info {
+       unsigned char irq;
+       __u32 mmio;
+       unsigned char hw_address[32];
+       unsigned char adapter_type;
+       unsigned char data_rate;
+       unsigned char token_release;
+       unsigned char avail_shared_ram;
+       unsigned char shared_ram_paging;
+       unsigned char dhb_size4mb;
+       unsigned char dhb_size16mb;
+       /* Additions by David Morris       */
+       unsigned char do_tok_int;
+       struct wait_queue *wait_for_tok_int;
+       struct wait_queue *wait_for_reset;
+       unsigned char sram_base;
+       /* Additions by Peter De Schrijver */
+       unsigned char page_mask;          /* mask to select RAM page to Map*/
+       unsigned char mapped_ram_size;    /* size of RAM page */
+       __u32 sram;                       /* Shared memory base address */
+       __u32 init_srb;                   /* Initial System Request Block address */
+       __u32 srb;                        /* System Request Block address */
+       __u32 ssb;                        /* System Status Block address */
+       __u32 arb;                        /* Adapter Request Block address */
+       __u32 asb;                        /* Adapter Status Block address */
+       unsigned short exsap_station_id;
+       unsigned short global_int_enable;
+       struct sk_buff *current_skb;
+       struct tr_statistics tr_stats;
+       unsigned char auto_ringspeedsave;
+       open_state open_status;
 };
 
-struct srb_open_response {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
-        unsigned char reserved2[3];
-        unsigned short error_code;
-        unsigned short asb_addr;
-        unsigned short srb_addr;
-        unsigned short arb_addr;
-        unsigned short ssb_addr;
-};
+/* token ring adapter commands */
+#define DIR_INTERRUPT          0x00 /* struct srb_interrupt */
+#define DIR_MOD_OPEN_PARAMS    0x01
+#define DIR_OPEN_ADAPTER       0x03 /* struct dir_open_adapter */
+#define DIR_CLOSE_ADAPTER      0x04
+#define DIR_SET_GRP_ADDR       0x06
+#define DIR_SET_FUNC_ADDR      0x07
+#define DIR_READ_LOG           0x08 /* struct srb_read_log */
+#define DLC_OPEN_SAP           0x15 /* struct dlc_open_sap */
+#define DLC_CLOSE_SAP          0x16
+#define DATA_LOST              0x20 /* struct asb_rec */
+#define REC_DATA               0x81 /* struct arb_rec_req */
+#define XMIT_DATA_REQ          0x82 /* struct arb_xmit_req */
+#define DLC_STATUS             0x83 /* struct arb_dlc_status */
+#define RING_STAT_CHANGE       0x84 /* struct dlc_open_sap ??? */
 
 /* DIR_OPEN_ADAPTER options */
-
 #define OPEN_PASS_BCON_MAC 0x0100
 #define NUM_RCV_BUF 16
 #define RCV_BUF_LEN 136
@@ -275,164 +233,197 @@ struct srb_open_response {
 #define DLC_MAX_SAP 2
 #define DLC_MAX_STA 1
 
-#define DLC_OPEN_SAP 0x15
-
-struct dlc_open_sap {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
-        unsigned char reserved2;
-        unsigned short station_id;
-        unsigned char timer_t1;
-        unsigned char timer_t2;
-        unsigned char timer_ti;
-        unsigned char maxout;
-        unsigned char maxin;
-        unsigned char maxout_incr;
-        unsigned char max_retry_count;
-        unsigned char gsap_max_mem;
-        unsigned short max_i_field;
-        unsigned char sap_value;
-        unsigned char sap_options;
-        unsigned char station_count;
-        unsigned char sap_gsap_mem;
-        unsigned char gsap[0];
-};
-
 /* DLC_OPEN_SAP options */
-
 #define MAX_I_FIELD 0x0088
 #define SAP_OPEN_IND_SAP 0x04
 #define SAP_OPEN_PRIORITY 0x20
 #define SAP_OPEN_STATION_CNT 0x1
-
-#define XMIT_DIR_FRAME 0x0a
+#define XMIT_DIR_FRAME 0x0A
 #define XMIT_UI_FRAME  0x0d
 #define XMIT_XID_CMD   0x0e
 #define XMIT_TEST_CMD  0x11
 
+/* srb close return code */
+#define SIGNAL_LOSS  0x8000
+#define HARD_ERROR   0x4000
+#define XMIT_BEACON  0x1000
+#define LOBE_FAULT   0x0800
+#define AUTO_REMOVAL 0x0400
+#define REMOVE_RECV  0x0100
+#define LOG_OVERFLOW 0x0080
+#define RING_RECOVER 0x0020
+
+struct srb_init_response {
+       unsigned char command;
+       unsigned char init_status;
+       unsigned char init_status_2;
+       unsigned char reserved[3];
+       __u16 bring_up_code;
+       __u16 encoded_address;
+       __u16 level_address;
+       __u16 adapter_address;
+       __u16 parms_address;
+       __u16 mac_address;
+};
+
+struct dir_open_adapter {
+       unsigned char command;
+       char reserved[7];
+       __u16 open_options;
+       unsigned char node_address[6];
+       unsigned char group_address[4];
+       unsigned char funct_address[4];
+       __u16 num_rcv_buf;
+       __u16 rcv_buf_len;
+       __u16 dhb_length;
+       unsigned char num_dhb;
+       char reserved2;
+       unsigned char dlc_max_sap;
+       unsigned char dlc_max_sta;
+       unsigned char dlc_max_gsap;
+       unsigned char dlc_max_gmem;
+       unsigned char dlc_t1_tick_1;
+       unsigned char dlc_t2_tick_1;
+       unsigned char dlc_ti_tick_1;
+       unsigned char dlc_t1_tick_2;
+       unsigned char dlc_t2_tick_2;
+       unsigned char dlc_ti_tick_2;
+       unsigned char product_id[18];
+};
+
+struct srb_open_response {
+       unsigned char command;
+       unsigned char reserved1;
+       unsigned char ret_code;
+       unsigned char reserved2[3];
+       __u16 error_code;
+       __u16 asb_addr;
+       __u16 srb_addr;
+       __u16 arb_addr;
+       __u16 ssb_addr;
+};
+
+struct dlc_open_sap {
+       unsigned char command;
+       unsigned char reserved1;
+       unsigned char ret_code;
+       unsigned char reserved2;
+       __u16 station_id;
+       unsigned char timer_t1;
+       unsigned char timer_t2;
+       unsigned char timer_ti;
+       unsigned char maxout;
+       unsigned char maxin;
+       unsigned char maxout_incr;
+       unsigned char max_retry_count;
+       unsigned char gsap_max_mem;
+       __u16 max_i_field;
+       unsigned char sap_value;
+       unsigned char sap_options;
+       unsigned char station_count;
+       unsigned char sap_gsap_mem;
+       unsigned char gsap[0];
+};
+
 struct srb_xmit {
-        unsigned char command;
-        unsigned char cmd_corr;
-        unsigned char ret_code;
-        unsigned char reserved1;
-        unsigned short station_id;
+       unsigned char command;
+       unsigned char cmd_corr;
+       unsigned char ret_code;
+       unsigned char reserved1;
+       __u16 station_id;
 };
 
-#define DIR_INTERRUPT 0x00
 struct srb_interrupt {
-        unsigned char command;
-        unsigned char cmd_corr;
-        unsigned char ret_code;
+       unsigned char command;
+       unsigned char cmd_corr;
+       unsigned char ret_code;
 };
 
-#define DIR_READ_LOG 0x08
 struct srb_read_log {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
-        unsigned char reserved2;
-        unsigned char line_errors;
-        unsigned char internal_errors;
-        unsigned char burst_errors;
-        unsigned char A_C_errors;
-        unsigned char abort_delimiters;
-        unsigned char reserved3;
-        unsigned char lost_frames;
-        unsigned char recv_congest_count;
-        unsigned char frame_copied_errors;
-        unsigned char frequency_errors;
-        unsigned char token_errors;
+       unsigned char command;
+       unsigned char reserved1;
+       unsigned char ret_code;
+       unsigned char reserved2;
+       unsigned char line_errors;
+       unsigned char internal_errors;
+       unsigned char burst_errors;
+       unsigned char A_C_errors;
+       unsigned char abort_delimiters;
+       unsigned char reserved3;
+       unsigned char lost_frames;
+       unsigned char recv_congest_count;
+       unsigned char frame_copied_errors;
+       unsigned char frequency_errors;
+       unsigned char token_errors;
 };
 
 struct asb_xmit_resp {
-        unsigned char command;
-        unsigned char cmd_corr;
-        unsigned char ret_code;
-        unsigned char reserved;
-        unsigned short station_id;
-        unsigned short frame_length;
-        unsigned char hdr_length;
-        unsigned        char rsap_value;
+       unsigned char command;
+       unsigned char cmd_corr;
+       unsigned char ret_code;
+       unsigned char reserved;
+       __u16 station_id;
+       __u16 frame_length;
+       unsigned char hdr_length;
+       unsigned char rsap_value;
 };
 
-#define XMIT_DATA_REQ 0x82
 struct arb_xmit_req {
-        unsigned char command;
-        unsigned char cmd_corr;
-        unsigned char reserved1[2];
-        unsigned short station_id;
-        unsigned short dhb_address;
+       unsigned char command;
+       unsigned char cmd_corr;
+       unsigned char reserved1[2];
+       __u16 station_id;
+       __u16 dhb_address;
 };
 
-#define REC_DATA 0x81
 struct arb_rec_req {
-        unsigned char command;
-        unsigned char reserved1[3];
-        unsigned short station_id;
-        unsigned short rec_buf_addr;
-        unsigned char lan_hdr_len;
-        unsigned char dlc_hdr_len;
-        unsigned short frame_len;
-        unsigned char msg_type;
+       unsigned char command;
+       unsigned char reserved1[3];
+       __u16 station_id;
+       __u16 rec_buf_addr;
+       unsigned char lan_hdr_len;
+       unsigned char dlc_hdr_len;
+       __u16 frame_len;
+       unsigned char msg_type;
 };
 
-#define DATA_LOST 0x20
 struct asb_rec {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
-        unsigned char reserved2;
-        unsigned short station_id;
-        unsigned short rec_buf_addr;
+       unsigned char command;
+       unsigned char reserved1;
+       unsigned char ret_code;
+       unsigned char reserved2;
+       __u16 station_id;
+       __u16 rec_buf_addr;
 };
 
 struct rec_buf {
-        unsigned char reserved1[2];
-        unsigned short buf_ptr;
-        unsigned char reserved2;
-        unsigned short buf_len;
-        unsigned char data[0];
+       unsigned char reserved1[2];
+       __u16 buf_ptr;
+       unsigned char reserved2;
+       __u16 buf_len;
+       unsigned char data[0];
 };
 
-#define DLC_STATUS          0x83
 struct arb_dlc_status {
-        unsigned char command;
-        unsigned char reserved1[3];
-        unsigned short station_id;
-        unsigned short status;
-        unsigned char frmr_data[5];
-        unsigned char access_prio;
-        unsigned char rem_addr[TR_ALEN];
-        unsigned        char rsap_value;
+       unsigned char command;
+       unsigned char reserved1[3];
+       __u16 station_id;
+       __u16 status;
+       unsigned char frmr_data[5];
+       unsigned char access_prio;
+       unsigned char rem_addr[TR_ALEN];
+       unsigned char rsap_value;
 };
 
-#define RING_STAT_CHANGE    0x84
 struct arb_ring_stat_change {
-        unsigned char command;
-        unsigned char reserved1[5];
-        unsigned short ring_status;
+       unsigned char command;
+       unsigned char reserved1[5];
+       __u16 ring_status;
 };
 
-#define DIR_CLOSE_ADAPTER   0x04
 struct srb_close_adapter {
-        unsigned char command;
-        unsigned char reserved1;
-        unsigned char ret_code;
+       unsigned char command;
+       unsigned char reserved1;
+       unsigned char ret_code;
 };
 
-#define DIR_MOD_OPEN_PARAMS 0x01
-#define DIR_SET_GRP_ADDR    0x06
-#define DIR_SET_FUNC_ADDR   0x07
-#define DLC_CLOSE_SAP       0x16
-
-
-#define SIGNAL_LOSS  0x8000
-#define HARD_ERROR   0x4000
-#define XMIT_BEACON  0x1000
-#define LOBE_FAULT   0x0800
-#define AUTO_REMOVAL 0x0400
-#define REMOVE_RECV  0x0100
-#define LOG_OVERFLOW 0x0080
-#define RING_RECOVER 0x0020
-
index d96a6e2a6a6ed4951a25ae9fa5650f27c39feb95..b709ff40c8512a4ceffc336588e6dd77d7c5d9c3 100644 (file)
@@ -34,8 +34,6 @@
 #include <linux/errno.h>
 #include <linux/fcntl.h>
 #include <linux/in.h>
-#include <linux/if_ether.h>    /* For the statistics structure. */
-#include <linux/if_arp.h>      /* For ARPHRD_ETHER */
 
 #include <asm/system.h>
 #include <asm/segment.h>
@@ -46,6 +44,8 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
+#include <linux/if_ether.h>    /* For the statistics structure. */
+#include <linux/if_arp.h>      /* For ARPHRD_ETHER */
 
 #define LOOPBACK_MTU (PAGE_SIZE*7/8)
 
@@ -72,7 +72,7 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev)
                skb=skb_clone(skb, GFP_ATOMIC);         /* Clone the buffer */
                if(skb==NULL)
                        return 1;
-               dev_kfree_skb(skb2, FREE_READ);
+               dev_kfree_skb(skb2, FREE_WRITE);
                unlock=0;
        }
        else if(skb->sk)
@@ -81,7 +81,7 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev)
                 *      Packet sent but looped back around. Cease to charge
                 *      the socket for the frame.
                 */
-               skb->sk->wmem_alloc-=skb->truesize;
+               atomic_sub(skb->truesize, &skb->sk->wmem_alloc);
                skb->sk->write_space(skb->sk);
        }
 
index b6745841b9f874c407fa31212cd327c9a781ae6a..41009984f342d960a72dee8f486374a33eba2c7d 100644 (file)
 #include <linux/fs.h>
 #include <linux/malloc.h>
 #include <linux/if_ether.h>
-#include <linux/if_arp.h>
 #include <linux/string.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/trdevice.h>
+#include <linux/if_arp.h>
 #ifdef CONFIG_NET_ALIAS
 #include <linux/net_alias.h>
 #endif
index 434476d7def727e81a6a68cd1d4db0d81ad7a492..62b15f52b56131229b338e2a023861c71099ce87 100644 (file)
@@ -273,8 +273,9 @@ printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
        /*
         *      Push down and install the IPIP header.
         */
-       iph = skb->h.iph;
-       iph->version    =       4;
+        
+       iph                     =       skb->h.iph;
+       iph->version            =       4;
        iph->tos                =       skb->ip_hdr->tos;
        iph->ttl                =       skb->ip_hdr->ttl;
        iph->frag_off           =       0;
@@ -285,8 +286,8 @@ printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
        iph->tot_len            =       htons(skb->len);
        iph->id                 =       htons(ip_id_count++);   /* Race condition here? */
        ip_send_check(iph);
-       skb->ip_hdr = skb->h.iph;
-
+       skb->ip_hdr             = skb->h.iph;
+       skb->protocol           =       htons(ETH_P_IP);
 #ifdef TUNNEL_DEBUG
        printk("New IP Header....\n");
        print_ip(iph);
@@ -317,8 +318,7 @@ printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
        return 0;
 }
 
-static struct enet_statistics *
-tunnel_get_stats(struct device *dev)
+static struct enet_statistics *tunnel_get_stats(struct device *dev)
 {
        return((struct enet_statistics*) dev->priv);
 }
@@ -336,7 +336,7 @@ int tunnel_init(struct device *dev)
        static int tun_msg=0;
        if(!tun_msg)
        {
-               printk ( KERN_INFO "tunnel: version v0.2b\n" );
+               printk ( KERN_INFO "tunnel: version v0.2b2\n" );
                tun_msg=1;
        }
 
@@ -393,11 +393,13 @@ static int tunnel_probe(struct device *dev)
        return 0;
 }
 
-static struct device dev_tunnel = {
+static struct device dev_tunnel = 
+{
        "tunl0\0   ", 
        0, 0, 0, 0,
        0x0, 0,
-       0, 0, 0, NULL, tunnel_probe };
+       0, 0, 0, NULL, tunnel_probe 
+ };
 
 int init_module(void)
 {
diff --git a/drivers/net/sdla.c b/drivers/net/sdla.c
new file mode 100644 (file)
index 0000000..c85a307
--- /dev/null
@@ -0,0 +1,1639 @@
+/*
+ * SDLA      An implementation of a driver for the Sangoma S502/S508 series
+ *           multi-protocol PC interface card.  Initial offering is with 
+ *           the DLCI driver, providing Frame Relay support for linux.
+ *
+ *           Global definitions for the Frame relay interface.
+ *
+ * Version:  @(#)sdla.c   0.10   23 Mar 1996
+ *
+ * Credits:  Sangoma Technologies, for the use of 2 cards for an extended
+ *                                 period of time.
+ *           David Mandelstam <dm@sangoma.com> for getting me started on 
+ *                            this project, and incentive to complete it.
+ *           Gene Kozen <74604.152@compuserve.com> for providing me with
+ *                      important information about the cards.
+ *
+ * Author:   Mike McLagan <mike.mclagan@linux.org>
+ *
+ *           This program is free software; you can redistribute it and/or
+ *           modify it under the terms of the GNU General Public License
+ *           as published by the Free Software Foundation; either version
+ *           2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/if_frad.h>
+
+#include <linux/sdla.h>
+
+static const char* version = "SDLA driver v0.10, 23 Mar 1996, mike.mclagan@linux.org";
+
+static const char* devname = "sdla";
+
+static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
+
+static unsigned int valid_mem[]  = {0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, 
+                                    0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
+                                    0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
+                                    0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
+                                    0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; 
+
+/*********************************************************
+ *
+ * these are the core routines that access the card itself 
+ *
+ *********************************************************/
+
+#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
+
+static void sdla_read(struct device *dev, int addr, void *buf, short len)
+{
+   unsigned long flags;
+   char          *temp, *base;
+   int           offset, bytes;
+
+   temp = buf;
+   while(len)
+   {
+      offset = addr & 0x1FFF;
+      if (offset + len > 0x2000)
+         bytes = 0x2000 - offset;
+      else
+         bytes = len;
+
+      base = (void *) dev->mem_start;
+      base += offset;
+
+      save_flags(flags);
+      cli();
+      SDLA_WINDOW(dev, addr);
+      memcpy(temp, base, bytes);
+      restore_flags(flags);
+
+      addr += bytes;
+      temp += bytes;
+      len  -= bytes;
+   }  
+}
+
+static void sdla_write(struct device *dev, int addr, void *buf, short len)
+{
+   unsigned long flags;
+   char          *temp, *base;
+   int           offset, bytes;
+
+   temp = buf;
+   while(len)
+   {
+      offset = addr & 0x1FFF;
+      if (offset + len > 0x2000)
+         bytes = 0x2000 - offset;
+      else
+         bytes = len;
+
+      base = (void *) dev->mem_start;
+      base += offset;
+
+      save_flags(flags);
+      cli();
+      SDLA_WINDOW(dev, addr);
+      memcpy(base, temp, bytes);
+      restore_flags(flags);
+
+      addr += bytes;
+      temp += bytes;
+      len  -= bytes;
+   }
+}
+
+static void sdla_clear(struct device *dev)
+{
+   unsigned long flags;
+   char          *base;
+   int           offset, len, addr, bytes;
+
+   len = 65536;
+   addr = 0;
+   while(len)
+   {
+      offset = addr & 0x1FFF;
+      if (offset + len > 0x2000)
+         bytes = offset + len - 0x2000;
+      else
+         bytes = len;
+
+      base = (void *) dev->mem_start;
+      base += offset;
+
+      save_flags(flags);
+      cli();
+      SDLA_WINDOW(dev, addr);
+      memset(base, 0, bytes);
+      restore_flags(flags);
+
+      addr += bytes;
+      len  -= bytes;
+   }
+}
+
+static char sdla_byte(struct device *dev, int addr)
+{
+   unsigned long flags;
+   char          byte, *temp;
+
+   temp = (void *) dev->mem_start;
+   temp += addr & 0x1FFF;
+
+   save_flags(flags);
+   cli();
+   SDLA_WINDOW(dev, addr);
+   byte = *temp;
+   restore_flags(flags);
+
+   return(byte);
+}
+
+void sdla_stop(struct device *dev)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+         outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state = SDLA_HALT;
+         break;
+      case SDLA_S502E:
+         outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
+         outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state = SDLA_S502E_ENABLE;
+         break;
+      case SDLA_S507:
+         flp->state &= ~SDLA_CPUEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+      case SDLA_S508:
+         flp->state &= ~SDLA_CPUEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+   }
+}
+
+void sdla_start(struct device *dev)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+         outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL);
+         outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state = SDLA_S502A_START;
+         break;
+      case SDLA_S502E:
+         outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL);
+         outb(0x00, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state = 0;
+         break;
+      case SDLA_S507:
+         flp->state |= SDLA_CPUEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+      case SDLA_S508:
+         flp->state |= SDLA_CPUEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+   }
+}
+
+/****************************************************
+ *
+ * this is used for the S502A/E cards to determine
+ * the speed of the onboard CPU.  Calibration is
+ * necessary for the Frame Relay code uploaded 
+ * later.  Incorrect results cause timing problems
+ * with link checks & status messages
+ *
+ ***************************************************/
+
+int sdla_z80_poll(struct device *dev, int z80_addr, int jiffs, char resp1, char resp2)
+{
+   unsigned long start, done, now;
+   char          resp, *temp;
+
+   start = now = jiffies;
+   done = jiffies + jiffs;
+
+   temp = (void *)dev->mem_start;
+   temp += z80_addr & 0x1FFF;
+
+   resp = ~resp1;
+   while ((jiffies < done) && (resp != resp1) && (!resp2 || (resp != resp2)))
+   {
+      if (jiffies != now)
+      {
+         SDLA_WINDOW(dev, z80_addr);
+         now = jiffies;
+         resp = *temp;
+      }
+   }
+   return(jiffies < done ? jiffies - start : -1);
+}
+
+/* constants for Z80 CPU speed */
+#define Z80_READY              '1'     /* Z80 is ready to begin */
+#define LOADER_READY           '2'     /* driver is ready to begin */
+#define Z80_SCC_OK             '3'     /* SCC is on board */
+#define Z80_SCC_BAD            '4'     /* SCC was not found */
+
+static int sdla_cpuspeed(struct device *dev, struct ifreq *ifr)
+{
+   int  jiffs;
+   char data;
+
+   sdla_start(dev);
+   if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0)
+      return(-EIO);
+
+   data = LOADER_READY;
+   sdla_write(dev, 0, &data, 1);
+
+   if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0)
+      return(-EIO);
+
+   sdla_stop(dev);
+   sdla_read(dev, 0, &data, 1);
+
+   if (data == Z80_SCC_BAD)
+      return(-EIO);
+
+   if (data != Z80_SCC_OK)
+      return(-EINVAL);
+
+   if (jiffs < 165)
+      ifr->ifr_mtu = SDLA_CPU_16M;
+   else
+      if (jiffs < 220)
+         ifr->ifr_mtu = SDLA_CPU_10M;
+      else
+         if (jiffs < 258)
+            ifr->ifr_mtu = SDLA_CPU_8M;
+         else
+            if (jiffs < 357)
+               ifr->ifr_mtu = SDLA_CPU_7M;
+            else
+               if (jiffs < 467)
+                  ifr->ifr_mtu = SDLA_CPU_5M;
+               else
+                  ifr->ifr_mtu = SDLA_CPU_3M;
+   return(0);
+}
+
+/************************************************
+ *
+ *  Direct interaction with the Frame Relay code 
+ *  starts here.
+ *
+ ************************************************/
+
+struct _dlci_stat {
+   short dlci          __attribute__((packed));
+   char  flags         __attribute__((packed));
+};
+
+struct _frad_stat {
+   char    flags;
+   struct _dlci_stat dlcis[SDLA_MAX_DLCI];
+};
+
+static void sdla_errors(struct device *dev, int cmd, int dlci, int ret, int len, void *data) 
+{
+   struct _dlci_stat *pstatus;
+   short             *pdlci;
+   int               i;
+   char              *state;
+
+   switch (ret)
+   {
+      case SDLA_RET_MODEM:
+         state = data;
+         if (*state & SDLA_MODEM_DCD_LOW)
+            printk(KERN_NOTICE "%s: Modem DCD unexpectedly low!\n", dev->name);
+         if (*state & SDLA_MODEM_CTS_LOW)
+            printk(KERN_NOTICE "%s: Modem CTS unexpectedly low!\n", dev->name);
+/* I should probably do something about this! */
+         break;
+
+      case SDLA_RET_CHANNEL_OFF:
+         printk(KERN_NOTICE "%s: Channel became inoperative!\n", dev->name);
+/* same here */
+         break;
+
+      case SDLA_RET_CHANNEL_ON:
+         printk(KERN_NOTICE "%s: Channel became operative!\n", dev->name);
+/* same here */
+         break;
+
+      case SDLA_RET_DLCI_STATUS:
+         printk(KERN_NOTICE "%s: Status change reported by Access Node.\n", dev->name);
+         len /= sizeof(struct _dlci_stat);
+         for(pstatus = data, i=0;i < len;i++,pstatus++)
+         {
+            if (pstatus->flags & SDLA_DLCI_NEW)
+               state = "new";
+            else
+               if (pstatus->flags & SDLA_DLCI_DELETED)
+                  state = "deleted";
+               else
+                  if (pstatus->flags & SDLA_DLCI_ACTIVE)
+                     state = "active";
+                  else
+                     state = "unknown status";
+            printk(KERN_NOTICE "%s: DLCI %i: %s.\n", dev->name, pstatus->dlci, state);
+/* same here */
+         }
+         break;
+
+      case SDLA_RET_DLCI_UNKNOWN:
+         printk(KERN_DEBUG "%s: Received unknown DLCIs:", dev->name);
+         len /= 2;
+         for(pdlci = data,i=0;i < len;i++,pdlci++)
+            printk(" %i", *pdlci);
+         printk("\n");
+         break;
+
+      case SDLA_RET_TIMEOUT:
+         printk(KERN_ERR "%s: Command timed out!\n", dev->name);
+         break;
+
+      default: 
+         /*
+          * Further processing could be done here 
+          * printk(KERN_DEBUG "%s: Unhandled return code 0x%2.2X\n", dev->name, ret);
+          *
+          */
+   }
+}
+
+static int sdla_cmd(struct device *dev, int cmd, short dlci, short flags, 
+                        void *inbuf, short inlen, void *outbuf, short *outlen)
+{
+   static struct _frad_stat status;
+   struct frad_local        *flp;
+   struct sdla_cmd          *cmd_buf;
+   unsigned long            pflags;
+   int                      jiffs, ret, waiting, len;
+   long                     temp, window;
+
+   flp = dev->priv;
+
+   window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF;
+   temp = (int) dev->mem_start;
+   temp += window & 0x1FFF;
+   cmd_buf = (struct sdla_cmd *)temp;
+   ret = 0;
+   jiffs = jiffies + HZ / 2;  /* 1/2 second timeout */
+   save_flags(pflags);
+   cli();
+   SDLA_WINDOW(dev, window);
+   cmd_buf->cmd = cmd;
+   cmd_buf->dlci = dlci;
+   cmd_buf->flags = flags;
+
+   if (inbuf)
+      memcpy(cmd_buf->data, inbuf, inlen);
+
+   cmd_buf->length = inlen;
+
+   cmd_buf->opp_flag = 1;
+   restore_flags(pflags);
+
+   waiting = 1;
+   len = 0;
+   while (waiting && (jiffies <= jiffs))
+   {
+      if (waiting++ % 4) 
+      {
+         save_flags(pflags);
+         cli();
+         SDLA_WINDOW(dev, window);
+         waiting = ((volatile)(cmd_buf->opp_flag));
+         restore_flags(pflags);
+      }
+   }
+   
+   if (!waiting)
+   {
+      save_flags(pflags);
+      cli();
+      SDLA_WINDOW(dev, window);
+      ret = cmd_buf->retval;
+      len = cmd_buf->length;
+      if (outbuf && len)
+      {
+         *outlen = *outlen >= len ? len : *outlen;
+         memcpy(outbuf, cmd_buf->data, *outlen);
+      }
+      if (ret)
+         memcpy(&status, cmd_buf->data, len);
+      restore_flags(pflags);
+   }
+   else
+      ret = SDLA_RET_TIMEOUT;
+
+   if (ret != SDLA_RET_OK)
+      sdla_errors(dev, cmd, dlci, ret, len, &status);
+
+   return(ret);
+}
+
+/***********************************************
+ *
+ * these functions are called by the DLCI driver 
+ *
+ ***********************************************/
+
+static int sdla_reconfig(struct device *dev);
+
+int sdla_activate(struct device *slave, struct device *master)
+{
+   struct frad_local *flp;
+   int               i;
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->master[i] == master)
+         break;
+
+   if (i == CONFIG_DLCI_MAX)
+      return(-ENODEV);
+
+   flp->dlci[i] = abs(flp->dlci[i]);
+
+   if (slave->start && (flp->config.station == FRAD_STATION_NODE))
+      sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+int sdla_deactivate(struct device *slave, struct device *master)
+{
+   struct frad_local *flp;
+   int               i;
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->master[i] == master)
+         break;
+
+   flp->dlci[i] = -abs(flp->dlci[i]);
+
+   if (slave->start && (flp->config.station == FRAD_STATION_NODE))
+      sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+int sdla_assoc(struct device *slave, struct device *master)
+{
+   struct frad_local *flp;
+   int               i;
+
+   if (master->type != ARPHRD_DLCI)
+      return(-EINVAL);
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+   {
+      if (!flp->master[i])
+         break;
+      if (abs(flp->dlci[i]) == *(short *)(master->dev_addr))
+         return(-EADDRINUSE);
+   } 
+
+   if (i == CONFIG_DLCI_MAX)
+      return(-EMLINK);  /* #### Alan: Comments on this ?? */
+
+   MOD_INC_USE_COUNT;
+
+   flp->master[i] = master;
+   flp->dlci[i] = -*(short *)(master->dev_addr);
+   master->mtu = slave->mtu;
+
+   if (slave->start)
+      if (flp->config.station == FRAD_STATION_CPE)
+         sdla_reconfig(slave);
+      else
+         sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+int sdla_deassoc(struct device *slave, struct device *master)
+{
+   struct frad_local *flp;
+   int               i;
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->master[i] == master)
+         break;
+
+   if (i == CONFIG_DLCI_MAX)
+      return(-ENODEV);
+
+   flp->master[i] = NULL;
+   flp->dlci[i] = 0;
+
+   MOD_DEC_USE_COUNT;
+
+   if (slave->start)
+      if (flp->config.station == FRAD_STATION_CPE)
+         sdla_reconfig(slave);
+      else
+         sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+int sdla_dlci_conf(struct device *slave, struct device *master, int get)
+{
+   struct frad_local *flp;
+   struct frad_local *dlp;
+   int               i;
+
+   flp = slave->priv;
+
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->master[i] == master)
+         break;
+
+   if (i == CONFIG_DLCI_MAX)
+      return(-ENODEV);
+
+   dlp = master->priv;
+   if (slave->start)
+      sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, flp->dlci[i], 0,  
+                  &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL);
+
+   return(0);
+}
+
+/**************************
+ *
+ * now for the Linux driver 
+ *
+ **************************/
+
+static int sdla_transmit(struct sk_buff *skb, struct device *dev)
+{
+   struct frad_local *flp;
+   int               ret, addr;
+   short             size;
+   unsigned long     flags;
+   struct buf_entry  *pbuf;
+
+   flp = dev->priv;
+   ret = 0;
+
+   if (dev->tbusy) 
+      return(1);
+
+   if (skb == NULL) 
+      return(0);
+
+   if (set_bit(0, (void*)&dev->tbusy) != 0)
+      printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
+   else
+   {
+      switch (flp->type)
+      {
+         case SDLA_S502A:
+         case SDLA_S502E:
+            ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
+            break;
+
+         case SDLA_S508:
+            size = sizeof(addr);
+            ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
+            if (ret == SDLA_RET_OK)
+            {
+               save_flags(flags); 
+               cli();
+               SDLA_WINDOW(dev, addr);
+               pbuf = (void *)(((int) dev->mem_start) + (addr & 0x1FFF));
+
+               sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
+
+               SDLA_WINDOW(dev, addr);
+               pbuf->opp_flag = 1;
+               restore_flags(flags);
+            }
+            break;
+      }
+      switch (ret)
+      {
+         case SDLA_RET_OK:
+            flp->stats.tx_packets++;
+            ret = 0;
+            break;
+         default:
+            flp->stats.tx_errors++;
+            ret = 1;
+      }
+
+      /* per Alan Cox, we can drop the packet on the floor if it doesn't go */
+      dev_kfree_skb(skb, FREE_WRITE);
+
+      dev->tbusy = 0;
+   }
+   return(ret);
+}
+
+static void sdla_receive(struct device *dev)
+{
+   struct device     *master;
+   struct frad_local *flp;
+   struct dlci_local *dlp;
+   struct sk_buff    *skb;
+
+   struct sdla_cmd   *cmd;
+   struct buf_info   *pbufi;
+   struct buf_entry  *pbuf;
+
+   unsigned long     flags;
+   int               i, received, success, addr;
+   short             dlci, len, split;
+   char              bogus;
+
+   flp = dev->priv;
+   bogus = 0;
+   success = 0;
+   received = 0;
+   addr = 0;
+   skb = NULL;
+   master = NULL;
+
+   save_flags(flags);
+   cli();
+
+   switch (flp->type)
+   {
+      case SDLA_S502A:
+      case SDLA_S502E:
+         cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & 0x1FFF));
+         SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
+         if (!cmd->opp_flag)
+            break;
+
+         dlci = cmd->dlci;
+         len = cmd->length;
+
+         for (i=0;i<CONFIG_DLCI_MAX;i++)
+            if (flp->dlci[i] == dlci)
+               break;
+
+         if (i == CONFIG_DLCI_MAX)
+         {
+            printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
+            flp->stats.rx_errors++;
+            cmd->opp_flag = 0;
+            break;
+         }
+
+         master = flp->master[i];
+         skb = dev_alloc_skb(len);
+         if (skb == NULL) 
+         {
+            printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+            flp->stats.rx_dropped++;
+            cmd->opp_flag = 0;
+            break;
+         }
+
+         /* pick up the data */
+         sdla_read(dev, dev->mem_start + ((SDLA_502_RCV_BUF + SDLA_502_DATA_OFS) & 0x1FFF), skb_put(skb,len), len);
+         cmd->opp_flag = 0;
+         success = 1;
+         break;
+
+      case SDLA_S508:
+         pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & 0x1FFF));
+         SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
+         pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & 0x1FFF));
+         if (!pbuf->opp_flag)
+            break;
+
+         dlci = pbuf->dlci;
+         len = pbuf->length;
+         addr = pbuf->buf_addr;
+
+         for (i=0;i<CONFIG_DLCI_MAX;i++)
+            if (flp->dlci[i] == dlci)
+               break;
+
+         if (i == CONFIG_DLCI_MAX)
+         {
+            printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
+            flp->stats.rx_errors++;
+            pbuf->opp_flag = 0;
+            break;
+         }
+
+         master = flp->master[i];
+         skb = dev_alloc_skb(len);
+         if (skb == NULL) 
+         {
+            printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+            flp->stats.rx_dropped++;
+            pbuf->opp_flag = 0;
+            break;
+         }
+
+         /* is this buffer split off the end of the internal ring buffer */
+         split = addr + len > pbufi->buf_top + 1 ? pbufi->buf_top - addr + 1 : 0;
+         len -= split;
+
+         /* lets get the data */
+         sdla_read(dev, addr, skb_put(skb, len), len);
+         if (split)
+         {
+            SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
+            sdla_read(dev, pbufi->buf_base, skb_put(skb, split), split);
+         }
+
+         SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
+         pbuf->opp_flag = 0;
+         success = 1;
+
+         /* increment the buffer we're looking at */
+         flp->buffer = (flp->buffer + 1) % pbufi->rse_num;
+         break;
+   }
+
+   if (success)
+   {
+      flp->stats.rx_packets++;
+      dlp = master->priv;
+      (*dlp->receive)(skb, master);
+   }
+
+   restore_flags(flags);
+}
+
+static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
+{
+   struct device     *dev;
+   struct frad_local *flp;
+   char              byte;
+
+   dev = irq2dev_map[irq];
+
+   if (dev == NULL)
+   {
+      printk(KERN_WARNING "sdla_isr(): irq %d for unknown device.\n", irq);
+      return;
+   }
+
+   flp = dev->priv;
+
+   if (!flp->initialized)
+   {
+      printk(KERN_WARNING "%s: irq %d for unintialiazed device.\n", dev->name, irq);
+      return;
+   }
+
+   dev->interrupt = 1;
+   byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
+   switch (byte)
+   {
+      case SDLA_INTR_RX:
+         sdla_receive(dev);
+         break;
+
+      /* the command will get an error return, which is processed above */
+      case SDLA_INTR_MODEM:
+      case SDLA_INTR_STATUS:
+         sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
+         break;
+
+      case SDLA_INTR_TX:
+      case SDLA_INTR_COMPLETE:
+      case SDLA_INTR_TIMER:
+         printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte);
+         break;
+   }
+
+   /* the S502E requires a manual acknowledgement of the interrupt */ 
+   if (flp->type == SDLA_S502E)
+   {
+      flp->state &= ~SDLA_S502E_INTACK;
+      outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+      flp->state |= SDLA_S502E_INTACK;
+      outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+   }
+
+   dev->interrupt = 0;
+   /* this clears the byte, informing the Z80 we're done */
+   byte = 0;
+   sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
+}
+
+static void sdla_poll(unsigned long device)
+{
+   struct device     *dev;
+   struct frad_local *flp;
+
+   dev = (struct device *) device;
+   flp = dev->priv;
+
+   if (sdla_byte(dev, SDLA_502_RCV_BUF))
+      sdla_receive(dev);
+
+   flp->timer.expires = 1;
+   add_timer(&flp->timer);
+}
+
+static int sdla_close(struct device *dev)
+{
+   struct frad_local *flp;
+   struct intr_info  intr;
+   int               len, i;
+   short             dlcis[CONFIG_DLCI_MAX];
+
+   flp = dev->priv;
+
+   len = 0;
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->dlci[i])
+         dlcis[len++] = abs(flp->dlci[i]);
+   len *= 2;
+
+   if (flp->config.station == FRAD_STATION_NODE)
+   {
+      for(i=0;i<CONFIG_DLCI_MAX;i++)
+         if (flp->dlci[i] > 0) 
+            sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
+      sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
+   }
+
+   memset(&intr, 0, sizeof(intr));
+   /* lets start up the reception */
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+         del_timer(&flp->timer); 
+         break;
+
+      case SDLA_S502E:
+         sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
+         flp->state &= ~SDLA_S502E_INTACK;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+
+      case SDLA_S507:
+         break;
+
+      case SDLA_S508:
+         sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
+         flp->state &= ~SDLA_S508_INTEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         break;
+   }
+
+   sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+   sdla_stop(dev);
+
+   dev->tbusy = 1;
+   dev->start = 0;
+
+   MOD_DEC_USE_COUNT;
+
+   return(0);
+}
+
+struct conf_data {
+   struct frad_conf config;
+   short            dlci[CONFIG_DLCI_MAX];
+};
+
+static int sdla_open(struct device *dev)
+{
+   struct frad_local *flp;
+   struct dlci_local *dlp;
+   struct conf_data  data;
+   struct intr_info  intr;
+   int               len, i;
+   char              byte;
+
+   flp = dev->priv;
+
+   if (!flp->initialized)
+      return(-EPERM);
+
+   if (!flp->configured)
+      return(-EPERM);
+
+   /* off to the races! */
+   sdla_start(dev);
+
+   /* time to send in the configuration */
+   len = 0;
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->dlci[i])
+         data.dlci[len++] = abs(flp->dlci[i]);
+   len *= 2;
+
+   memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
+   len += sizeof(struct frad_conf);
+
+   sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+   sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
+
+   if (flp->type == SDLA_S508)
+      flp->buffer = 0;
+
+   sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+
+   /* lets start up the reception */
+   memset(&intr, 0, sizeof(intr));
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+         flp->timer.expires = 1;
+         add_timer(&flp->timer);
+         break;
+
+      case SDLA_S502E:
+         flp->state |= SDLA_S502E_ENABLE;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         flp->state |= SDLA_S502E_INTACK;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         byte = 0;
+         sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
+         intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
+         sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
+         break;
+
+      case SDLA_S507:
+         break;
+
+      case SDLA_S508:
+         flp->state |= SDLA_S508_INTEN;
+         outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+         byte = 0;
+         sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
+         intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
+         intr.irq = dev->irq;
+         sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
+         break;
+   }
+
+   if (flp->config.station == FRAD_STATION_CPE)
+   {
+      byte = SDLA_ICS_STATUS_ENQ;
+      sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
+   }
+   else
+   {
+      sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
+      for(i=0;i<CONFIG_DLCI_MAX;i++)
+         if (flp->dlci[i] > 0)
+            sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
+   }
+
+   /* configure any specific DLCI settings */
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->dlci[i])
+      {
+         dlp = flp->master[i]->priv;
+         if (dlp->configured)
+            sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
+      }
+
+   dev->tbusy = 0;
+   dev->interrupt = 0;
+   dev->start = 1;
+
+   MOD_INC_USE_COUNT;
+
+   return(0);
+}
+
+static int sdla_config(struct device *dev, struct frad_conf *conf, int get)
+{
+   struct frad_local *flp;
+   struct conf_data  data;
+   int               i, err;
+
+   if (dev->type == 0xFFFF)
+      return(-EUNATCH);
+
+   flp = dev->priv;
+
+   if (!get)
+   {
+      if (dev->start)
+         return(-EBUSY);
+
+      err = verify_area(VERIFY_READ, conf, sizeof(struct frad_conf));
+      if (err)
+         return(err);
+
+      memcpy_fromfs(&data.config, conf, sizeof(struct frad_conf));
+
+      if (data.config.station & ~FRAD_STATION_NODE)
+         return(-EINVAL);
+
+      if (data.config.flags & ~FRAD_VALID_FLAGS)
+         return(-EINVAL);
+
+      if ((data.config.kbaud < 0) || 
+          ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
+         return(-EINVAL);
+
+      if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
+         return(-EINVAL);
+
+      if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
+         return(-EINVAL);
+
+      if ((data.config.T391 < 5) || (data.config.T391 > 30))
+         return(-EINVAL);
+
+      if ((data.config.T392 < 5) || (data.config.T392 > 30))
+         return(-EINVAL);
+
+      if ((data.config.N391 < 1) || (data.config.N391 > 255))
+         return(-EINVAL);
+
+      if ((data.config.N392 < 1) || (data.config.N392 > 10))
+         return(-EINVAL);
+
+      if ((data.config.N393 < 1) || (data.config.N393 > 10))
+         return(-EINVAL);
+
+      memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
+      flp->config.flags |= SDLA_DIRECT_RECV;
+
+      if (dev->mtu != flp->config.mtu)
+      {
+         /* this is required to change the MTU */
+         dev->mtu = flp->config.mtu;
+         for(i=0;i<CONFIG_DLCI_MAX;i++)
+            if (flp->master[i])
+               flp->master[i]->mtu = flp->config.mtu;
+      }
+
+      flp->config.mtu += sizeof(struct fradhdr);
+      flp->configured = 1;
+   }
+   else
+   {
+      err = verify_area(VERIFY_WRITE, conf, sizeof(struct frad_conf));
+      if (err)
+         return(err);
+
+      sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, &data, sizeof(data), NULL, NULL);
+      memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
+
+      data.config.flags &= ~SDLA_DIRECT_RECV;
+      data.config.mtu -= sizeof(struct fradhdr);
+      memcpy_tofs(conf, &data.config, sizeof(struct frad_conf));
+   }
+
+   return(0);
+}
+
+static int sdla_xfer(struct device *dev, struct sdla_mem *info, int read)
+{
+   struct sdla_mem mem;
+   int    err;
+   char   *temp;
+
+   err = verify_area(VERIFY_READ, info, sizeof(struct sdla_mem));
+   if (err)
+      return(err);
+
+   memcpy_fromfs(&mem, info, sizeof(mem));
+   if (read)
+   {
+      err = verify_area(VERIFY_WRITE, mem.data, mem.len);
+      if (err)
+         return(err);
+
+      temp = kmalloc(mem.len, GFP_KERNEL);
+      if (!temp)
+         return(-ENOMEM);
+      sdla_read(dev, mem.addr, temp, mem.len);
+      memcpy_tofs(mem.data, temp, mem.len);
+      kfree(temp);
+   }
+   else
+   {
+      err = verify_area(VERIFY_READ, mem.data, mem.len);
+      if (err)
+         return(err);
+
+      temp = kmalloc(mem.len, GFP_KERNEL);
+      if (!temp)
+         return(-ENOMEM);
+      memcpy_fromfs(temp, mem.data, mem.len);
+      sdla_write(dev, mem.addr, temp, mem.len);
+      kfree(temp);
+   }
+   return(0);
+}
+
+static int sdla_reconfig(struct device *dev)
+{
+   struct frad_local *flp;
+   struct conf_data  data;
+   int               i, len;
+
+   flp = dev->priv;
+
+   memcpy(&data, &flp->config, sizeof(struct frad_conf));
+
+   len = 0;
+   for(i=0;i<CONFIG_DLCI_MAX;i++)
+      if (flp->dlci[i])
+         data.dlci[len++] = flp->dlci[i];
+   len *= 2;
+   len += sizeof(struct frad_conf);
+
+   sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+   sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
+   sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
+
+   return(0);
+}
+
+static int sdla_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+
+   if (!flp->initialized)
+      return(-EPERM);
+
+   switch (cmd)
+   {
+      case FRAD_GET_CONF:
+      case FRAD_SET_CONF:
+         return(sdla_config(dev, (struct frad_conf *)ifr->ifr_data, cmd == FRAD_GET_CONF));
+
+      case SDLA_IDENTIFY:
+         ifr->ifr_flags = flp->type;
+         break;
+
+      case SDLA_CPUSPEED:
+         return(sdla_cpuspeed(dev, ifr)); 
+
+/* ==========================================================
+NOTE:  This is rather a useless action right now, as the
+       driver does not support protocols other than FR right
+       now.  However, Sangoma has modules for a number of
+       other protocols.
+============================================================*/
+      case SDLA_PROTOCOL:
+         if (flp->configured)
+            return(-EALREADY);
+
+         switch (ifr->ifr_flags)
+         {
+            case ARPHRD_FRAD:
+               dev->type = ifr->ifr_flags;
+               dev->family = AF_UNSPEC;
+               break;
+
+            default:
+               return(-ENOPROTOOPT);
+         }
+         break;
+
+      case SDLA_CLEARMEM:
+         sdla_clear(dev);
+         break;
+
+      case SDLA_WRITEMEM:
+      case SDLA_READMEM:
+         return(sdla_xfer(dev, (struct sdla_mem *)ifr->ifr_data, cmd == SDLA_READMEM));
+
+      case SDLA_START:
+         sdla_start(dev);
+         break;
+
+      case SDLA_STOP:
+         sdla_stop(dev);
+         break;
+
+      default:
+         return(-EOPNOTSUPP);
+   }
+   return(0);
+}
+
+int sdla_change_mtu(struct device *dev, int new_mtu)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+
+   if (dev->start)
+      return(-EBUSY);
+
+   /* for now, you can't change the MTU! */
+   return(-EACCES);
+}
+
+int sdla_set_config(struct device *dev, struct ifmap *map)
+{
+   struct frad_local *flp;
+   int               i;
+   char              byte;
+
+   flp = dev->priv;
+
+   if (flp->initialized)
+      return(-EINVAL);
+
+   for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
+      if (valid_port[i] == map->base_addr)
+         break;   
+
+   if (i == sizeof(valid_port) / sizeof(int))
+      return(-EINVAL);
+
+   dev->base_addr = map->base_addr;
+   request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name);
+
+   /* test for card types, S502A, S502E, S507, S508                 */
+   /* these tests shut down the card completely, so clear the state */
+   flp->type = SDLA_UNKNOWN;
+   flp->state = 0;
+   
+   for(i=1;i<SDLA_IO_EXTENTS;i++)
+      if (inb(dev->base_addr + i) != 0xFF)
+        break;
+
+   if (i == SDLA_IO_EXTENTS)
+   {   
+      outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
+      if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x08)
+      {
+         outb(SDLA_S502E_INTACK, dev->base_addr + SDLA_REG_CONTROL);
+         if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x0C)
+         {
+            outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+            flp->type = SDLA_S502E;
+         }
+      }
+   }
+
+   if (flp->type == SDLA_UNKNOWN)
+   {
+      for(byte=inb(dev->base_addr),i=0;i<SDLA_IO_EXTENTS;i++)
+         if (inb(dev->base_addr + i) != byte)
+            break;
+
+      if (i == SDLA_IO_EXTENTS)
+      {
+         outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+         if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x30)
+         {
+            outb(SDLA_S507_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
+            if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x32)
+            {
+               outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+               flp->type = SDLA_S507;
+            }
+         }
+      }
+   }
+
+   if (flp->type == SDLA_UNKNOWN)
+   {
+      outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+      if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x00)
+      {
+         outb(SDLA_S508_INTEN, dev->base_addr + SDLA_REG_CONTROL);
+         if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x10)
+         {
+            outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
+            flp->type = SDLA_S508;
+         }
+      }
+   }
+
+   if (flp->type == SDLA_UNKNOWN)
+   {
+      outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
+      if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
+      {
+         outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
+         if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
+         {
+            outb(SDLA_S502A_INTEN, dev->base_addr + SDLA_REG_CONTROL);
+            if (inb(dev->base_addr + SDLA_S502_STS) == 0x44)
+            {
+               outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
+               flp->type = SDLA_S502A;
+            }
+         }
+      }
+   }
+
+   if (flp->type == SDLA_UNKNOWN)
+   {
+      printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
+      return(-ENODEV);
+   }
+
+   switch(dev->base_addr)
+   {
+      case 0x270:
+      case 0x280:
+      case 0x380: 
+      case 0x390:
+         if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
+            return(-EINVAL);
+   }
+
+   switch (map->irq)
+   {
+      case 2:
+         if (flp->type != SDLA_S502E)
+            return(-EINVAL);
+         break;
+
+      case 10:
+      case 11:
+      case 12:
+      case 15:
+      case 4:
+         if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
+            return(-EINVAL);
+
+      case 3:
+      case 5:
+      case 7:
+         if (flp->type == SDLA_S502A)
+            return(-EINVAL);
+         break;
+
+      default:
+         return(-EINVAL);
+   }
+   dev->irq = map->irq;
+
+   if (request_irq(dev->irq, &sdla_isr, 0, dev->name, NULL)) 
+      return(-EADDRINUSE);
+
+   irq2dev_map[dev->irq] = dev;
+
+   if (flp->type == SDLA_S507)
+   {
+      switch(dev->irq)
+      {
+         case 3:
+            flp->state = SDLA_S507_IRQ3;
+            break;
+         case 4:
+            flp->state = SDLA_S507_IRQ4;
+            break;
+         case 5:
+            flp->state = SDLA_S507_IRQ5;
+            break;
+         case 7:
+            flp->state = SDLA_S507_IRQ7;
+            break;
+         case 10:
+            flp->state = SDLA_S507_IRQ10;
+            break;
+         case 11:
+            flp->state = SDLA_S507_IRQ11;
+            break;
+         case 12:
+            flp->state = SDLA_S507_IRQ12;
+            break;
+         case 15:
+            flp->state = SDLA_S507_IRQ15;
+            break;
+      }
+   }
+
+   for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
+      if (valid_mem[i] == map->mem_start)
+         break;   
+
+   if (i == sizeof(valid_mem) / sizeof(int))
+      return(-EINVAL);
+
+   if ((flp->type == SDLA_S502A) && (((map->mem_start & 0xF000) >> 12) == 0x0E))
+      return(-EINVAL);
+
+   if ((flp->type != SDLA_S507) && ((map->mem_start >> 16) == 0x0B))
+      return(-EINVAL);
+
+   if ((flp->type == SDLA_S507) && ((map->mem_start >> 16) == 0x0D))
+      return(-EINVAL);
+
+   dev->mem_start = map->mem_start;
+   dev->mem_end = dev->mem_start + 0x2000;
+
+   byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
+   byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
+   switch(flp->type)
+   {
+      case SDLA_S502A:
+      case SDLA_S502E:
+         switch (map->mem_start >> 16)
+         {
+            case 0x0A:
+               byte |= SDLA_S502_SEG_A;
+               break;
+            case 0x0C:
+               byte |= SDLA_S502_SEG_C;
+               break;
+            case 0x0D:
+               byte |= SDLA_S502_SEG_D;
+               break;
+            case 0x0E:
+               byte |= SDLA_S502_SEG_E;
+               break;
+         }
+         break;
+      case SDLA_S507:
+         switch (map->mem_start >> 16)
+         {
+            case 0x0A:
+               byte |= SDLA_S507_SEG_A;
+               break;
+            case 0x0B:
+               byte |= SDLA_S507_SEG_B;
+               break;
+            case 0x0C:
+               byte |= SDLA_S507_SEG_C;
+               break;
+            case 0x0E:
+               byte |= SDLA_S507_SEG_E;
+               break;
+         }
+         break;
+      case SDLA_S508:
+         switch (map->mem_start >> 16)
+         {
+            case 0x0A:
+               byte |= SDLA_S508_SEG_A;
+               break;
+            case 0x0C:
+               byte |= SDLA_S508_SEG_C;
+               break;
+            case 0x0D:
+               byte |= SDLA_S508_SEG_D;
+               break;
+            case 0x0E:
+               byte |= SDLA_S508_SEG_E;
+               break;
+         }
+         break;
+   }
+
+   /* set the memory bits, and enable access */
+   outb(byte, dev->base_addr + SDLA_REG_PC_WINDOW);
+   switch(flp->type)
+   {
+      case SDLA_S502E:
+         flp->state = SDLA_S502E_ENABLE;
+         break;
+      case SDLA_S507:
+         flp->state |= SDLA_MEMEN;
+         break;
+      case SDLA_S508:
+         flp->state = SDLA_MEMEN;
+         break;
+   }
+   outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
+
+   flp->initialized = 1;
+   return(0);
+}
+static struct enet_statistics *sdla_stats(struct device *dev)
+{
+   struct frad_local *flp;
+
+   flp = dev->priv;
+
+   return(&flp->stats);
+}
+
+int sdla_init(struct device *dev)
+{
+   struct frad_local *flp;
+   int               i;
+
+   /* allocate the private data structure */
+   flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL);
+   if (!flp)
+      return(-ENOMEM);
+
+   memset(flp, 0, sizeof(struct frad_local));
+   dev->priv = flp;
+
+   dev->flags           = 0;
+   dev->open            = sdla_open;
+   dev->stop            = sdla_close;
+   dev->do_ioctl        = sdla_ioctl;
+   dev->set_config      = sdla_set_config;
+   dev->get_stats       = sdla_stats;
+   dev->hard_start_xmit = sdla_transmit;
+   dev->change_mtu     = sdla_change_mtu;
+
+   dev->type            = 0xFFFF;
+   dev->family          = AF_UNSPEC;
+   dev->pa_alen         = sizeof(unsigned long);
+   dev->hard_header_len = 0;
+   dev->mtu             = SDLA_MAX_MTU;
+
+   for (i = 0; i < DEV_NUMBUFFS; i++) 
+      skb_queue_head_init(&dev->buffs[i]);
+
+   flp->activate        = sdla_activate;
+   flp->deactivate      = sdla_deactivate;
+   flp->assoc           = sdla_assoc;
+   flp->deassoc         = sdla_deassoc;
+   flp->dlci_conf       = sdla_dlci_conf;
+
+   init_timer(&flp->timer);
+   flp->timer.expires   = 1;
+   flp->timer.data      = (unsigned long) dev;
+   flp->timer.function  = sdla_poll;
+
+   return(0);
+}
+
+void sdla_setup(void)
+{
+   printk("%s.\n", version);
+   register_frad(devname);
+}
+
+#ifdef MODULE
+static struct device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init};
+
+int init_module(void)
+{
+   int result;
+
+   sdla_setup();
+   if ((result = register_netdev(&sdla0)) != 0)
+      return result;
+
+   return 0;
+}
+
+void cleanup_module(void)
+{
+   unregister_netdev(&sdla0);
+   if (sdla0.priv)
+      kfree(sdla0.priv);
+   if (sdla0.irq)
+      free_irq(sdla0.irq, NULL);
+}
+#endif /* MODULE */
index 99403e8afb47e9512b57c2ff2b3ab39d516e62cb..555d6b3a7e7b60b6ffbff8ff72440250920a8b81 100644 (file)
@@ -73,7 +73,6 @@ struct pci_dev_info dev_info[] = {
        DEVICE( CIRRUS,         CIRRUS_5434_4,  "GD 5434"),
        DEVICE( CIRRUS,         CIRRUS_5434_8,  "GD 5434"),
        DEVICE( CIRRUS,         CIRRUS_5436,    "GD 5436"),
-       DEVICE( CIRRUS,         CIRRUS_6205,    "GD 6205"),
        DEVICE( CIRRUS,         CIRRUS_6729,    "CL 6729"),
        DEVICE( CIRRUS,         CIRRUS_7542,    "CL 7542"),
        DEVICE( CIRRUS,         CIRRUS_7543,    "CL 7543"),
@@ -90,9 +89,11 @@ struct pci_dev_info dev_info[] = {
        DEVICE( MATROX,         MATROX_MGA_IMP, "MGA Impression"),
        DEVICE( CT,             CT_65545,       "65545"),
        DEVICE( CT,             CT_65548,       "65548"),
+       DEVICE( MIRO,           MIRO_36050,     "ZR36050"),
        DEVICE( FD,             FD_36C70,       "TMC-18C30"),
        DEVICE( SI,             SI_6201,        "6201"),
        DEVICE( SI,             SI_6202,        "6202"),
+       DEVICE( SI,             SI_6205,        "6205"),
        DEVICE( SI,             SI_503,         "85C503"),
        DEVICE( SI,             SI_501,         "85C501"),
        DEVICE( SI,             SI_496,         "85C496"),
@@ -163,11 +164,25 @@ struct pci_dev_info dev_info[] = {
        DEVICE( VIA,            VIA_82C561,     "VT 82C561"),
        DEVICE( VIA,            VIA_82C576,     "VT 82C576 3V"),
        DEVICE( VIA,            VIA_82C416,     "VT 82C416MV"),
-       DEVICE( VORTEX,         VORTEX_GDT,     "GDT 6000b"),
+       DEVICE( VORTEX,         VORTEX_GDT60x0, "GDT 60x0"),
+       DEVICE( VORTEX,         VORTEX_GDT6000B,"GDT 6000b"),
+       DEVICE( VORTEX,         VORTEX_GDT6x10, "GDT 6110/6510"),
+       DEVICE( VORTEX,         VORTEX_GDT6x20, "GDT 6120/6520"),
+       DEVICE( VORTEX,         VORTEX_GDT6530, "GDT 6530"),
+       DEVICE( VORTEX,         VORTEX_GDT6550, "GDT 6550"),
+       DEVICE( VORTEX,         VORTEX_GDT6x17, "GDT 6117/6517"),
+       DEVICE( VORTEX,         VORTEX_GDT6x27, "GDT 6127/6527"),
+       DEVICE( VORTEX,         VORTEX_GDT6537, "GDT 6537"),
+       DEVICE( VORTEX,         VORTEX_GDT6557, "GDT 6557"),
+       DEVICE( VORTEX,         VORTEX_GDT6x15, "GDT 6115/6515"),
+       DEVICE( VORTEX,         VORTEX_GDT6x25, "GDT 6125/6525"),
+       DEVICE( VORTEX,         VORTEX_GDT6535, "GDT 6535"),
+       DEVICE( VORTEX,         VORTEX_GDT6555, "GDT 6555"),
        DEVICE( EF,             EF_ATM_FPGA,            "155P-MF1 (FPGA)"),
        DEVICE( EF,             EF_ATM_ASIC,    "155P-MF1 (ASIC)"),
        DEVICE( IMAGINGTECH,    IMAGINGTECH_ICPCI, "MVC IC-PCI"),
        DEVICE( FORE,           FORE_PCA200PC, "PCA-200PC"),
+       DEVICE( FORE,           FORE_PCA200E,    "PCA-200E"),
        DEVICE( PLX,            PLX_9060,       "PCI9060 i960 bridge"),
        DEVICE( ALLIANCE,       ALLIANCE_PROMOTIO, "Promotion-6410"),
        DEVICE( ALLIANCE,       ALLIANCE_PROVIDEO, "Provideo"),
index 6d3e3ef03e81816b5039b4ff321a8bbabbd7a1b0..945606028599edbfaab0cdccce23e0bb6f81b200 100644 (file)
@@ -2185,7 +2185,7 @@ static int NCR5380_transfer_dma (struct Scsi_Host *instance,
 
     *data = d + c;
     *count = 0;
-    *phase = (NCR5380_read(STATUS_REG & PHASE_MASK));
+    *phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
 #if 0
     NCR5380_print_phase(instance);
 #endif
index 632093e69849a483d14f36c8fc5d9a9d51934ba4..7c196409db6f5a86452aca128b4808e01f4694b4 100644 (file)
@@ -1,4 +1,4 @@
-REAME file for the Linux g_NCR5380 driver.
+README file for the Linux g_NCR5380 driver.
 
 (c) 1993 Drew Eckhard
 NCR53c400 extensions (c) 1994,1995,1996 Kevin Lentin
index 713c8d0509d1bb786ac55f7504e3ad5b70f8bb7b..9a83e720020646e6ded2b3864299e222ca936ea6 100644 (file)
@@ -982,6 +982,9 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
                                   get resources.  */
 
    shpnt = scsi_register( tpnt, 0 );
+   shpnt->irq = interrupt_level;
+   shpnt->io_port = port_base;
+   shpnt->n_io_port = 0x10;
    print_banner( shpnt );
 
                                /* Log IRQ with kernel */   
index f1258585fd6cdc5be84f704c4ae54652beb2c0d8..ea1d67e77b2c793bc4e4c91745faea6d0a39d8cc 100644 (file)
@@ -2153,7 +2153,7 @@ static int update_timeout(Scsi_Cmnd * SCset, int timeout)
     
     if(SCset){
        oldto = SCset->timeout - used;
-       SCset->timeout = timeout + used;
+       SCset->timeout = timeout;
     }
 
     least = 0xffffffff;
@@ -2161,7 +2161,8 @@ static int update_timeout(Scsi_Cmnd * SCset, int timeout)
     for(host = scsi_hostlist; host; host = host->next)
        for(SCpnt = host->host_queue; SCpnt; SCpnt = SCpnt->next)
            if (SCpnt->timeout > 0) {
-               SCpnt->timeout -= used;
+               if (SCpnt != SCset)
+                 SCpnt->timeout -= used;
                if(SCpnt->timeout <= 0) SCpnt->timeout = -1;
                if(SCpnt->timeout > 0 && SCpnt->timeout < least)
                    least = SCpnt->timeout;
index a4e569424048d552b61ffa7a14c30b796f08fa3a..6e73b9e973382167b8e48be02cf1b46f0bf37ad5 100644 (file)
@@ -514,7 +514,7 @@ static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors
  * turned off 
  */
 #define INIT_SCSI_REQUEST       \
-    if (!CURRENT) {             \
+    if (!CURRENT || CURRENT_PLUGGED) {     \
        CLEAR_INTR;             \
        restore_flags(flags);   \
        return;                 \
index 1f5155addc2e943478fff7583ec54c7e340846f1..5359c33411d0a27679c12f2d6e75312ed4f4cb30 100644 (file)
@@ -19,6 +19,7 @@
 #include "scsi_ioctl.h"
 #include "hosts.h"
 #include "sd.h"
+#include <linux/scsicam.h>     /* must follow "hosts.h" */
 
 int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
 {
index 8a3d0c91117f23f33b008eaaa5191e694e73bd49..5caf251b060c7a53cc9f3868b083e04dde6606af 100644 (file)
@@ -1,2 +1,2 @@
-3.5
+3.5.1
 0x030500
index 421c2719c575f6e217f7997f9e51ae9d2e022b7f..2574a3e7f9bdbd6356ab6aa6c1163c2677af3b80 100644 (file)
@@ -1,5 +1,5 @@
-Changelog for version 3.5
--------------------------
+Changelog for version 3.5.1
+---------------------------
 
 Since 3.5
 - Improved handling of playback underrunt situations.
index c9d1fec52f81403231c0494a053b40513d26d285..225fadc2ab1d9cc21d748640c23ebfa01a62acc9 100644 (file)
@@ -30,6 +30,7 @@ TOPDIR=/usr/src/linux
 endif
 
 
+ifndef HOSTCC
 build:
        @echo Compiling modularized sound driver
        @make sound.o
@@ -37,6 +38,7 @@ build:
 
 install:       sound.o
        cp sound.o $(MODULEDIR)
+endif
 
 .c.o:
        $(CC) $(CFLAGS) -c $<
index 1c65fb427ab622b32af033f27f5a0fe7969dbbe2..6c8c07635bb5d729cc5d268c6ce617d9a79c643a 100644 (file)
@@ -1,5 +1,5 @@
-Version 3.5-beta11 release notes
---------------------------------
+Version 3.5.1 release notes
+---------------------------
 
 Most up to date information about this driver is available from 
 http://personal.eunet.fi/pp/voxware.
index 17f58e2f2635ec10215b0b769986f3bd6c5a2196..93eaacb937434865d551a2e26cfad587e21ba8d7 100644 (file)
@@ -601,8 +601,7 @@ the file when configuring the driver. The easiest way is to mount the DOS
 partition containing the file with Linux. 
 
 It's possible to load your own DSP algorithms and run them with the card.
-Look at the directory pss_test of snd-util-3.0.tar.gz for more info.§
-package.
+Look at the directory pss_test of snd-util-3.0.tar.gz for more info.
 
 AudioTriX Pro
 -------------
@@ -689,9 +688,6 @@ are terrible), just modify ssinit.c to use another microcode file and try
 again. It's possible to use an earlier version of sndscape.co[01] but it
 may sound wierd.
 
-Btw, The driver may complain something about "sscapeintr()" after
-running ssinit. You should just ignore these messages.
-
 MAD16 (Pro) and Mozart
 ----------------------
 
index 0939d8de317218ed04a0a9460ba67f4dbe2bacbc..bb5fc70776f0b0fabf4c62cbbf6a7dab005252c2 100644 (file)
@@ -1152,9 +1152,9 @@ ad1848_detect (int io_base, int *ad_flags, int *osp)
 {
 
   unsigned char   tmp;
-  int             i;
   ad1848_info    *devc = &dev_info[nr_ad1848_devs];
   unsigned char   tmp1 = 0xff, tmp2 = 0xff;
+  int             i;
 
   DDB (printk ("ad1848_detect(%x)\n", io_base));
 
@@ -1201,6 +1201,11 @@ ad1848_detect (int io_base, int *ad_flags, int *osp)
       return 0;
     }
 
+  DDB (printk ("ad1848: regs: "));
+  for (i = 0; i < 32; i++)
+    DDB (printk ("%02x ", ad_read (devc, i)));
+  DDB (printk ("\n"));
+
   /*
      * Test if it's possible to change contents of the indirect registers.
      * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
@@ -1254,15 +1259,6 @@ ad1848_detect (int io_base, int *ad_flags, int *osp)
      * with CS4231.
    */
 
-  DDB (printk ("ad1848_detect() - step F\n"));
-  ad_write (devc, 12, 0);      /* Mode2=disabled */
-
-  for (i = 0; i < 16; i++)
-    if ((tmp1 = ad_read (devc, i)) != (tmp2 = ad_read (devc, i + 16)))
-      {
-       DDB (printk ("ad1848 detect error - step F(%d/%x/%x)\n", i, tmp1, tmp2));
-       return 0;
-      }
 
   /*
      * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit (0x40).
index 4a7a8d9251001d928a40f8c99807f60d24027238..ef6dba813d2c5dcda38cd79f907d298007f7db2e 100644 (file)
@@ -51,7 +51,7 @@ static int      audio_format[MAX_AUDIO_DEV];
 static int      local_conversion[MAX_AUDIO_DEV];
 
 static int
-set_format (int dev, int fmt)
+set_format (int dev, long fmt)
 {
   if (fmt != AFMT_QUERY)
     {
@@ -80,7 +80,7 @@ int
 audio_open (int dev, struct fileinfo *file)
 {
   int             ret;
-  int             bits;
+  long            bits;
   int             dev_type = dev & 0x0f;
   int             mode = file->mode & O_ACCMODE;
 
@@ -128,13 +128,31 @@ audio_open (int dev, struct fileinfo *file)
 void
 sync_output (int dev)
 {
-  int             buf_no, buf_ptr, buf_size;
+  int             buf_no, buf_ptr, buf_size, p, i;
   char           *dma_buf;
+  struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
 
   if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
     {
       DMAbuf_start_output (dev, buf_no, buf_ptr);
     }
+
+/*
+ * Clean all unused buffer fragments.
+ */
+
+  p = dmap->qtail;
+
+  for (i = dmap->qlen; i < dmap->nbufs; i++)
+    {
+      memset (dmap->raw_buf + p * dmap->fragment_size,
+             dmap->neutral_byte,
+             dmap->fragment_size);
+
+      p = (p + 1) % dmap->nbufs;
+    }
+
+  dmap->flags |= DMA_CLEAN;
 }
 
 void
index 170da9214a6d482bcc645207eb57948b5f44dd06..41321eb0a61df85679c3242f982127da99794b94 100644 (file)
@@ -1,13 +1,36 @@
 /*
- *      PnP soundcard support is not included in this version.
+ *     PnP soundcard support is not included in this version.
  *
- *      AEDSP16 will not work without significant changes.
+ *       AEDSP16 will not work without significant changes.
  */
 #define DISABLED_OPTIONS       (B(OPT_SPNP)|B(OPT_AEDSP16)|B(OPT_UNUSED1)|B(OPT_UNUSED2))
 /*
  * sound/configure.c  - Configuration program for the Linux Sound Driver
  */
-#define COPYING2
+/*
+ * Copyright by Hannu Savolainen 1993-1996
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 2.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
 
 #include <stdio.h>
 #include <unistd.h>
@@ -56,7 +79,7 @@
 #define ANY_DEVS (B(OPT_AUDIO)|B(OPT_MIDI)|B(OPT_GUS)| \
                  B(OPT_MPU401)|B(OPT_PSS)|B(OPT_GUS16)|B(OPT_GUSMAX)| \
                  B(OPT_MSS)|B(OPT_SSCAPE)|B(OPT_UART6850)|B(OPT_TRIX)| \
-                 B(OPT_MAD16)|B(OPT_CS4232)|B(OPT_MAUI))
+                 B(OPT_MAD16)|B(OPT_CS4232)|B(OPT_MAUI)|B(OPT_ADLIB))
 #define AUDIO_CARDS (B (OPT_PSS) | B (OPT_SB) | B (OPT_PAS) | B (OPT_GUS) | \
                B (OPT_MSS) | B (OPT_GUS16) | B (OPT_GUSMAX) | B (OPT_TRIX) | \
                B (OPT_SSCAPE)| B(OPT_MAD16) | B(OPT_CS4232))
@@ -221,7 +244,7 @@ char           *help[] =
   "them. In addition the MAD16 chip is used in some cards made by known\n"
   "manufacturers such as Turtle Beach (Tropez), Reveal (some models) and\n"
   "Diamond (latest ones).\n",
-  
+
   "Enable this if you have a card based on the Crystal CS4232 chip set.\n",
 
   "Enable this option if you have a Turtle Beach Wave Front, Maui,\n"
@@ -246,7 +269,7 @@ char           *help[] =
   "This enables the dev/midixx devices and access to any MIDI ports\n"
   "using /dev/sequencer and /dev/music. This option also affects any\n"
   "MPU401 and/or General MIDI compatible devices.\n",
-  
+
   "This should not be asked",
 
   "This enables the Yamaha FM synthesizer chip used on many sound\n"
@@ -297,21 +320,6 @@ int             bin2hex (char *path, char *target, char *varname);
 int
 can_select_option (int nr)
 {
-#if 0
-  switch (nr)
-    {
-    case OPT_LAST_MUTUAL + 1:
-      fprintf (stderr, "\nThe following cards should work with any other cards.\n"
-              "CAUTION! Don't enable MPU-401 if you don't have it.\n");
-      break;
-
-    case OPT_HIGHLEVEL:
-      fprintf (stderr, "\nSelect one or more of the following options\n");
-      break;
-
-
-    }
-#endif
 
   if (hw_table[nr].conditions)
     if (!(hw_table[nr].conditions & selected_options))
@@ -333,12 +341,12 @@ think_positively (char *prompt, int def_answ, char *help)
   char            answ[512];
   int             len;
 
-  response:
-  fprintf(stderr, prompt);
+response:
+  fprintf (stderr, prompt);
   if (def_answ)
-    fprintf(stderr, " [Y/n/?] ");
+    fprintf (stderr, " [Y/n/?] ");
   else
-    fprintf(stderr, " [N/y/?] ");
+    fprintf (stderr, " [N/y/?] ");
 
   if ((len = read (0, answ, sizeof (answ))) < 1)
     {
@@ -354,12 +362,13 @@ think_positively (char *prompt, int def_answ, char *help)
                                 */
     return def_answ;
 
-  if (answ[0] == '?') {                /* display help message */
-    fprintf(stderr, "\n");
-    fprintf(stderr, help);
-    fprintf(stderr, "\n");
-    goto response;
-  }
+  if (answ[0] == '?')
+    {                          /* display help message */
+      fprintf (stderr, "\n");
+      fprintf (stderr, help);
+      fprintf (stderr, "\n");
+      goto response;
+    }
 
   answ[len - 1] = 0;
 
@@ -420,7 +429,7 @@ ask_int_choice (int mask, char *macro,
       for (i = 0; i < OPT_LAST; i++)
        if (mask == B (i))
          {
-           unsigned int             j;
+           unsigned int    j;
 
            for (j = 0; j < strlen (choices); j++)
              if (choices[j] == '\'')
@@ -441,7 +450,7 @@ ask_int_choice (int mask, char *macro,
        return;
 
       fprintf (stderr, "\n%s\n", question);
-      if (strcmp(choices, ""))
+      if (strcmp (choices, ""))
        fprintf (stderr, "Possible values are: %s\n", choices);
 
       if (format == FMT_INT)
@@ -579,18 +588,18 @@ use_old_config (char *filename)
            continue;
 
          if (strcmp (tmp, "JAZZ_DMA16") == 0)  /* Rename it (hack) */
-         {
-               printf("#define SB_DMA2 %s\n",
-                       &buf[18]);
-               continue;
-         }
+           {
+             printf ("#define SB_DMA2 %s\n",
+                     &buf[18]);
+             continue;
+           }
 
          if (strcmp (tmp, "SB16_DMA") == 0)    /* Rename it (hack) */
-         {
-               printf("#define SB_DMA2 %s\n",
-                       &buf[16]);
-               continue;
-         }
+           {
+             printf ("#define SB_DMA2 %s\n",
+                     &buf[16]);
+             continue;
+           }
 
          tmp[8] = 0;           /* Truncate the string */
          if (strcmp (tmp, "EXCLUDE_") == 0)
@@ -678,14 +687,11 @@ use_old_config (char *filename)
   printf ("#define SELECTED_SOUND_OPTIONS\t0x%08x\n", selected_options);
   fprintf (stderr, "Old configuration copied.\n");
 
-#ifdef linux
   build_defines ();
-#endif
   old_config_used = 1;
   return 1;
 }
 
-#ifdef linux
 void
 build_defines (void)
 {
@@ -703,10 +709,6 @@ build_defines (void)
     if (!hw_table[i].alias)
       if (selected_options & B (i))
        fprintf (optf, "CONFIG_%s=y\n", hw_table[i].macro);
-#if 0
-      else
-       fprintf (optf, "CONFIG_%s=n\n", hw_table[i].macro);
-#endif
 
 
   fprintf (optf, "\n");
@@ -717,22 +719,16 @@ build_defines (void)
     {
       if (selected_options & extra_options[i].mask)
        fprintf (optf, "CONFIG_%s=y\n", extra_options[i].name);
-#if 0
-      else
-       fprintf (optf, "CONFIG_%s=n\n", extra_options[i].name);
-#endif
       i++;
     }
 
   fprintf (optf, "\n");
   fclose (optf);
 }
-#endif
 
 void
 ask_parameters (void)
 {
-#ifdef linux
   int             num;
 
   build_defines ();
@@ -765,7 +761,7 @@ ask_parameters (void)
                  "0, 1 or 3");
 
   ask_int_choice (B (OPT_SB), "SB_DMA2",
-                 "SoundBlaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW)",
+               "SoundBlaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW)",
                  FMT_INT,
                  5,
                  "5, 6 or 7");
@@ -797,21 +793,21 @@ ask_parameters (void)
   if (selected_options & B (OPT_PAS))
     {
       if (think_positively ("Enable Joystick port on ProAudioSpectrum", 0,
-      "Enable this option if you want to use the joystick port provided\n"
-      "on the PAS sound card.\n"))
-         printf ("#define PAS_JOYSTICK_ENABLE\n");
+       "Enable this option if you want to use the joystick port provided\n"
+                           "on the PAS sound card.\n"))
+       printf ("#define PAS_JOYSTICK_ENABLE\n");
 
       if (think_positively ("Enable PAS16 bus clock option", 0,
-      "The PAS16 can be noisy with some motherboards. There is a command\n"
-      "line switch (:T?) in the DOS driver for PAS16 which solves this.\n"
+       "The PAS16 can be noisy with some motherboards. There is a command\n"
+       "line switch (:T?) in the DOS driver for PAS16 which solves this.\n"
       "Don't enable this feature unless you have problems and have to use\n"
-      "this switch with DOS\n"))
+                           "this switch with DOS\n"))
        printf ("#define BROKEN_BUS_CLOCK\n");
 
       if (think_positively ("Disable SB mode of PAS16", 0,
-      "You should disable SB emulation of PAS16 if you want to use\n"
-      "Another SB compatible card in the same system\n"))
-         printf ("#define DISABLE_SB_EMULATION\n");
+            "You should disable SB emulation of PAS16 if you want to use\n"
+                        "Another SB compatible card in the same system\n"))
+       printf ("#define DISABLE_SB_EMULATION\n");
     }
 
   ask_int_choice (B (OPT_GUS), "GUS_BASE",
@@ -989,10 +985,10 @@ ask_parameters (void)
       int             reveal_spea;
 
       reveal_spea = think_positively (
-        "Is your SoundScape card made/marketed by Reveal or Spea",
-       0,
-       "Enable if you have a SoundScape card with the Reveal or\n"
-       "Spea name on it.\n");
+                 "Is your SoundScape card made/marketed by Reveal or Spea",
+                                      0,
+                "Enable if you have a SoundScape card with the Reveal or\n"
+                                      "Spea name on it.\n");
       if (reveal_spea)
        printf ("#define REVEAL_SPEA\n");
 
@@ -1123,7 +1119,6 @@ ask_parameters (void)
                  FMT_INT,
                  9,
                  "5, 7, 9 or 10");
-#endif
   ask_int_choice (B (OPT_AUDIO), "DSP_BUFFSIZE",
                  "Audio DMA buffer size",
                  FMT_INT,
@@ -1152,9 +1147,7 @@ dump_script (void)
   selected_options = 0;
   ask_parameters ();
 
-#if 1
   printf ("#\n$MAKE -C drivers/sound kernelconfig || exit 1\n");
-#endif
 }
 
 void
@@ -1258,11 +1251,12 @@ main (int argc, char *argv[])
 
   if (access (oldconf, R_OK) == 0)
     {
-      char str[255];
-      sprintf(str, "Old configuration exists in `%s'. Use it", oldconf);
+      char            str[255];
+
+      sprintf (str, "Old configuration exists in `%s'. Use it", oldconf);
       if (think_positively (str, 1,
-"Enable this option to load the previously saved configuration file\n"
-"for all of the sound driver parameters.\n"))
+      "Enable this option to load the previously saved configuration file\n"
+                           "for all of the sound driver parameters.\n"))
        if (use_old_config (oldconf))
          exit (0);
     }
@@ -1308,28 +1302,28 @@ main (int argc, char *argv[])
   if (selected_options & B (OPT_SB))
     {
       if (think_positively (
-        "Support for the SG NX Pro mixer", 0,
-        "Enable this if you want to support the additional mixer functions\n"
-        "provided on Sound Galaxy NX Pro sound cards.\n"))
+                            "Support for the SG NX Pro mixer", 0,
+       "Enable this if you want to support the additional mixer functions\n"
+                         "provided on Sound Galaxy NX Pro sound cards.\n"))
        printf ("#define __SGNXPRO__\n");
     }
 
   if (selected_options & B (OPT_SB))
     {
       if (think_positively ("Support for the MV Jazz16 (ProSonic etc.)", 0,
-      "Enable this if you have an MV Jazz16 or ProSonic sound card.\n"))
+         "Enable this if you have an MV Jazz16 or ProSonic sound card.\n"))
        {
          if (think_positively ("Do you have SoundMan Wave", 0,
- "Enable this option of you have the Logitech SoundMan Wave sound card.\n"))
                              "Enable this option of you have the Logitech SoundMan Wave sound card.\n"))
            {
              printf ("#define SM_WAVE\n");
 
            midi0001_again:
              if (think_positively (
-"Do you have access to the MIDI0001.BIN file", 1,
-"The Logitech SoundMan Wave has a microcontroller which must be\n"
-"initialized before MIDI emulation works. This is possible only if the\n"
-"microcode file is compiled into the driver.\n"))
+                          "Do you have access to the MIDI0001.BIN file", 1,
+                                    "The Logitech SoundMan Wave has a microcontroller which must be\n"
+                                    "initialized before MIDI emulation works. This is possible only if the\n"
+                          "microcode file is compiled into the driver.\n"))
                {
                  char            path[512];
 
@@ -1343,8 +1337,8 @@ main (int argc, char *argv[])
                      fprintf (stderr, "Couldn't open file %s\n",
                               path);
                      if (think_positively ("Try again with correct path", 1,
-"The specified file could not be opened. Enter the correct path to the\n"
-"file.\n"))
+                                           "The specified file could not be opened. Enter the correct path to the\n"
+                                           "file.\n"))
                        goto midi0001_again;
                    }
                  else
@@ -1360,13 +1354,13 @@ main (int argc, char *argv[])
   if (selected_options & B (OPT_SB))
     {
       if (think_positively ("Do you have a Logitech SoundMan Games", 0,
-"The Logitech SoundMan Games supports 44 kHz in stereo while the\n"
-"standard SB Pro supports just 22 kHz stereo. You have the option of\n"
-"enabling SM Games mode.  However, enable it only if you are sure that\n"
-"your card is an SM Games. Enabling this feature with a plain old SB\n"
-"Pro will cause troubles with stereo mode.\n\n"
-"DANGER! Read the above once again before answering 'y'\n"
-"Answer 'n' if you are unsure what to do!\n"))
+        "The Logitech SoundMan Games supports 44 kHz in stereo while the\n"
+      "standard SB Pro supports just 22 kHz stereo. You have the option of\n"
+                           "enabling SM Games mode.  However, enable it only if you are sure that\n"
+      "your card is an SM Games. Enabling this feature with a plain old SB\n"
+                           "Pro will cause troubles with stereo mode.\n\n"
+                 "DANGER! Read the above once again before answering 'y'\n"
+                           "Answer 'n' if you are unsure what to do!\n"))
        printf ("#define SM_GAMES\n");
     }
 
@@ -1378,10 +1372,10 @@ main (int argc, char *argv[])
        {
 
          if (think_positively (
-"Do you want support for the Audio Excel SoundBlaster Pro mode",
-1,
-"Enable this option if you want the Audio Excel sound card to operate\n"
-"in SoundBlaster Pro mode.\n"))
+           "Do you want support for the Audio Excel SoundBlaster Pro mode",
+                                1,
+                                "Enable this option if you want the Audio Excel sound card to operate\n"
+                                "in SoundBlaster Pro mode.\n"))
            {
              printf ("#define AEDSP16_SBPRO\n");
              sel1 = 1;
@@ -1390,12 +1384,12 @@ main (int argc, char *argv[])
 
       if ((selected_options & B (OPT_MSS)) && (sel1 == 0))
        {
-         
+
          if (think_positively (
-"Do you want support for the Audio Excel Microsoft Sound System mode",
-1,
-"Enable this option if you want the Audio Excel sound card to operate\n"
-"in Microsoft Sound System mode.\n"))
+                                "Do you want support for the Audio Excel Microsoft Sound System mode",
+                                1,
+                                "Enable this option if you want the Audio Excel sound card to operate\n"
+                                "in Microsoft Sound System mode.\n"))
            {
              printf ("#define AEDSP16_MSS\n");
              sel1 = 1;
@@ -1416,8 +1410,8 @@ main (int argc, char *argv[])
     {
     genld_again:
       if (think_positively ("Do you wish to include an LD file", 1,
-     "If you want to emulate the SoundBlaster card and you have a DSPxxx.LD\n"
-     "file then you must include the LD in the kernel.\n"))
+                           "If you want to emulate the SoundBlaster card and you have a DSPxxx.LD\n"
+                     "file then you must include the LD in the kernel.\n"))
        {
          char            path[512];
 
@@ -1428,9 +1422,9 @@ main (int argc, char *argv[])
 
          if (!bin2hex (path, "synth-ld.h", "pss_synth"))
            {
-              fprintf (stderr, "couldn't open `%s' as the LD file\n", path);
+             fprintf (stderr, "couldn't open `%s' as the LD file\n", path);
              if (think_positively ("try again with correct path", 1,
-                "The given LD file could not opened.\n"))
+                                   "The given LD file could not opened.\n"))
                goto genld_again;
            }
          else
@@ -1455,12 +1449,12 @@ main (int argc, char *argv[])
     hex2hex_again:
 
       if (think_positively ("Do you want to include TRXPRO.HEX in your kernel",
-      1,
-"The MediaTriX AudioTrix Pro has an onboard microcontroller which\n"
-"needs to be initialized by downloading the code from the file TRXPRO.HEX\n"
-"in the DOS driver directory. If you don't have the TRXPRO.HEX file handy\n"
-"you may skip this step. However, the SB and MPU-401 modes of AudioTriX\n"
-"Pro will not work without this file!\n"))
+                           1,
+       "The MediaTriX AudioTrix Pro has an onboard microcontroller which\n"
+                           "needs to be initialized by downloading the code from the file TRXPRO.HEX\n"
+                           "in the DOS driver directory. If you don't have the TRXPRO.HEX file handy\n"
+                           "you may skip this step. However, the SB and MPU-401 modes of AudioTriX\n"
+                           "Pro will not work without this file!\n"))
        {
          char            path[512];
 
@@ -1479,7 +1473,7 @@ main (int argc, char *argv[])
   if (!(selected_options & ANY_DEVS))
     {
       printf ("invalid_configuration__run_make_config_again\n");
-      fprintf (stderr,"\n*** This combination is useless. Sound driver disabled!!! ***\n*** You need to enable support for at least one device    ***\n\n");
+      fprintf (stderr, "\n*** This combination is useless. Sound driver disabled!!! ***\n*** You need to enable support for at least one device    ***\n\n");
       exit (0);
     }
 
@@ -1516,12 +1510,13 @@ main (int argc, char *argv[])
 
   if (!old_config_used)
     {
-      char str[255];
-      sprintf(str, "Save copy of this configuration to `%s'", oldconf);
-      if (think_positively (str, 1, 
-"If you enable this option then the sound driver configuration is\n"
-"saved to a file. If you later need to recompile the kernel you have\n"
-"the option of using the saved configuration.\n"))
+      char            str[255];
+
+      sprintf (str, "Save copy of this configuration to `%s'", oldconf);
+      if (think_positively (str, 1,
+       "If you enable this option then the sound driver configuration is\n"
+      "saved to a file. If you later need to recompile the kernel you have\n"
+                         "the option of using the saved configuration.\n"))
        {
          char            cmd[200];
 
index a27876e22c254c811f7fbae6f1f57e08e56e5ee4..317d5730f31f768e996db7c4912050965bcacd0a 100644 (file)
@@ -71,8 +71,8 @@ typedef struct pnp_sounddev
 #define MAX_SUB_BUFFERS                (32*MAX_REALTIME_FACTOR)
 
 #define DMODE_NONE             0
-#define DMODE_OUTPUT           1
-#define DMODE_INPUT            2
+#define DMODE_OUTPUT           PCM_ENABLE_OUTPUT
+#define DMODE_INPUT            PCM_ENABLE_INPUT
 
 struct dma_buffparms {
        int      dma_mode;      /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
@@ -96,6 +96,8 @@ struct dma_buffparms {
 #define DMA_STARTED    0x00000008
 #define DMA_EMPTY      0x00000010      
 #define DMA_ALLOC_DONE 0x00000020
+#define DMA_SYNCING    0x00000040
+#define DMA_CLEAN      0x00000080
 
        int      open_mode;
 
index a26eb82648549af46fa8844253a7b9455e9bbb1e..85d5179b6d5414a8a1bb8f34edc040411ca396f7 100644 (file)
@@ -360,6 +360,8 @@ dma_sync (int dev)
       save_flags (flags);
       cli ();
 
+      audio_devs[dev]->flags |= DMA_SYNCING;
+
       audio_devs[dev]->dmap_out->underrun_count = 0;
       while (!current_got_fatal_signal ()
             && audio_devs[dev]->dmap_out->qlen
@@ -384,10 +386,12 @@ dma_sync (int dev)
          };
          if ((out_sleep_flag[dev].mode & WK_TIMEOUT))
            {
+             audio_devs[dev]->flags &= ~DMA_SYNCING;
              restore_flags (flags);
              return audio_devs[dev]->dmap_out->qlen;
            }
        }
+      audio_devs[dev]->flags &= ~DMA_SYNCING;
       restore_flags (flags);
 
       /*
@@ -1023,6 +1027,8 @@ DMAbuf_getwrbuffer (int dev, char **buf, int *size, int dontblock)
   int             abort, err = EIO;
   struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
 
+  dmap->flags &= ~DMA_CLEAN;
+
   if (audio_devs[dev]->dmap_out->mapping_flags & DMA_MAP_MAPPED)
     {
       printk ("Sound: Can't write to mmapped device (3)\n");
@@ -1165,6 +1171,7 @@ DMAbuf_start_output (int dev, int buff_no, int l)
   struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
 
   dmap->cfrag = -1;
+
 /*
  * Bypass buffering if using mmaped access
  */
@@ -1401,7 +1408,8 @@ DMAbuf_outputintr (int dev, int event_type)
        {
          dmap->underrun_count++;
 
-         if (dmap->underrun_count > 5 || dmap->flags & DMA_EMPTY)
+         if (!(dmap->flags & DMA_CLEAN) &&
+             (audio_devs[dev]->flags & DMA_SYNCING || dmap->underrun_count > 5 || dmap->flags & DMA_EMPTY))
            {
              dmap->qlen = 0;
              force_restart (dev, dmap);
@@ -1624,6 +1632,7 @@ DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handle
 
          save_flags (flags);
          cli ();
+
          in_sleep_flag[dev].mode = WK_SLEEP;
          module_select_wait (&in_sleeper[dev], wait);
          restore_flags (flags);
@@ -1650,6 +1659,7 @@ DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handle
        {
          save_flags (flags);
          cli ();
+
          in_sleep_flag[dev].mode = WK_SLEEP;
          module_select_wait (&in_sleeper[dev], wait);
          restore_flags (flags);
@@ -1668,6 +1678,7 @@ DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handle
 
          save_flags (flags);
          cli ();
+
          out_sleep_flag[dev].mode = WK_SLEEP;
          module_select_wait (&out_sleeper[dev], wait);
          restore_flags (flags);
@@ -1688,6 +1699,7 @@ DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handle
        {
          save_flags (flags);
          cli ();
+
          out_sleep_flag[dev].mode = WK_SLEEP;
          module_select_wait (&out_sleeper[dev], wait);
          restore_flags (flags);
index 06849f1c07d87e1f005d5c19ec3fe8e53fdff735..13e479dcefbe9de36fd9ca8bde74741efe3f8803 100644 (file)
@@ -768,7 +768,7 @@ gus_initialize (void)
 
   irq_image = 0;
   tmp = gus_irq_map[gus_irq];
-  if (!tmp)
+  if (!gus_pnp_flag && !tmp)
     printk ("Warning! GUS IRQ not selected\n");
   irq_image |= tmp;
   irq_image |= 0x40;           /* Combine IRQ1 (GF1) and IRQ2 (Midi) */
@@ -1658,7 +1658,7 @@ guswave_load_patch (int dev, int format, const char *addr,
          blk_sz = blk_end - target;
        }
 
-      if (gus_no_dma)
+      if (gus_pnp_flag || gus_no_dma)
        {
          /*
           * For some reason the DMA is not possible. We have to use PIO.
index 4053de89916cb09a2d4a7b79652d2533463afc7a..df977ff28aeec08f2c02ff446a5155648b94d32b 100644 (file)
@@ -23,7 +23,6 @@
  */
 #include <linux/config.h>
 
-
 /*
  * sound/mad16.c
  *
@@ -32,6 +31,7 @@
  *      OPTi 82C928     MAD16           (replaced by C929)
  *      OAK OTI-601D    Mozart
  *      OPTi 82C929     MAD16 Pro
+ *      OPTi 82C930     (Not supported yet)
  *
  * These audio interface chips don't prduce sound themselves. They just
  * connect some other components (OPL-[234] and a WSS compatible codec)
@@ -82,6 +82,7 @@ static int      already_initialized = 0;
 #define C928   1
 #define MOZART 2
 #define C929   3
+#define C930   4
 
 /*
  *    Registers
@@ -92,6 +93,7 @@ static int      already_initialized = 0;
  *      only until the next I/O read or write.
  */
 
+#define MC0_PORT       0xf8c   /* Dummy port */
 #define MC1_PORT       0xf8d   /* SB address, CDROM interface type, joystick */
 #define MC2_PORT       0xf8e   /* CDROM address, IRQ, DMA, plus OPL4 bit */
 #define MC3_PORT       0xf8f
@@ -100,6 +102,11 @@ static int      already_initialized = 0;
 #define MC5_PORT       0xf91
 #define MC6_PORT       0xf92
 #define MC7_PORT       0xf93
+#define MC8_PORT       0xf94
+#define MC9_PORT       0xf95
+#define MC10_PORT      0xf96
+#define MC11_PORT      0xf97
+#define MC12_PORT      0xf98
 
 static int      board_type = C928;
 
@@ -128,6 +135,7 @@ mad_read (int port)
     case C929:
       outb (0xE3, PASSWD_REG);
       break;
+
     }
 
   tmp = inb (port);
@@ -154,6 +162,7 @@ mad_write (int port, int value)
     case C929:
       outb (0xE3, PASSWD_REG);
       break;
+
     }
 
   outb ((unsigned char) (value & 0xff), port);
@@ -164,6 +173,7 @@ static int
 detect_mad16 (void)
 {
   unsigned char   tmp, tmp2;
+  int             i;
 
 /*
  * Check that reading a register doesn't return bus float (0xff)
@@ -176,6 +186,10 @@ detect_mad16 (void)
       DDB (printk ("MC1_PORT returned 0xff\n"));
       return 0;
     }
+
+  for (i = 0xf8d; i <= 0xf98; i++)
+    DDB (printk ("Port %0x (init value) = %0x\n", i, mad_read (i)));
+
 /*
  * Now check that the gate is closed on first I/O after writing
  * the password. (This is how a MAD16 compatible card works).
@@ -188,7 +202,6 @@ detect_mad16 (void)
     }
 
   mad_write (MC1_PORT, tmp ^ 0x80);    /* Togge a bit */
-
   if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80))    /* Compare the bit */
     {
       mad_write (MC1_PORT, tmp);       /* Restore */
@@ -201,6 +214,67 @@ detect_mad16 (void)
 
 }
 
+static int
+wss_init (struct address_info *hw_config)
+{
+  int             ad_flags = 0;
+
+/*
+ *    Verify the WSS parameters
+ */
+
+  if (check_region (hw_config->io_base, 8))
+    {
+      printk ("MSS: I/O port conflict\n");
+      return 0;
+    }
+
+  if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
+    return 0;
+  /*
+     * Check if the IO port returns valid signature. The original MS Sound
+     * system returns 0x04 while some cards (AudioTriX Pro for example)
+     * return 0x00.
+   */
+
+  if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
+      (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
+    {
+      DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
+                  hw_config->io_base, inb (hw_config->io_base + 3)));
+      return 0;
+    }
+
+  if (hw_config->irq > 11)
+    {
+      printk ("MSS: Bad IRQ %d\n", hw_config->irq);
+      return 0;
+    }
+
+  if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
+    {
+      printk ("MSS: Bad DMA %d\n", hw_config->dma);
+      return 0;
+    }
+
+  /*
+     * Check that DMA0 is not in use with a 8 bit board.
+   */
+
+  if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
+    {
+      printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
+      return 0;
+    }
+
+  if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
+    {
+      printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
+    }
+
+  return 1;
+}
+
 int
 probe_mad16 (struct address_info *hw_config)
 {
@@ -238,9 +312,13 @@ probe_mad16 (struct address_info *hw_config)
       DDB (printk ("Detect using password = 0xE3\n"));
 
       if (!detect_mad16 ())
-       return 0;
-
-      DDB (printk ("mad16.c: 82C929 detected\n"));
+       {
+         return 0;
+       }
+      else
+       {
+         DDB (printk ("mad16.c: 82C929 detected\n"));
+       }
     }
   else
     {
@@ -259,7 +337,7 @@ probe_mad16 (struct address_info *hw_config)
     }
 
   for (i = 0xf8d; i <= 0xf93; i++)
-    DDB (printk ("port %03x = %03x\n", i, mad_read (i)));
+    DDB (printk ("port %03x = %02x\n", i, mad_read (i)));
 
 /*
  * Set the WSS address
@@ -323,59 +401,9 @@ probe_mad16 (struct address_info *hw_config)
     }
 
   for (i = 0xf8d; i <= 0xf93; i++)
-    DDB (printk ("port %03x after init = %03x\n", i, mad_read (i)));
-
-/*
- *    Verify the WSS parameters
- */
-
-  if (check_region (hw_config->io_base, 8))
-    {
-      printk ("MSS: I/O port conflict\n");
-      return 0;
-    }
-
-  /*
-     * Check if the IO port returns valid signature. The original MS Sound
-     * system returns 0x04 while some cards (AudioTriX Pro for example)
-     * return 0x00.
-   */
-
-  if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
-      (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
-    {
-      DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
-                  hw_config->io_base, inb (hw_config->io_base + 3)));
-      return 0;
-    }
-
-  if (hw_config->irq > 11)
-    {
-      printk ("MSS: Bad IRQ %d\n", hw_config->irq);
-      return 0;
-    }
-
-  if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
-    {
-      printk ("MSS: Bad DMA %d\n", hw_config->dma);
-      return 0;
-    }
+    DDB (printk ("port %03x after init = %02x\n", i, mad_read (i)));
 
-  /*
-     * Check that DMA0 is not in use with a 8 bit board.
-   */
-
-  if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
-    {
-      printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
-      return 0;
-    }
-
-  if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
-    {
-      printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
-      return 0;
-    }
+  wss_init (hw_config);
 
   return 1;
 }
index 89681a117fd2bb943a0427050ca9e438472d5140..c6f4e8b084e7f672fa40ba542b6976160c0a5e75 100644 (file)
@@ -513,6 +513,7 @@ MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handl
     case SEL_IN:
       if (!DATA_AVAIL (midi_in_buf[dev]))
        {
+
          input_sleep_flag[dev].mode = WK_SLEEP;
          module_select_wait (&input_sleeper[dev], wait);
          return 0;
@@ -523,6 +524,7 @@ MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table_handl
     case SEL_OUT:
       if (SPACE_AVAIL (midi_out_buf[dev]))
        {
+
          midi_sleep_flag[dev].mode = WK_SLEEP;
          module_select_wait (&midi_sleeper[dev], wait);
          return 0;
index 0106b40e261bb2f516ae506f5ea324aa3fd37eea..09234c69c81161a6dc3779127d6ff4a4bbe7fe58 100644 (file)
@@ -157,7 +157,7 @@ sb16_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
     {
     case SOUND_PCM_WRITE_RATE:
       if (local)
-       return dsp_set_speed ((int) arg);
+       return dsp_set_speed ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_speed (get_fs_long ((long *) arg)));
 
     case SOUND_PCM_READ_RATE:
@@ -167,12 +167,12 @@ sb16_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
 
     case SNDCTL_DSP_STEREO:
       if (local)
-       return dsp_set_stereo ((int) arg);
+       return dsp_set_stereo ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg)));
 
     case SOUND_PCM_WRITE_CHANNELS:
       if (local)
-       return dsp_set_stereo ((int) arg - 1) + 1;
+       return dsp_set_stereo ((long) arg - 1) + 1;
       return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg) - 1) + 1);
 
     case SOUND_PCM_READ_CHANNELS:
@@ -182,7 +182,7 @@ sb16_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
 
     case SNDCTL_DSP_SETFMT:
       if (local)
-       return dsp_set_bits ((int) arg);
+       return dsp_set_bits ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_bits (get_fs_long ((long *) arg)));
 
     case SOUND_PCM_READ_BITS:
index de8c532c3fb13ae303e01b814e0428a9b7497396..1ddc82b47df13a144798141472c73978aa517825 100644 (file)
@@ -834,7 +834,7 @@ sb_dsp_open (int dev, int mode)
 
   if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI))
     {
-      printk ("SB: Audio device or MIDI already in use\n");
+      printk ("SB: Audio device or MIDI already in use.\n");
       return -EBUSY;
     }
 
@@ -938,7 +938,7 @@ sb_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
     {
     case SOUND_PCM_WRITE_RATE:
       if (local)
-       return dsp_speed ((int) arg);
+       return dsp_speed ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_speed (get_fs_long ((long *) arg)));
       break;
 
@@ -950,7 +950,7 @@ sb_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
 
     case SOUND_PCM_WRITE_CHANNELS:
       if (local)
-       return dsp_set_stereo ((int) arg - 1) + 1;
+       return dsp_set_stereo ((long) arg - 1) + 1;
       return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg) - 1) + 1);
       break;
 
@@ -962,7 +962,7 @@ sb_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
 
     case SNDCTL_DSP_STEREO:
       if (local)
-       return dsp_set_stereo ((int) arg);
+       return dsp_set_stereo ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_stereo (get_fs_long ((long *) arg)));
       break;
 
@@ -971,7 +971,7 @@ sb_dsp_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
        */
     case SNDCTL_DSP_SETFMT:
       if (local)
-       return dsp_set_bits ((int) arg);
+       return dsp_set_bits ((long) arg);
       return snd_ioctl_return ((int *) arg, dsp_set_bits (get_fs_long ((long *) arg)));
       break;
 
index e52627305eee18ab7ba5b7c08f765ade82a80783..7af949de55188a6e209699899191b0e3ebf83a34 100644 (file)
@@ -1908,12 +1908,12 @@ sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table_han
       cli ();
       if (!iqlen)
        {
+
          midi_sleep_flag.mode = WK_SLEEP;
          module_select_wait (&midi_sleeper, wait);
          restore_flags (flags);
          return 0;
        }
-      midi_sleep_flag.mode &= ~WK_SLEEP;
       restore_flags (flags);
       return 1;
       break;
@@ -1923,12 +1923,12 @@ sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table_han
       cli ();
       if ((SEQ_MAX_QUEUE - qlen) < output_treshold)
        {
+
          seq_sleep_flag.mode = WK_SLEEP;
          module_select_wait (&seq_sleeper, wait);
          restore_flags (flags);
          return 0;
        }
-      seq_sleep_flag.mode &= ~WK_SLEEP;
       restore_flags (flags);
       return 1;
       break;
index e49f4b002bdc25657c685da38ff5af60496f14f9..18ea3258d31fa50bcdbb7ae04865234b5fd8e915 100644 (file)
@@ -172,6 +172,7 @@ struct channel_info {
 #define WK_TIMEOUT     0x02
 #define WK_SIGNAL      0x04
 #define WK_SLEEP       0x08
+#define WK_SELECT      0x10
 
 #define OPEN_READ      PCM_ENABLE_INPUT
 #define OPEN_WRITE     PCM_ENABLE_OUTPUT
index 3e1a24f8a59802b30871460955ff8becd5dca679..413724a72f436f97432172df5bd801bbdbe916e1 100644 (file)
@@ -523,12 +523,12 @@ sound_ioctl_sw (int dev, struct fileinfo *file,
   if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0)    /* Mixer ioctl */
     if ((dev & 0x0f) != SND_DEV_CTL)
       {
+#ifdef CONFIG_AUDIO
        int             dtype = dev & 0x0f;
        int             mixdev;
 
        switch (dtype)
          {
-#ifdef CONFIG_AUDIO
          case SND_DEV_DSP:
          case SND_DEV_DSP16:
          case SND_DEV_AUDIO:
@@ -536,12 +536,9 @@ sound_ioctl_sw (int dev, struct fileinfo *file,
            if (mixdev < 0 || mixdev >= num_mixers)
              return -ENXIO;
            return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg);
-           break;
-#endif
-
-         default:
-           return mixer_devs[0]->ioctl (0, cmd, arg);
          }
+#endif
+         return mixer_devs[0]->ioctl (0, cmd, arg);
       }
 
   switch (dev & 0x0f)
index 9da8c50d04555fa6869221db698b9f73bb9fe8e0..8ab6f7c62a4c91fd089dc651a1bad074beb99fba 100644 (file)
@@ -389,8 +389,6 @@ char            kernel_version[] = UTS_RELEASE;
 
 #endif
 
-static int      debugmem = 0;  /* switched off by default */
-
 static int      sound[20] =
 {0};
 
@@ -442,6 +440,11 @@ cleanup_module (void)
 {
   int             i;
 
+  if (MOD_IN_USE)
+    {
+      return;
+    }
+
   if (chrdev_registered)
     module_unregister_chrdev (sound_major, "sound");
 
@@ -461,6 +464,7 @@ cleanup_module (void)
        printk ("Sound: Hmm, DMA%d was left allocated - fixed\n", i);
        sound_free_dma (i);
       }
+
 }
 #endif
 
@@ -599,6 +603,8 @@ sound_stop_timer (void)
 fatal_error__This_version_is_not_compatible_with_this_kernel;
 #endif
 
+static int      debugmem = 0;  /* switched off by default */
+
 static int      dma_buffsize = DSP_BUFFSIZE;
 
 int
@@ -647,7 +653,7 @@ sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan)
 
       audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
 
-      if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, 1)) == NULL)
+      if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
        audio_devs[dev]->buffsize /= 2;
     }
 
@@ -726,6 +732,7 @@ soud_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc * info)
   printk ("Exited sound_map_buffer()\n");
   return -EINVAL;
 }
+#endif
 
 void
 conf_printf (char *name, struct address_info *hw_config)
@@ -768,4 +775,3 @@ conf_printf2 (char *name, int base, int irq, int dma, int dma2)
 
   printk ("\n");
 }
-#endif
index 67e3554faa1a3c63df00fe95476795a0d8f90d63..0bdf900a7cd22841af9a7861d64a55a8aa110c47 100644 (file)
@@ -1,2 +1,2 @@
-#define SOUND_VERSION_STRING "3.5-960313"
+#define SOUND_VERSION_STRING "3.5.1-960324"
 #define SOUND_INTERNAL_VERSION 0x030500
index 064ee22fce7de1ec961812f6ecef3cca72761b76..2635166577cb9b70eb318e5e0d8ef0dc42c424d0 100644 (file)
@@ -306,7 +306,7 @@ sscapeintr (int irq, void *dev_id, struct pt_regs *dummy)
   unsigned char   bits, tmp;
   static int      debug = 0;
 
-  printk ("sscapeintr(0x%02x)\n", (bits = sscape_read (devc, GA_INTSTAT_REG)));
+  bits = sscape_read (devc, GA_INTSTAT_REG);
   if ((sscape_sleep_flag.mode & WK_SLEEP))
     {
       {
index 57ecef53c6556e45fae65a2be3741c3e0e5acf44..4e347c49f0146fcf162d919cabade8dc3c334aa9 100644 (file)
@@ -13,8 +13,8 @@
 
 static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-       char *cp, *interp, *i_name, *i_arg, *page;
-       int retval, offset;
+       char *cp, *interp, *i_name, *i_arg;
+       int retval;
        if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
                return -ENOEXEC;
        /*
@@ -60,16 +60,7 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
         * This is done in reverse order, because of how the
         * user environment and arguments are stored.
         */
-       if (bprm->argc) {
-               offset = bprm->p % PAGE_SIZE;
-               page = (char*)bprm->page[bprm->p/PAGE_SIZE];
-               while(bprm->p++,*(page+offset++))
-                       if(offset==PAGE_SIZE){
-                               offset=0;
-                               page = (char*)bprm->page[bprm->p/PAGE_SIZE];
-                       }
-               bprm->argc--;
-       }
+       remove_arg_zero(bprm);
        bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
        bprm->argc++;
        if (i_arg) {
index ec1629ea52466464516314f451883230ece9c42d..809c2152883369611ff769085d635a46379d0fc7 100644 (file)
@@ -18,8 +18,6 @@
  * string-hash computed over the name. 
  */
 
-#include <stddef.h>
-
 #include <linux/fs.h>
 #include <linux/string.h>
 
@@ -51,9 +49,11 @@ struct dir_cache_entry {
        struct dir_cache_entry * next_lru,  * prev_lru;
 };
 
+#define dcache_offset(x) ((unsigned long)&((struct dir_cache_entry*)0)->x)
+#define dcache_datalen (dcache_offset(lru_head) - dcache_offset(dc_dev))
+
 #define COPYDATA(de, newde) \
-memcpy((void *) &newde->dc_dev, (void *) &de->dc_dev, \
-sizeof(kdev_t) + 3*sizeof(unsigned long) + 1 + DCACHE_NAME_LEN)
+memcpy((void *) &newde->dc_dev, (void *) &de->dc_dev, dcache_datalen)
 
 static struct dir_cache_entry level1_cache[DCACHE_SIZE];
 static struct dir_cache_entry level2_cache[DCACHE_SIZE];
@@ -69,22 +69,27 @@ static struct dir_cache_entry * level2_head;
  * The hash-queues are also doubly-linked circular lists, but the head is
  * itself on the doubly-linked list, not just a pointer to the first entry.
  */
-#define DCACHE_HASH_QUEUES 19
+#define DCACHE_HASH_QUEUES 32
 #define hash_fn(dev,dir,namehash) ((HASHDEV(dev) ^ (dir) ^ (namehash)) % DCACHE_HASH_QUEUES)
 
 static struct hash_list hash_table[DCACHE_HASH_QUEUES];
 
 static inline void remove_lru(struct dir_cache_entry * de)
 {
-       de->next_lru->prev_lru = de->prev_lru;
-       de->prev_lru->next_lru = de->next_lru;
+       struct dir_cache_entry * next = de->next_lru;
+       struct dir_cache_entry * prev = de->prev_lru;
+
+       next->prev_lru = prev;
+       prev->next_lru = next;
 }
 
 static inline void add_lru(struct dir_cache_entry * de, struct dir_cache_entry *head)
 {
+       struct dir_cache_entry * prev = head->prev_lru;
+
        de->next_lru = head;
-       de->prev_lru = head->prev_lru;
-       de->prev_lru->next_lru = de;
+       de->prev_lru = prev;
+       prev->next_lru = de;
        head->prev_lru = de;
 }
 
@@ -104,7 +109,9 @@ static inline void update_lru(struct dir_cache_entry * de)
  */
 static inline unsigned long namehash(const char * name, int len)
 {
-       return len * *(const unsigned char *) name;
+       return len +
+               ((const unsigned char *) name)[0]+
+               ((const unsigned char *) name)[len-1];
 }
 
 /*
@@ -112,18 +119,22 @@ static inline unsigned long namehash(const char * name, int len)
  */
 static inline void remove_hash(struct dir_cache_entry * de)
 {
-       if (de->h.next) {
-               de->h.next->h.prev = de->h.prev;
-               de->h.prev->h.next = de->h.next;
+       struct dir_cache_entry * next = de->h.next;
+
+       if (next) {
+               struct dir_cache_entry * prev = de->h.prev;
+               next->h.prev = prev;
+               prev->h.next = next;
                de->h.next = NULL;
        }
 }
 
 static inline void add_hash(struct dir_cache_entry * de, struct hash_list * hash)
 {
-       de->h.next = hash->next;
+       struct dir_cache_entry * next = hash->next;
+       de->h.next = next;
        de->h.prev = (struct dir_cache_entry *) hash;
-       hash->next->h.prev = de;
+       next->h.prev = de;
        hash->next = de;
 }
 
index 7288e316dd4fd4004fb7c56cd3fc1ce92ee7c5b6..bb4d32eb5831d25b94d63ee3a12310a0dea46e37 100644 (file)
@@ -137,7 +137,9 @@ static int parse_options(char *options, struct iso9660_options * popt)
                  if (*vpnt) return 0;
                  switch(*this_char) {
                  case 'b':
-                   if (ivalue != 1024 && ivalue != 2048) return 0;
+                   if (   ivalue != 512 
+                       && ivalue != 1024 
+                       && ivalue != 2048) return 0;
                    popt->blocksize = ivalue;
                    break;
                  case 'u':
@@ -200,6 +202,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
        int high_sierra;
        kdev_t dev = s->s_dev;
        unsigned int vol_desc_start;
+       int orig_zonesize;
 
        struct iso_volume_descriptor *vdp;
        struct hs_volume_descriptor *hdp;
@@ -324,6 +327,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
        
        /* RDE: convert log zone size to bit shift */
 
+       orig_zonesize = s -> u.isofs_sb.s_log_zone_size;
        switch (s -> u.isofs_sb.s_log_zone_size)
          { case  512: s -> u.isofs_sb.s_log_zone_size =  9; break;
            case 1024: s -> u.isofs_sb.s_log_zone_size = 10; break;
@@ -336,7 +340,8 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
 
        /* RDE: data zone now byte offset! */
 
-       s->u.isofs_sb.s_firstdatazone = (isonum_733( rootp->extent) 
+       s->u.isofs_sb.s_firstdatazone = ((isonum_733 (rootp->extent) + 
+                                          isonum_711 (rootp->ext_attr_length))
                                         << s -> u.isofs_sb.s_log_zone_size);
        s->s_magic = ISOFS_SUPER_MAGIC;
        
@@ -354,11 +359,32 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
               1UL << s->u.isofs_sb.s_log_zone_size);
        printk(KERN_DEBUG "First datazone:%ld   Root inode number %d\n",
               s->u.isofs_sb.s_firstdatazone >> s -> u.isofs_sb.s_log_zone_size,
-              isonum_733 (rootp->extent) << s -> u.isofs_sb.s_log_zone_size);
+              (isonum_733(rootp->extent) + isonum_711(rootp->ext_attr_length))
+                       << s -> u.isofs_sb.s_log_zone_size);
        if(high_sierra) printk(KERN_DEBUG "Disc in High Sierra format.\n");
        unlock_super(s);
        /* set up enough so that it can read an inode */
        
+       /*
+        * Force the blocksize to 512 for 512 byte sectors.  The file
+        * read primitives really get it wrong in a bad way if we don't
+        * do this.
+        */
+       if( orig_zonesize < opt.blocksize )
+         {
+           opt.blocksize = orig_zonesize;
+           blocksize_bits = 0;
+           {
+             int i = opt.blocksize;
+             while (i != 1){
+               blocksize_bits++;
+               i >>=1;
+             }
+           }
+           set_blocksize(dev, opt.blocksize);
+           printk(KERN_DEBUG "Forcing new log zone size:%d\n", opt.blocksize);
+         }
+
        s->s_dev = dev;
        s->s_op = &isofs_sops;
        s->u.isofs_sb.s_mapping = opt.map;
@@ -376,7 +402,9 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
        s->u.isofs_sb.s_mode = opt.mode & 0777;
        s->s_blocksize = opt.blocksize;
        s->s_blocksize_bits = blocksize_bits;
-       s->s_mounted = iget(s, isonum_733 (rootp->extent) << s -> u.isofs_sb.s_log_zone_size);
+       s->s_mounted = iget(s, (isonum_733(rootp->extent) + 
+                           isonum_711(rootp->ext_attr_length))
+                               << s -> u.isofs_sb.s_log_zone_size);
        unlock_super(s);
 
        if (!(s->s_mounted)) {
index eb1c4b394fd3e9e82c7165871ad92b4961f4fc97..4350fdd6561add8b5c838cbcfa0527f55d353b10 100644 (file)
@@ -23,6 +23,26 @@ ncp_ioctl (struct inode * inode, struct file * filp,
        struct ncp_fs_info info;
        struct ncp_server *server = NCP_SERVER(inode);
 
+       /*
+        * Binary compatible with 1.3.XX releases.
+        * Take this out in 2.1.0 development series.
+        * <mec@duracef.shout.net> 12 Mar 1996
+        */
+       switch(cmd) {
+       case _IOR('n', 1, unsigned char *):
+           cmd = NCP_IOC_NCPREQUEST;
+           break;
+       case _IOR('u', 1, uid_t):
+           cmd = NCP_IOC_GETMOUNTUID;
+           break;
+       case _IO('l', 1):
+           cmd = NCP_IOC_CONN_LOGGED_IN;
+           break;
+       case _IOWR('i', 1, unsigned char *):
+           cmd = NCP_IOC_GET_FS_INFO;
+           break;
+       }
+
        switch(cmd) {
        case NCP_IOC_NCPREQUEST:
 
@@ -106,10 +126,12 @@ ncp_ioctl (struct inode * inode, struct file * filp,
                        return -EINVAL;
                }
 
-               info.addr        = server->m.serv_addr;
-               info.mounted_uid = server->m.mounted_uid;
-               info.connection  = server->connection;
-               info.buffer_size = server->buffer_size;
+               info.addr          = server->m.serv_addr;
+               info.mounted_uid   = server->m.mounted_uid;
+               info.connection    = server->connection;
+               info.buffer_size   = server->buffer_size;
+               info.volume_number = NCP_ISTRUCT(inode)->volNumber;
+               info.directory_id  = NCP_ISTRUCT(inode)->DosDirNum;
 
                memcpy_tofs((struct ncp_fs_info *)arg, &info, sizeof(info));
                return 0;               
index 5dcf153c1e0a3c3cb53e2c6f9875c01286be6195..b4a090c076f0ca7360bb26b8bcdceb9b9dbc66af 100644 (file)
@@ -217,14 +217,9 @@ ncp_close_file(struct ncp_server *server, const char *file_id)
        ncp_add_byte(server, 0);
        ncp_add_mem(server, file_id, 6);
 
-       if ((result = ncp_request(server, 66)) != 0)
-       {
-               ncp_unlock_server(server);
-               return result;
-       }
-
+       result = ncp_request(server, 66);
        ncp_unlock_server(server);
-       return 0;
+       return result;
 }
 
 static void
@@ -366,14 +361,9 @@ ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
        ncp_add_handle_path(server, file->volNumber,
                            file->DosDirNum, 1, NULL);
 
-       if ((result = ncp_request(server, 87)) != 0)
-       {
-               ncp_unlock_server(server);
-               return result;
-       }
-
+       result = ncp_request(server, 87);
        ncp_unlock_server(server);
-       return 0;
+       return result;
 }
 
 int
@@ -390,14 +380,9 @@ ncp_del_file_or_subdir(struct ncp_server *server,
        ncp_add_handle_path(server, dir->volNumber,
                            dir->DosDirNum, 1, name);
        
-       if ((result = ncp_request(server, 87)) != 0)
-       {
-               ncp_unlock_server(server);
-               return result;
-       }
-
+       result = ncp_request(server, 87);
        ncp_unlock_server(server);
-       return 0;
+       return result;
 }
 
 static inline void
index f00da29861fb4f4718a8054f13bab4830b581665..9996f1a9af7492f4b15e4f231a8030aecc37d71b 100644 (file)
@@ -80,7 +80,7 @@ void nfs_put_super(struct super_block *sb)
  * The way this works is that the mount process passes a structure
  * in the data argument which contains an open socket to the NFS
  * server and the root file handle obtained from the server's mount
- * daemon.  We stash theses away in the private superblock fields.
+ * daemon.  We stash these away in the private superblock fields.
  * Later we can add other mount parameters like caching values.
  */
 
@@ -169,7 +169,7 @@ struct super_block *nfs_read_super(struct super_block *sb, void *raw_data,
            sock->ops->getname(sock, &(server->toaddr), &dummylen, 1) ;
          }
        } else {
-       /*  printk("NFS: coppying passed addr to server->toaddr\n") ;*/
+       /*  printk("NFS: copying passed addr to server->toaddr\n") ;*/
          memcpy((char *)&(server->toaddr),(char *)(&data->addr),sizeof(server->toaddr));
        }
        /* End of JSP NFS patch */
index d1b6d56a8f9411bbf716a9c4a1ce18ca63ece5fb..b5882d64bc26b360d1e6c84ed96f891de944a6e3 100644 (file)
@@ -612,6 +612,9 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
        struct vfsmount *vfsmnt;
        int error;
 
+       if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
+               return -EACCES;
+               /*flags |= MS_RDONLY;*/
        error = namei(dir_name, &dir_i);
        if (error)
                return error;
@@ -656,6 +659,7 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
 static int do_remount_sb(struct super_block *sb, int flags, char *data)
 {
        int retval;
+       struct vfsmount *vfsmnt;
        
        if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
                return -EACCES;
@@ -671,6 +675,9 @@ static int do_remount_sb(struct super_block *sb, int flags, char *data)
        }
        sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
                (flags & MS_RMT_MASK);
+       vfsmnt = lookup_vfsmnt(sb->s_dev);
+       if (vfsmnt)
+               vfsmnt->mnt_flags = sb->s_flags;
        return 0;
 }
 
index 804f65e5e66e64a9b0efb29ea130b0589c5cc8af..bdf2331f744eaec50b156a5e11af20be4b3167db 100644 (file)
@@ -65,8 +65,9 @@ int UMSDOS_ioctl_dir (
                in UMSDOS. EPERM is returned for other user.
        */
        /*
-               Well, not all case require write access, but it simplify the code
-               and let's face it, there is only one client (umssync) for all this
+               Well, not all cases require write access, but it simplifies
+               the code, and let's face it, there is only one client (umssync)
+               for all this.
        */
        if ((err = verify_area(VERIFY_WRITE,(void*)data,sizeof(struct umsdos_ioctl))) < 0) {
                ret = err;
index 96215f6286268b81396e45fd5e53fb431b6b0ad2..e0043b264721a1be4f59377c5e53adc13e1a2222 100644 (file)
@@ -334,47 +334,47 @@ extern unsigned long apecs_init (unsigned long mem_start,
  * Data structure for handling APECS machine checks:
  */
 struct el_apecs_sysdata_mcheck {
-    u_long      coma_gcr;                       
-    u_long      coma_edsr;                      
-    u_long      coma_ter;                       
-    u_long      coma_elar;                      
-    u_long      coma_ehar;                      
-    u_long      coma_ldlr;                      
-    u_long      coma_ldhr;                      
-    u_long      coma_base0;                     
-    u_long      coma_base1;                     
-    u_long      coma_base2;                     
-    u_long      coma_cnfg0;                     
-    u_long      coma_cnfg1;                     
-    u_long      coma_cnfg2;                     
-    u_long      epic_dcsr;                      
-    u_long      epic_pear;                      
-    u_long      epic_sear;                      
-    u_long      epic_tbr1;                      
-    u_long      epic_tbr2;                      
-    u_long      epic_pbr1;                      
-    u_long      epic_pbr2;                      
-    u_long      epic_pmr1;                      
-    u_long      epic_pmr2;                      
-    u_long      epic_harx1;                     
-    u_long      epic_harx2;                     
-    u_long      epic_pmlt;                      
-    u_long      epic_tag0;                      
-    u_long      epic_tag1;                      
-    u_long      epic_tag2;                      
-    u_long      epic_tag3;                      
-    u_long      epic_tag4;                      
-    u_long      epic_tag5;                      
-    u_long      epic_tag6;                      
-    u_long      epic_tag7;                      
-    u_long      epic_data0;                     
-    u_long      epic_data1;                     
-    u_long      epic_data2;                     
-    u_long      epic_data3;                     
-    u_long      epic_data4;                     
-    u_long      epic_data5;                     
-    u_long      epic_data6;                     
-    u_long      epic_data7;                     
+    unsigned long coma_gcr;
+    unsigned long coma_edsr;
+    unsigned long coma_ter;
+    unsigned long coma_elar;
+    unsigned long coma_ehar;
+    unsigned long coma_ldlr;
+    unsigned long coma_ldhr;
+    unsigned long coma_base0;
+    unsigned long coma_base1;
+    unsigned long coma_base2;
+    unsigned long coma_cnfg0;
+    unsigned long coma_cnfg1;
+    unsigned long coma_cnfg2;
+    unsigned long epic_dcsr;
+    unsigned long epic_pear;
+    unsigned long epic_sear;
+    unsigned long epic_tbr1;
+    unsigned long epic_tbr2;
+    unsigned long epic_pbr1;
+    unsigned long epic_pbr2;
+    unsigned long epic_pmr1;
+    unsigned long epic_pmr2;
+    unsigned long epic_harx1;
+    unsigned long epic_harx2;
+    unsigned long epic_pmlt;
+    unsigned long epic_tag0;
+    unsigned long epic_tag1;
+    unsigned long epic_tag2;
+    unsigned long epic_tag3;
+    unsigned long epic_tag4;
+    unsigned long epic_tag5;
+    unsigned long epic_tag6;
+    unsigned long epic_tag7;
+    unsigned long epic_data0;
+    unsigned long epic_data1;
+    unsigned long epic_data2;
+    unsigned long epic_data3;
+    unsigned long epic_data4;
+    unsigned long epic_data5;
+    unsigned long epic_data6;
+    unsigned long epic_data7;
 };
 
 #define RTC_PORT(x)    (0x70 + (x))
index 32b193855e6ad2d00d2b68c49cabc0aed7e55ad5..d816b7099846fba66019d7d2df1e306c9c338c1f 100644 (file)
@@ -1,9 +1,12 @@
-#ifndef __ARCH_I386_ATOMIC__
-#define __ARCH_I386_ATOMIC__
+#ifndef __ARCH_ALPHA_ATOMIC__
+#define __ARCH_ALPHA_ATOMIC__
 
 /*
  * Atomic operations that C can't guarantee us.  Useful for
- * resource counting etc..
+ * resource counting etc...
+ *
+ * But use these as seldom as possible since they are much more slower
+ * than regular operations.
  */
 
 /*
index 80e6a4b4221491a75e46b0e1bc029bd6e68bdfed..fc63727f41783e09aeb673d0e0e09a792e129ce8 100644 (file)
@@ -37,7 +37,7 @@
 #define _IOC_WRITE     4U
 
 #define _IOC(dir,type,nr,size)                 \
-       ((__u32)                                \
+       ((unsigned int)                         \
         (((dir)  << _IOC_DIRSHIFT) |           \
          ((type) << _IOC_TYPESHIFT) |          \
          ((nr)   << _IOC_NRSHIFT) |            \
@@ -63,4 +63,4 @@
 #define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
 #define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
 
-#endif
+#endif /* _ALPHA_IOCTL_H */
diff --git a/include/asm-alpha/ioctls.h b/include/asm-alpha/ioctls.h
new file mode 100644 (file)
index 0000000..bb4f71d
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef _ASM_ALPHA_IOCTLS_H
+#define _ASM_ALPHA_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+#define FIOCLEX                _IO('f', 1)
+#define FIONCLEX       _IO('f', 2)
+#define FIOASYNC       _IOW('f', 125, int)
+#define FIONBIO                _IOW('f', 126, int)
+#define FIONREAD       _IOR('f', 127, int)
+#define TIOCINQ                FIONREAD
+
+#define TIOCGETP       _IOR('t', 8, struct sgttyb)
+#define TIOCSETP       _IOW('t', 9, struct sgttyb)
+#define TIOCSETN       _IOW('t', 10, struct sgttyb)    /* TIOCSETP wo flush */
+
+#define TIOCSETC       _IOW('t', 17, struct tchars)
+#define TIOCGETC       _IOR('t', 18, struct tchars)
+#define TCGETS         _IOR('t', 19, struct termios)
+#define TCSETS         _IOW('t', 20, struct termios)
+#define TCSETSW                _IOW('t', 21, struct termios)
+#define TCSETSF                _IOW('t', 22, struct termios)
+
+#define TCGETA         _IOR('t', 23, struct termio)
+#define TCSETA         _IOW('t', 24, struct termio)
+#define TCSETAW                _IOW('t', 25, struct termio)
+#define TCSETAF                _IOW('t', 28, struct termio)
+
+#define TCSBRK         _IO('t', 29)
+#define TCXONC         _IO('t', 30)
+#define TCFLSH         _IO('t', 31)
+
+#define TIOCSWINSZ     _IOW('t', 103, struct winsize)
+#define TIOCGWINSZ     _IOR('t', 104, struct winsize)
+#define        TIOCSTART       _IO('t', 110)           /* start output, like ^Q */
+#define        TIOCSTOP        _IO('t', 111)           /* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCGLTC       _IOR('t', 116, struct ltchars)
+#define TIOCSLTC       _IOW('t', 117, struct ltchars)
+#define TIOCSPGRP      _IOW('t', 118, int)
+#define TIOCGPGRP      _IOR('t', 119, int)
+
+#define TIOCEXCL       0x540C
+#define TIOCNXCL       0x540D
+#define TIOCSCTTY      0x540E
+
+#define TIOCSTI                0x5412
+#define TIOCMGET       0x5415
+#define TIOCMBIS       0x5416
+#define TIOCMBIC       0x5417
+#define TIOCMSET       0x5418
+# define TIOCM_LE      0x001
+# define TIOCM_DTR     0x002
+# define TIOCM_RTS     0x004
+# define TIOCM_ST      0x008
+# define TIOCM_SR      0x010
+# define TIOCM_CTS     0x020
+# define TIOCM_CAR     0x040
+# define TIOCM_RNG     0x080
+# define TIOCM_DSR     0x100
+# define TIOCM_CD      TIOCM_CAR
+# define TIOCM_RI      TIOCM_RNG
+
+#define TIOCGSOFTCAR   0x5419
+#define TIOCSSOFTCAR   0x541A
+#define TIOCLINUX      0x541C
+#define TIOCCONS       0x541D
+#define TIOCGSERIAL    0x541E
+#define TIOCSSERIAL    0x541F
+#define TIOCPKT                0x5420
+# define TIOCPKT_DATA           0
+# define TIOCPKT_FLUSHREAD      1
+# define TIOCPKT_FLUSHWRITE     2
+# define TIOCPKT_STOP           4
+# define TIOCPKT_START          8
+# define TIOCPKT_NOSTOP                16
+# define TIOCPKT_DOSTOP                32
+
+
+#define TIOCNOTTY      0x5422
+#define TIOCSETD       0x5423
+#define TIOCGETD       0x5424
+#define TCSBRKP                0x5425  /* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT 0x5426  /* For debugging only */
+
+#define TIOCSERCONFIG  0x5453
+#define TIOCSERGWILD   0x5454
+#define TIOCSERSWILD   0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+  /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+# define TIOCSER_TEMT    0x01  /* Transmitter physically empty */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT     0x545C  /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT    0x545D  /* read serial port inline interrupt counts */
+
+#endif /* _ASM_ALPHA_IOCTLS_H */
index 3498d77c135de64f869fd979ed5ee9a812867a11..07382f5f1580f5f0173d0018e0df54b6420740b9 100644 (file)
@@ -1,14 +1,8 @@
-#ifndef _ASMAXP_PARAM_H
-#define _ASMAXP_PARAM_H
-
-#include <linux/config.h>
+#ifndef _ASM_ALPHA_PARAM_H
+#define _ASM_ALPHA_PARAM_H
 
 #ifndef HZ
-# if defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB66P)
-#  define HZ    977    /* Evaluation Boards seem to be a little odd */
-# else
-#  define HZ   1024    /* normal value for Alpha systems */
-# endif
+# define HZ    1024
 #endif
 
 #define EXEC_PAGESIZE  8192
@@ -23,4 +17,4 @@
 
 #define MAXHOSTNAMELEN 64      /* max length of hostname */
 
-#endif
+#endif /* _ASM_ALPHA_PARAM_H */
diff --git a/include/asm-alpha/posix_types.h b/include/asm-alpha/posix_types.h
new file mode 100644 (file)
index 0000000..ee5b31d
--- /dev/null
@@ -0,0 +1,94 @@
+#ifndef _ALPHA_POSIX_TYPES_H
+#define _ALPHA_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned int   __dev_t;
+typedef unsigned int   __ino_t;
+typedef unsigned int   __mode_t;
+typedef unsigned short __nlink_t;
+typedef long           __off_t;
+typedef int            __pid_t;
+typedef unsigned int   __uid_t;
+typedef unsigned int   __gid_t;
+typedef unsigned long  __size_t;
+typedef long           __ssize_t;
+typedef long           __ptrdiff_t;
+typedef long           __time_t;
+typedef long           __clock_t;
+typedef int            __daddr_t;
+typedef char *         __caddr_t;
+
+typedef struct {
+       int     val[2];
+} __fsid_t;
+
+#ifndef __GNUC__
+
+#define        __FD_SET(d, set)        ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+#define        __FD_CLR(d, set)        ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+#define        __FD_ISSET(d, set)      ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+#define        __FD_ZERO(set)  \
+  ((void) memset ((__ptr_t) (set), 0, sizeof (__fd_set)))
+
+#else /* __GNUC__ */
+
+/* With GNU C, use inline functions instead so args are evaluated only once: */
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __fd_set *p)
+{ 
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__fd_set *p)
+{
+       unsigned int *tmp = p->fds_bits;
+       int i;
+
+       if (__builtin_constant_p(__FDSET_INTS)) {
+               switch (__FDSET_INTS) {
+                       case 8:
+                               tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
+                               tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
+                               return;
+               }
+       }
+       i = __FDSET_INTS;
+       while (i) {
+               i--;
+               *tmp = 0;
+               tmp++;
+       }
+}
+
+#endif /* __GNUC__ */
+
+#endif /* _ALPHA_POSIX_TYPES_H */
index 20ca49a4fee588545f95fc458e17d825082d69d9..47bdbf7ce8183b02904e33c85bcae21129671e1a 100644 (file)
@@ -3,16 +3,7 @@
 
 #include <linux/types.h>
 #include <asm/ioctl.h>
-
-/* Socket-level I/O control calls. */
-#define FIOGETOWN      _IOR('f', 123, int)
-#define FIOSETOWN      _IOW('f', 124, int)
-
-#define SIOCATMARK     _IOR('s', 7, int)
-#define SIOCSPGRP      _IOW('s', 8, pid_t)
-#define SIOCGPGRP      _IOR('s', 9, pid_t)
-
-#define SIOCGSTAMP     0x8906                  /* Get stamp - linux-specific */
+#include <asm/sockios.h>
 
 /* For setsockoptions(2) */
 /*
diff --git a/include/asm-alpha/sockios.h b/include/asm-alpha/sockios.h
new file mode 100644 (file)
index 0000000..e4961a7
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _ASM_ALPHA_SOCKIOS_H
+#define _ASM_ALPHA_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+
+#define FIOGETOWN      _IOR('f', 123, int)
+#define FIOSETOWN      _IOW('f', 124, int)
+
+#define SIOCATMARK     _IOR('s', 7, int)
+#define SIOCSPGRP      _IOW('s', 8, pid_t)
+#define SIOCGPGRP      _IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP     0x8906          /* Get stamp - linux-specific */
+
+#endif /* _ASM_ALPHA_SOCKIOS_H */
index b2cd89057e1e6fa1591dfad854bf4b6ef0697dae..1f399b493d2cfb696fc453b318020b8448bdd3fb 100644 (file)
@@ -1,9 +1,13 @@
 #ifndef _ALPHA_STATFS_H
 #define _ALPHA_STATFS_H
 
-typedef struct {
-       int     val[2];
-} fsid_t;
+#ifndef _LINUX_TYPES_DONT_EXPORT
+
+#include <linux/posix_types.h>
+
+typedef __fsid_t       fsid_t;
+
+#endif
 
 /*
  * The OSF/1 statfs structure is much larger, but this should
@@ -19,7 +23,7 @@ struct statfs {
        int     f_bavail;
        int     f_files;
        int     f_ffree;
-       fsid_t  f_fsid;
+       __fsid_t f_fsid;
        /* linux-specific entries start here.. */
        int     f_namelen;
 };
diff --git a/include/asm-alpha/termbits.h b/include/asm-alpha/termbits.h
new file mode 100644 (file)
index 0000000..354a7ad
--- /dev/null
@@ -0,0 +1,176 @@
+#ifndef _ALPHA_TERMBITS_H
+#define _ALPHA_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char  cc_t;
+typedef unsigned int   speed_t;
+typedef unsigned int   tcflag_t;
+
+/*
+ * termios type and macro definitions.  Be careful about adding stuff
+ * to this file since it's used in GNU libc and there are strict rules
+ * concerning namespace pollution.
+ */
+
+#define NCCS 19
+struct termios {
+       tcflag_t c_iflag;               /* input mode flags */
+       tcflag_t c_oflag;               /* output mode flags */
+       tcflag_t c_cflag;               /* control mode flags */
+       tcflag_t c_lflag;               /* local mode flags */
+       cc_t c_cc[NCCS];                /* control characters */
+       cc_t c_line;                    /* line discipline (== c_cc[19]) */
+       speed_t c_ispeed;               /* input speed */
+       speed_t c_ospeed;               /* output speed */
+};
+
+/* c_cc characters */
+#define VEOF 0
+#define VEOL 1
+#define VEOL2 2
+#define VERASE 3
+#define VWERASE 4
+#define VKILL 5
+#define VREPRINT 6
+#define VSWTC 7
+#define VINTR 8
+#define VQUIT 9
+#define VSUSP 10
+#define VSTART 12
+#define VSTOP 13
+#define VLNEXT 14
+#define VDISCARD 15
+#define VMIN 16
+#define VTIME 17
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK  0000020
+#define ISTRIP 0000040
+#define INLCR  0000100
+#define IGNCR  0000200
+#define ICRNL  0000400
+#define IXON   0001000
+#define IXOFF  0002000
+#if !defined(KERNEL) || defined(__USE_BSD)
+  /* POSIX.1 doesn't want these... */
+# define IXANY         0004000
+# define IUCLC         0010000
+# define IMAXBEL       0020000
+#endif
+
+/* c_oflag bits */
+#define OPOST  0000001
+#define ONLCR  0000002
+#define OLCUC  0000004
+
+#define OCRNL  0000010
+#define ONOCR  0000020
+#define ONLRET 0000040
+
+#define OFILL  00000100
+#define OFDEL  00000200
+#define NLDLY  00001400
+#define   NL0  00000000
+#define   NL1  00000400
+#define   NL2  00001000
+#define   NL3  00001400
+#define TABDLY 00006000
+#define   TAB0 00000000
+#define   TAB1 00002000
+#define   TAB2 00004000
+#define   TAB3 00006000
+#define CRDLY  00030000
+#define   CR0  00000000
+#define   CR1  00010000
+#define   CR2  00020000
+#define   CR3  00030000
+#define FFDLY  00040000
+#define   FF0  00000000
+#define   FF1  00040000
+#define BSDLY  00100000
+#define   BS0  00000000
+#define   BS1  00100000
+#define VTDLY  00200000
+#define   VT0  00000000
+#define   VT1  00200000
+#define XTABS  01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
+
+/* c_cflag bit meaning */
+#define CBAUD  0000017
+#define  B0    0000000         /* hang up */
+#define  B50   0000001
+#define  B75   0000002
+#define  B110  0000003
+#define  B134  0000004
+#define  B150  0000005
+#define  B200  0000006
+#define  B300  0000007
+#define  B600  0000010
+#define  B1200 0000011
+#define  B1800 0000012
+#define  B2400 0000013
+#define  B4800 0000014
+#define  B9600 0000015
+#define  B19200        0000016
+#define  B38400        0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CBAUDEX 0000020
+#define  B57600   00020
+#define  B115200  00021
+#define  B230400  00022
+
+#define CSIZE  00001400
+#define   CS5  00000000
+#define   CS6  00000400
+#define   CS7  00001000
+#define   CS8  00001400
+
+#define CSTOPB 00002000
+#define CREAD  00004000
+#define PARENB 00010000
+#define PARODD 00020000
+#define HUPCL  00040000
+
+#define CLOCAL 00100000
+#define CRTSCTS          020000000000          /* flow control */
+
+/* c_lflag bits */
+#define ISIG   0x00000080
+#define ICANON 0x00000100
+#define XCASE  0x00004000
+#define ECHO   0x00000008
+#define ECHOE  0x00000002
+#define ECHOK  0x00000004
+#define ECHONL 0x00000010
+#define NOFLSH 0x80000000
+#define TOSTOP 0x00400000
+#define ECHOCTL        0x00000040
+#define ECHOPRT        0x00000020
+#define ECHOKE 0x00000001
+#define FLUSHO 0x00800000
+#define PENDIN 0x20000000
+#define IEXTEN 0x00000400
+
+/* Values for the ACTION argument to `tcflow'.  */
+#define        TCOOFF          0
+#define        TCOON           1
+#define        TCIOFF          2
+#define        TCION           3
+
+/* Values for the QUEUE_SELECTOR argument to `tcflush'.  */
+#define        TCIFLUSH        0
+#define        TCOFLUSH        1
+#define        TCIOFLUSH       2
+
+/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'.  */
+#define        TCSANOW         0
+#define        TCSADRAIN       1
+#define        TCSAFLUSH       2
+
+#endif /* _ALPHA_TERMBITS_H */
index 9074112da11ec739d2e735903636c8220af2d386..37a3333bd0ea7a87395e717fcac716203cf4fbe4 100644 (file)
@@ -1,9 +1,8 @@
 #ifndef _ALPHA_TERMIOS_H
 #define _ALPHA_TERMIOS_H
 
-#include <linux/types.h>
-
-#include <asm/ioctl.h>
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
 
 struct sgttyb {
        char    sg_ispeed;
@@ -31,89 +30,6 @@ struct ltchars {
        char    t_lnextc;
 };
 
-#define FIOCLEX                _IO('f', 1)
-#define FIONCLEX       _IO('f', 2)
-#define FIOASYNC       _IOW('f', 125, int)
-#define FIONBIO                _IOW('f', 126, int)
-#define FIONREAD       _IOR('f', 127, int)
-#define TIOCINQ                FIONREAD
-
-#define TIOCGETP       _IOR('t', 8, struct sgttyb)
-#define TIOCSETP       _IOW('t', 9, struct sgttyb)
-#define TIOCSETN       _IOW('t', 10, struct sgttyb)    /* TIOCSETP wo flush */
-
-#define TIOCSETC       _IOW('t', 17, struct tchars)
-#define TIOCGETC       _IOR('t', 18, struct tchars)
-#define TCGETS         _IOR('t', 19, struct termios)
-#define TCSETS         _IOW('t', 20, struct termios)
-#define TCSETSW                _IOW('t', 21, struct termios)
-#define TCSETSF                _IOW('t', 22, struct termios)
-
-#define TCGETA         _IOR('t', 23, struct termio)
-#define TCSETA         _IOW('t', 24, struct termio)
-#define TCSETAW                _IOW('t', 25, struct termio)
-#define TCSETAF                _IOW('t', 28, struct termio)
-
-#define TCSBRK         _IO('t', 29)
-#define TCXONC         _IO('t', 30)
-#define TCFLSH         _IO('t', 31)
-
-#define TIOCSWINSZ     _IOW('t', 103, struct winsize)
-#define TIOCGWINSZ     _IOR('t', 104, struct winsize)
-#define        TIOCSTART       _IO('t', 110)           /* start output, like ^Q */
-#define        TIOCSTOP        _IO('t', 111)           /* stop output, like ^S */
-#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
-
-#define TIOCGLTC       _IOR('t', 116, struct ltchars)
-#define TIOCSLTC       _IOW('t', 117, struct ltchars)
-#define TIOCSPGRP      _IOW('t', 118, int)
-#define TIOCGPGRP      _IOR('t', 119, int)
-
-#define TIOCEXCL       0x540C
-#define TIOCNXCL       0x540D
-#define TIOCSCTTY      0x540E
-
-#define TIOCSTI                0x5412
-#define TIOCMGET       0x5415
-#define TIOCMBIS       0x5416
-#define TIOCMBIC       0x5417
-#define TIOCMSET       0x5418
-#define TIOCGSOFTCAR   0x5419
-#define TIOCSSOFTCAR   0x541A
-#define TIOCLINUX      0x541C
-#define TIOCCONS       0x541D
-#define TIOCGSERIAL    0x541E
-#define TIOCSSERIAL    0x541F
-#define TIOCPKT                0x5420
-
-#define TIOCNOTTY      0x5422
-#define TIOCSETD       0x5423
-#define TIOCGETD       0x5424
-#define TCSBRKP                0x5425  /* Needed for POSIX tcsendbreak() */
-#define TIOCTTYGSTRUCT 0x5426  /* For debugging only */
-
-#define TIOCSERCONFIG  0x5453
-#define TIOCSERGWILD   0x5454
-#define TIOCSERSWILD   0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR   0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT     0x545C  /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT    0x545D  /* read serial port inline interrupt counts */
-
-/* Used for packet mode */
-#define TIOCPKT_DATA            0
-#define TIOCPKT_FLUSHREAD       1
-#define TIOCPKT_FLUSHWRITE      2
-#define TIOCPKT_STOP            4
-#define TIOCPKT_START           8
-#define TIOCPKT_NOSTOP         16
-#define TIOCPKT_DOSTOP         32
-
 struct winsize {
        unsigned short ws_row;
        unsigned short ws_col;
@@ -131,40 +47,13 @@ struct termio {
        unsigned char c_cc[NCC];        /* control characters */
 };
 
-#define NCCS 19
-struct termios {
-       tcflag_t c_iflag;               /* input mode flags */
-       tcflag_t c_oflag;               /* output mode flags */
-       tcflag_t c_cflag;               /* control mode flags */
-       tcflag_t c_lflag;               /* local mode flags */
-       cc_t c_cc[NCCS];                /* control characters */
-       cc_t c_line;                    /* line discipline (== c_cc[19]) */
-       int c_ispeed;                   /* input speed */
-       int c_ospeed;                   /* output speed */
-};
-
-/* c_cc characters */
-#define VEOF 0
-#define VEOL 1
-#define VEOL2 2
-#define VERASE 3
-#define VWERASE 4
-#define VKILL 5
-#define VREPRINT 6
-#define VSWTC 7
-#define VINTR 8
-#define VQUIT 9
-#define VSUSP 10
-#define VSTART 12
-#define VSTOP 13
-#define VLNEXT 14
-#define VDISCARD 15
-#define VMIN 16
-#define VTIME 17
-
 /*
- * ..and the same for c_cc in the termio structure.. 
- * Oh, how I love being backwardly compatible.
+ * c_cc characters in the termio structure.  Oh, how I love being
+ * backwardly compatible.  Notice that character 4 and 5 are
+ * interpreted differently depending on whether ICANON is set in
+ * c_lflag.  If it's set, they are used as _VEOF and _VEOL, otherwise
+ * as _VMIN and V_TIME.  This is for compatibility with OSF/1 (which
+ * is compatible with sysV)...
  */
 #define _VINTR 0
 #define _VQUIT 1
@@ -177,6 +66,12 @@ struct termios {
 #define _VEOL2 6
 #define _VSWTC 7
 
+/* line disciplines */
+#define N_TTY          0
+#define N_SLIP         1
+#define N_MOUSE                2
+#define N_PPP          3
+
 #ifdef __KERNEL__
 /*     eof=^D          eol=\0          eol2=\0         erase=del
        werase=^W       kill=^U         reprint=^R      sxtc=\0
@@ -185,158 +80,6 @@ struct termios {
        vmin=\1         vtime=\0
 */
 #define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000"
-#endif
-
-/* c_iflag bits */
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK  0000020
-#define ISTRIP 0000040
-#define INLCR  0000100
-#define IGNCR  0000200
-#define ICRNL  0000400
-#define IXON   0001000
-#define IXOFF  0002000
-#define IXANY  0004000
-#define IUCLC  0010000
-#define IMAXBEL        0020000
-
-/* c_oflag bits */
-#define OPOST  0000001
-#define ONLCR  0000002
-#define OLCUC  0000004
-
-#define OCRNL  0000010
-#define ONOCR  0000020
-#define ONLRET 0000040
-
-#define OFILL  00000100
-#define OFDEL  00000200
-#define NLDLY  00001400
-#define   NL0  00000000
-#define   NL1  00000400
-#define   NL2  00001000
-#define   NL3  00001400
-#define TABDLY 00006000
-#define   TAB0 00000000
-#define   TAB1 00002000
-#define   TAB2 00004000
-#define   TAB3 00006000
-#define CRDLY  00030000
-#define   CR0  00000000
-#define   CR1  00010000
-#define   CR2  00020000
-#define   CR3  00030000
-#define FFDLY  00040000
-#define   FF0  00000000
-#define   FF1  00040000
-#define BSDLY  00100000
-#define   BS0  00000000
-#define   BS1  00100000
-#define VTDLY  00200000
-#define   VT0  00000000
-#define   VT1  00200000
-#define XTABS  01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
-
-/* c_cflag bit meaning */
-#define CBAUD  0000017
-#define  B0    0000000         /* hang up */
-#define  B50   0000001
-#define  B75   0000002
-#define  B110  0000003
-#define  B134  0000004
-#define  B150  0000005
-#define  B200  0000006
-#define  B300  0000007
-#define  B600  0000010
-#define  B1200 0000011
-#define  B1800 0000012
-#define  B2400 0000013
-#define  B4800 0000014
-#define  B9600 0000015
-#define  B19200        0000016
-#define  B38400        0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CBAUDEX 0000020
-#define  B57600   00020
-#define  B115200  00021
-#define  B230400  00022
-
-#define CSIZE  00001400
-#define   CS5  00000000
-#define   CS6  00000400
-#define   CS7  00001000
-#define   CS8  00001400
-
-#define CSTOPB 00002000
-#define CREAD  00004000
-#define PARENB 00010000
-#define PARODD 00020000
-#define HUPCL  00040000
-
-#define CLOCAL 00100000
-#define CRTSCTS          020000000000          /* flow control */
-
-/* c_lflag bits */
-#define ISIG   0x00000080
-#define ICANON 0x00000100
-#define XCASE  0x00004000
-#define ECHO   0x00000008
-#define ECHOE  0x00000002
-#define ECHOK  0x00000004
-#define ECHONL 0x00000010
-#define NOFLSH 0x80000000
-#define TOSTOP 0x00400000
-#define ECHOCTL        0x00000040
-#define ECHOPRT        0x00000020
-#define ECHOKE 0x00000001
-#define FLUSHO 0x00800000
-#define PENDIN 0x20000000
-#define IEXTEN 0x00000400
-
-/* modem lines */
-#define TIOCM_LE       0x001
-#define TIOCM_DTR      0x002
-#define TIOCM_RTS      0x004
-#define TIOCM_ST       0x008
-#define TIOCM_SR       0x010
-#define TIOCM_CTS      0x020
-#define TIOCM_CAR      0x040
-#define TIOCM_RNG      0x080
-#define TIOCM_DSR      0x100
-#define TIOCM_CD       TIOCM_CAR
-#define TIOCM_RI       TIOCM_RNG
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
-
-
-/* tcflow() and TCXONC use these */
-#define        TCOOFF          0
-#define        TCOON           1
-#define        TCIOFF          2
-#define        TCION           3
-
-/* tcflush() and TCFLSH use these */
-#define        TCIFLUSH        0
-#define        TCOFLUSH        1
-#define        TCIOFLUSH       2
-
-/* tcsetattr uses these */
-#define        TCSANOW         0
-#define        TCSADRAIN       1
-#define        TCSAFLUSH       2
-
-/* line disciplines */
-#define N_TTY          0
-#define N_SLIP         1
-#define N_MOUSE                2
-#define N_PPP          3
-
-#ifdef __KERNEL__
 
 /*
  * Translate a "termio" structure into a "termios". Ugh.
index 4276f2f2626fd47e9ca65e3ddb6fe8c8df2b6f36..28e5d487de089a6cd180e180d08e1f7bcb31762d 100644 (file)
@@ -1,41 +1,15 @@
 #ifndef _ALPHA_TYPES_H
 #define _ALPHA_TYPES_H
 
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned long size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef long ssize_t;
-#endif
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef long ptrdiff_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue.  However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
 
-typedef int pid_t;
-typedef unsigned int uid_t;
-typedef unsigned int gid_t;
-typedef unsigned int dev_t;
-typedef unsigned int ino_t;
-typedef unsigned int mode_t;
 typedef unsigned int umode_t;
-typedef unsigned short nlink_t;
-typedef int daddr_t;
-typedef long off_t;
 
 /*
  * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -98,55 +72,4 @@ typedef unsigned long u64;
 #endif
 
 #endif /* __KERNEL__ */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, fd_set *fdsetp)
-{
-       unsigned long _tmp = fd / __NFDBITS;
-       unsigned long _rem = fd % __NFDBITS;
-       fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, fd_set *fdsetp)
-{
-       unsigned long _tmp = fd / __NFDBITS;
-       unsigned long _rem = fd % __NFDBITS;
-       fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, fd_set *p)
-{ 
-       unsigned long _tmp = fd / __NFDBITS;
-       unsigned long _rem = fd % __NFDBITS;
-       return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(fd_set *p)
-{
-       unsigned int *tmp = p->fds_bits;
-       int i;
-
-       if (__builtin_constant_p(__FDSET_INTS)) {
-               switch (__FDSET_INTS) {
-                       case 8:
-                               tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
-                               tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
-                               return;
-               }
-       }
-       i = __FDSET_INTS;
-       while (i) {
-               i--;
-               *tmp = 0;
-               tmp++;
-       }
-}
-
-#endif
+#endif /* _ALPHA_TYPES_H */
diff --git a/include/asm-i386/ioctls.h b/include/asm-i386/ioctls.h
new file mode 100644 (file)
index 0000000..60e0806
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __ARCH_I386_IOCTLS_H__
+#define __ARCH_I386_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS         0x5401
+#define TCSETS         0x5402
+#define TCSETSW                0x5403
+#define TCSETSF                0x5404
+#define TCGETA         0x5405
+#define TCSETA         0x5406
+#define TCSETAW                0x5407
+#define TCSETAF                0x5408
+#define TCSBRK         0x5409
+#define TCXONC         0x540A
+#define TCFLSH         0x540B
+#define TIOCEXCL       0x540C
+#define TIOCNXCL       0x540D
+#define TIOCSCTTY      0x540E
+#define TIOCGPGRP      0x540F
+#define TIOCSPGRP      0x5410
+#define TIOCOUTQ       0x5411
+#define TIOCSTI                0x5412
+#define TIOCGWINSZ     0x5413
+#define TIOCSWINSZ     0x5414
+#define TIOCMGET       0x5415
+#define TIOCMBIS       0x5416
+#define TIOCMBIC       0x5417
+#define TIOCMSET       0x5418
+#define TIOCGSOFTCAR   0x5419
+#define TIOCSSOFTCAR   0x541A
+#define FIONREAD       0x541B
+#define TIOCINQ                FIONREAD
+#define TIOCLINUX      0x541C
+#define TIOCCONS       0x541D
+#define TIOCGSERIAL    0x541E
+#define TIOCSSERIAL    0x541F
+#define TIOCPKT                0x5420
+#define FIONBIO                0x5421
+#define TIOCNOTTY      0x5422
+#define TIOCSETD       0x5423
+#define TIOCGETD       0x5424
+#define TCSBRKP                0x5425  /* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT 0x5426  /* For debugging only */
+#define FIONCLEX       0x5450  /* these numbers need to be adjusted. */
+#define FIOCLEX                0x5451
+#define FIOASYNC       0x5452
+#define TIOCSERCONFIG  0x5453
+#define TIOCSERGWILD   0x5454
+#define TIOCSERSWILD   0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT     0x545C  /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT    0x545D  /* read serial port inline interrupt counts */
+
+/* Used for packet mode */
+#define TIOCPKT_DATA            0
+#define TIOCPKT_FLUSHREAD       1
+#define TIOCPKT_FLUSHWRITE      2
+#define TIOCPKT_STOP            4
+#define TIOCPKT_START           8
+#define TIOCPKT_NOSTOP         16
+#define TIOCPKT_DOSTOP         32
+
+#define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
+
+#endif
diff --git a/include/asm-i386/posix_types.h b/include/asm-i386/posix_types.h
new file mode 100644 (file)
index 0000000..f2d8682
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef __ARCH_I386_POSIX_TYPES_H
+#define __ARCH_I386_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned short __dev_t;
+typedef unsigned long  __ino_t;
+typedef unsigned short __mode_t;
+typedef unsigned short __nlink_t;
+typedef long           __off_t;
+typedef int            __pid_t;
+typedef unsigned short __uid_t;
+typedef unsigned short __gid_t;
+typedef unsigned int   __size_t;
+typedef int            __ssize_t;
+typedef int            __ptrdiff_t;
+typedef long           __time_t;
+typedef long           __clock_t;
+typedef int            __daddr_t;
+typedef char *         __caddr_t;
+
+#undef __FD_SET
+#define __FD_SET(fd,fdsetp) \
+               __asm__ __volatile__("btsl %1,%0": \
+                       "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
+
+#undef __FD_CLR
+#define __FD_CLR(fd,fdsetp) \
+               __asm__ __volatile__("btrl %1,%0": \
+                       "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
+
+#undef __FD_ISSET
+#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
+               unsigned char __result; \
+               __asm__ __volatile__("btl %1,%2 ; setb %0" \
+                       :"=q" (__result) :"r" ((int) (fd)), \
+                       "m" (*(fd_set *) (fdsetp))); \
+               __result; }))
+
+#undef __FD_ZERO
+#define __FD_ZERO(fdsetp) \
+               __asm__ __volatile__("cld ; rep ; stosl" \
+                       :"=m" (*(fd_set *) (fdsetp)) \
+                       :"a" (0), "c" (__FDSET_INTS), \
+                       "D" ((fd_set *) (fdsetp)) :"cx","di")
+
+#endif
index c2e40d685517f2cad57aee115b22cf6ff38a6049..e8986470e09d25decb9d568eb081d8fd1089e9f7 100644 (file)
@@ -175,13 +175,14 @@ extern struct cpuinfo_x86 cpu_data[NR_CPUS];
  */
  
 extern int smp_found_config;
-extern void smp_scan_config(unsigned long, unsigned long);
+extern int smp_scan_config(unsigned long, unsigned long);
 extern unsigned long smp_alloc_memory(unsigned long mem_base);
 extern unsigned char *apic_reg;
 extern unsigned char *kernel_stacks[NR_CPUS];
 extern unsigned char boot_cpu_id;
 extern unsigned long cpu_present_map;
 extern volatile int cpu_number_map[NR_CPUS];
+extern volatile int cpu_logical_map[NR_CPUS];
 extern volatile unsigned long smp_invalidate_needed;
 extern void smp_invalidate(void);
 extern volatile unsigned long kernel_flag, kernel_counter;
index dc9230061f0182ac5e868992e8f01fca383231f0..529a3ffefa6f89c51dc04fe0367af135cb8ff768 100644 (file)
@@ -1,13 +1,7 @@
 #ifndef _ASM_SOCKET_H
 #define _ASM_SOCKET_H
 
-/* Socket-level I/O control calls. */
-#define FIOSETOWN      0x8901
-#define SIOCSPGRP      0x8902
-#define FIOGETOWN      0x8903
-#define SIOCGPGRP      0x8904
-#define SIOCATMARK     0x8905
-#define SIOCGSTAMP     0x8906          /* Get stamp */
+#include <asm/sockios.h>
 
 /* For setsockoptions(2) */
 #define SOL_SOCKET     1
diff --git a/include/asm-i386/sockios.h b/include/asm-i386/sockios.h
new file mode 100644 (file)
index 0000000..6b747f8
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __ARCH_I386_SOCKIOS__
+#define __ARCH_I386_SOCKIOS__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN      0x8901
+#define SIOCSPGRP      0x8902
+#define FIOGETOWN      0x8903
+#define SIOCGPGRP      0x8904
+#define SIOCATMARK     0x8905
+#define SIOCGSTAMP     0x8906          /* Get stamp */
+
+#endif
index e79720e5dd8f8d70feab7e3153fb2eb8046e2ad4..1d067077e3b6b6b8a43efe9c5934ea1ee295c3f4 100644 (file)
@@ -402,6 +402,10 @@ extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
                case 4:
                        *(unsigned long *)to = *(const unsigned long *)from;
                        return to;
+               case 8:
+                       *(unsigned long *)to = *(const unsigned long *)from;
+                       *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+                       return to;
        }
 #define COMMON(x) \
 __asm__("cld\n\t" \
diff --git a/include/asm-i386/termbits.h b/include/asm-i386/termbits.h
new file mode 100644 (file)
index 0000000..3633f67
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef __ARCH_I386_TERMBITS_H__
+#define __ARCH_I386_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char  cc_t;
+typedef unsigned int   speed_t;
+typedef unsigned int   tcflag_t;
+
+#define NCCS 19
+struct termios {
+       tcflag_t c_iflag;               /* input mode flags */
+       tcflag_t c_oflag;               /* output mode flags */
+       tcflag_t c_cflag;               /* control mode flags */
+       tcflag_t c_lflag;               /* local mode flags */
+       cc_t c_line;                    /* line discipline */
+       cc_t c_cc[NCCS];                /* control characters */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK  0000020
+#define ISTRIP 0000040
+#define INLCR  0000100
+#define IGNCR  0000200
+#define ICRNL  0000400
+#define IUCLC  0001000
+#define IXON   0002000
+#define IXANY  0004000
+#define IXOFF  0010000
+#define IMAXBEL        0020000
+
+/* c_oflag bits */
+#define OPOST  0000001
+#define OLCUC  0000002
+#define ONLCR  0000004
+#define OCRNL  0000010
+#define ONOCR  0000020
+#define ONLRET 0000040
+#define OFILL  0000100
+#define OFDEL  0000200
+#define NLDLY  0000400
+#define   NL0  0000000
+#define   NL1  0000400
+#define CRDLY  0003000
+#define   CR0  0000000
+#define   CR1  0001000
+#define   CR2  0002000
+#define   CR3  0003000
+#define TABDLY 0014000
+#define   TAB0 0000000
+#define   TAB1 0004000
+#define   TAB2 0010000
+#define   TAB3 0014000
+#define   XTABS        0014000
+#define BSDLY  0020000
+#define   BS0  0000000
+#define   BS1  0020000
+#define VTDLY  0040000
+#define   VT0  0000000
+#define   VT1  0040000
+#define FFDLY  0100000
+#define   FF0  0000000
+#define   FF1  0100000
+
+/* c_cflag bit meaning */
+#define CBAUD  0010017
+#define  B0    0000000         /* hang up */
+#define  B50   0000001
+#define  B75   0000002
+#define  B110  0000003
+#define  B134  0000004
+#define  B150  0000005
+#define  B200  0000006
+#define  B300  0000007
+#define  B600  0000010
+#define  B1200 0000011
+#define  B1800 0000012
+#define  B2400 0000013
+#define  B4800 0000014
+#define  B9600 0000015
+#define  B19200        0000016
+#define  B38400        0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE  0000060
+#define   CS5  0000000
+#define   CS6  0000020
+#define   CS7  0000040
+#define   CS8  0000060
+#define CSTOPB 0000100
+#define CREAD  0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL  0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define  B57600  0010001
+#define  B115200 0010002
+#define  B230400 0010003
+#define CIBAUD   002003600000  /* input baud rate (not used) */
+#define CRTSCTS          020000000000          /* flow control */
+
+/* c_lflag bits */
+#define ISIG   0000001
+#define ICANON 0000002
+#define XCASE  0000004
+#define ECHO   0000010
+#define ECHOE  0000020
+#define ECHOK  0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL        0001000
+#define ECHOPRT        0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+#define        TCOOFF          0
+#define        TCOON           1
+#define        TCIOFF          2
+#define        TCION           3
+
+/* tcflush() and TCFLSH use these */
+#define        TCIFLUSH        0
+#define        TCOFLUSH        1
+#define        TCIOFLUSH       2
+
+/* tcsetattr uses these */
+#define        TCSANOW         0
+#define        TCSADRAIN       1
+#define        TCSAFLUSH       2
+
+#endif
index de03be1f09fa860f3ba21a74947e39dc1b199953..07f949172edd373ba11ad9ac069f32c289f1be41 100644 (file)
@@ -1,71 +1,8 @@
 #ifndef _I386_TERMIOS_H
 #define _I386_TERMIOS_H
 
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS         0x5401
-#define TCSETS         0x5402
-#define TCSETSW                0x5403
-#define TCSETSF                0x5404
-#define TCGETA         0x5405
-#define TCSETA         0x5406
-#define TCSETAW                0x5407
-#define TCSETAF                0x5408
-#define TCSBRK         0x5409
-#define TCXONC         0x540A
-#define TCFLSH         0x540B
-#define TIOCEXCL       0x540C
-#define TIOCNXCL       0x540D
-#define TIOCSCTTY      0x540E
-#define TIOCGPGRP      0x540F
-#define TIOCSPGRP      0x5410
-#define TIOCOUTQ       0x5411
-#define TIOCSTI                0x5412
-#define TIOCGWINSZ     0x5413
-#define TIOCSWINSZ     0x5414
-#define TIOCMGET       0x5415
-#define TIOCMBIS       0x5416
-#define TIOCMBIC       0x5417
-#define TIOCMSET       0x5418
-#define TIOCGSOFTCAR   0x5419
-#define TIOCSSOFTCAR   0x541A
-#define FIONREAD       0x541B
-#define TIOCINQ                FIONREAD
-#define TIOCLINUX      0x541C
-#define TIOCCONS       0x541D
-#define TIOCGSERIAL    0x541E
-#define TIOCSSERIAL    0x541F
-#define TIOCPKT                0x5420
-#define FIONBIO                0x5421
-#define TIOCNOTTY      0x5422
-#define TIOCSETD       0x5423
-#define TIOCGETD       0x5424
-#define TCSBRKP                0x5425  /* Needed for POSIX tcsendbreak() */
-#define TIOCTTYGSTRUCT 0x5426  /* For debugging only */
-#define FIONCLEX       0x5450  /* these numbers need to be adjusted. */
-#define FIOCLEX                0x5451
-#define FIOASYNC       0x5452
-#define TIOCSERCONFIG  0x5453
-#define TIOCSERGWILD   0x5454
-#define TIOCSERSWILD   0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR   0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT     0x545C  /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT    0x545D  /* read serial port inline interrupt counts */
-
-/* Used for packet mode */
-#define TIOCPKT_DATA            0
-#define TIOCPKT_FLUSHREAD       1
-#define TIOCPKT_FLUSHWRITE      2
-#define TIOCPKT_STOP            4
-#define TIOCPKT_START           8
-#define TIOCPKT_NOSTOP         16
-#define TIOCPKT_DOSTOP         32
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
 
 struct winsize {
        unsigned short ws_row;
@@ -84,35 +21,6 @@ struct termio {
        unsigned char c_cc[NCC];        /* control characters */
 };
 
-#define NCCS 19
-struct termios {
-       tcflag_t c_iflag;               /* input mode flags */
-       tcflag_t c_oflag;               /* output mode flags */
-       tcflag_t c_cflag;               /* control mode flags */
-       tcflag_t c_lflag;               /* local mode flags */
-       cc_t c_line;                    /* line discipline */
-       cc_t c_cc[NCCS];                /* control characters */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
 #ifdef __KERNEL__
 /*     intr=^C         quit=^\         erase=del       kill=^U
        eof=^D          vtime=\0        vmin=\1         sxtc=\0
@@ -123,110 +31,6 @@ struct termios {
 #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
 #endif
 
-/* c_iflag bits */
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK  0000020
-#define ISTRIP 0000040
-#define INLCR  0000100
-#define IGNCR  0000200
-#define ICRNL  0000400
-#define IUCLC  0001000
-#define IXON   0002000
-#define IXANY  0004000
-#define IXOFF  0010000
-#define IMAXBEL        0020000
-
-/* c_oflag bits */
-#define OPOST  0000001
-#define OLCUC  0000002
-#define ONLCR  0000004
-#define OCRNL  0000010
-#define ONOCR  0000020
-#define ONLRET 0000040
-#define OFILL  0000100
-#define OFDEL  0000200
-#define NLDLY  0000400
-#define   NL0  0000000
-#define   NL1  0000400
-#define CRDLY  0003000
-#define   CR0  0000000
-#define   CR1  0001000
-#define   CR2  0002000
-#define   CR3  0003000
-#define TABDLY 0014000
-#define   TAB0 0000000
-#define   TAB1 0004000
-#define   TAB2 0010000
-#define   TAB3 0014000
-#define   XTABS        0014000
-#define BSDLY  0020000
-#define   BS0  0000000
-#define   BS1  0020000
-#define VTDLY  0040000
-#define   VT0  0000000
-#define   VT1  0040000
-#define FFDLY  0100000
-#define   FF0  0000000
-#define   FF1  0100000
-
-/* c_cflag bit meaning */
-#define CBAUD  0010017
-#define  B0    0000000         /* hang up */
-#define  B50   0000001
-#define  B75   0000002
-#define  B110  0000003
-#define  B134  0000004
-#define  B150  0000005
-#define  B200  0000006
-#define  B300  0000007
-#define  B600  0000010
-#define  B1200 0000011
-#define  B1800 0000012
-#define  B2400 0000013
-#define  B4800 0000014
-#define  B9600 0000015
-#define  B19200        0000016
-#define  B38400        0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE  0000060
-#define   CS5  0000000
-#define   CS6  0000020
-#define   CS7  0000040
-#define   CS8  0000060
-#define CSTOPB 0000100
-#define CREAD  0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL  0002000
-#define CLOCAL 0004000
-#define CBAUDEX 0010000
-#define  B57600  0010001
-#define  B115200 0010002
-#define  B230400 0010003
-#define CIBAUD   002003600000  /* input baud rate (not used) */
-#define CRTSCTS          020000000000          /* flow control */
-
-/* c_lflag bits */
-#define ISIG   0000001
-#define ICANON 0000002
-#define XCASE  0000004
-#define ECHO   0000010
-#define ECHOE  0000020
-#define ECHOK  0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define ECHOCTL        0001000
-#define ECHOPRT        0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-#define IEXTEN 0100000
-
 /* modem lines */
 #define TIOCM_LE       0x001
 #define TIOCM_DTR      0x002
@@ -241,24 +45,6 @@ struct termios {
 #define TIOCM_RI       TIOCM_RNG
 
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
-
-
-/* tcflow() and TCXONC use these */
-#define        TCOOFF          0
-#define        TCOON           1
-#define        TCIOFF          2
-#define        TCION           3
-
-/* tcflush() and TCFLSH use these */
-#define        TCIFLUSH        0
-#define        TCOFLUSH        1
-#define        TCIOFLUSH       2
-
-/* tcsetattr uses these */
-#define        TCSANOW         0
-#define        TCSADRAIN       1
-#define        TCSAFLUSH       2
 
 /* line disciplines */
 #define N_TTY          0
@@ -276,7 +62,7 @@ struct termios {
 extern inline void trans_from_termio(struct termio * termio,
        struct termios * termios)
 {
-#define SET_LOW_BITS(x,y)      ((x) = (0xffff0000 & (x)) | (y))
+#define SET_LOW_BITS(x,y)      (*(unsigned short *)(&x) = (y))
        SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
        SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
        SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
index ec3df86ef18d0d6fdfb678b049ab5a291641210e..71309ac823de08de6027ac69faa720488f3aa7d7 100644 (file)
@@ -1,41 +1,7 @@
 #ifndef _I386_TYPES_H
 #define _I386_TYPES_H
 
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef int ptrdiff_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-
-typedef int pid_t;
-typedef unsigned short uid_t;
-typedef unsigned short gid_t;
-typedef unsigned short dev_t;
-typedef unsigned long ino_t;
-typedef unsigned short mode_t;
 typedef unsigned short umode_t;
-typedef unsigned short nlink_t;
-typedef int daddr_t;
-typedef long off_t;
 
 /*
  * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -75,29 +41,4 @@ typedef unsigned long long u64;
 
 #endif /* __KERNEL__ */
 
-#undef __FD_SET
-#define __FD_SET(fd,fdsetp) \
-               __asm__ __volatile__("btsl %1,%0": \
-                       "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef __FD_CLR
-#define __FD_CLR(fd,fdsetp) \
-               __asm__ __volatile__("btrl %1,%0": \
-                       "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef __FD_ISSET
-#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
-               unsigned char __result; \
-               __asm__ __volatile__("btl %1,%2 ; setb %0" \
-                       :"=q" (__result) :"r" ((int) (fd)), \
-                       "m" (*(fd_set *) (fdsetp))); \
-               __result; }))
-
-#undef __FD_ZERO
-#define __FD_ZERO(fdsetp) \
-               __asm__ __volatile__("cld ; rep ; stosl" \
-                       :"=m" (*(fd_set *) (fdsetp)) \
-                       :"a" (0), "c" (__FDSET_INTS), \
-                       "D" ((fd_set *) (fdsetp)) :"cx","di")
-
 #endif
index 1837f210fa0bf4aebe00dea9508b7843f8ed31ed..3d8ca8fbd435c3aab33edd12959bff45b7b5e3a9 100644 (file)
 #define __NR_sched_get_priority_min    160
 #define __NR_sched_rr_get_interval     161
 #define __NR_nanosleep         162
+#define __NR_mremap            163
 
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
index b5234136871e2973c1f61a462fb5f7e6ccf3d586..c70d0577b698ffb73f35df42f379fcfef29c9b31 100644 (file)
@@ -140,5 +140,9 @@ extern struct atalk_iface *atalk_find_dev(struct device *dev);
 extern struct at_addr *atalk_find_dev_addr(struct device *dev);
 extern int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr);
 extern void aarp_send_probe(struct device *dev, struct at_addr *addr);
+#ifdef MODULE
+extern void aarp_cleanup_module(void);
+#endif
+
 #endif
 #endif
index 49d65750d0c1e0c1b5eef5ddb9f6a91c55bdb891..4ab606c10cece9f0a42b379506ec33cdd03f8cd4 100644 (file)
@@ -51,6 +51,7 @@ extern int init_aout_binfmt(void);
 extern int init_script_binfmt(void);
 
 extern int prepare_binprm(struct linux_binprm *);
+extern void remove_arg_zero(struct linux_binprm *);
 extern int search_binary_handler(struct linux_binprm *,struct pt_regs *);
 extern void flush_old_exec(struct linux_binprm * bprm);
 extern unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm);
index 04d1c88f9ad679610629c5d84474c4778ef8846c..4685165fd721abf382b54753610f317e897e5122 100644 (file)
@@ -319,6 +319,8 @@ static void floppy_off(unsigned int nr);
 #define CURRENT (blk_dev[MAJOR_NR].current_request)
 #endif
 
+#define CURRENT_PLUGGED IS_PLUGGED(blk_dev+MAJOR_NR)
+
 #define CURRENT_DEV DEVICE_NR(CURRENT->rq_dev)
 
 #ifdef DEVICE_INTR
@@ -356,7 +358,7 @@ static void (DEVICE_REQUEST)(void);
 #endif
 
 #define INIT_REQUEST \
-       if (!CURRENT) {\
+       if (!CURRENT || CURRENT_PLUGGED) {\
                CLEAR_INTR; \
                return; \
        } \
index 65287871b7494fb29fb8ed8c5f042f5aa5415378..f261aca324ba4b8590f0f009e5499293de7380ed 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/major.h>
 #include <linux/sched.h>
 #include <linux/genhd.h>
+#include <linux/tqueue.h>
 
 /*
  * Ok, this is an expanded form so that we can use the same
@@ -35,8 +36,11 @@ struct request {
 struct blk_dev_struct {
        void (*request_fn)(void);
        struct request * current_request;
+       struct tq_struct plug_tq;
 };
 
+#define IS_PLUGGED(dev) ((dev)->plug_tq.sync)
+
 struct sec_size {
        unsigned block_size;
        unsigned block_size_bits;
index 0fa1186fa25a7dbb91a109a20a802def80a40a7b..1487ae79e532ec29f3c35d9ddec6b62f172f7506 100644 (file)
@@ -480,6 +480,7 @@ extern int do_truncate(struct inode *, unsigned long);
 extern int register_blkdev(unsigned int, const char *, struct file_operations *);
 extern int unregister_blkdev(unsigned int major, const char * name);
 extern int blkdev_open(struct inode * inode, struct file * filp);
+extern void blkdev_release (struct inode * inode);
 extern struct file_operations def_blk_fops;
 extern struct inode_operations blkdev_inode_operations;
 
index e107ae1d28ea35fa5046be75f815eff219edb6e8..59ed69c08117ca7ffdd14a54a8ff17463c1364e1 100644 (file)
@@ -11,7 +11,8 @@
  *             Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source.
  *             Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *             Florian La Roche.
+ *             Florian La Roche,
+ *             Jonathan Layes <layes@loran.com>
  *
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
@@ -31,6 +32,8 @@
 #define        ARPHRD_IEEE802  6               /* IEEE 802.2 Ethernet/TR/TB    */
 #define        ARPHRD_ARCNET   7               /* ARCnet                       */
 #define        ARPHRD_APPLETLK 8               /* APPLEtalk                    */
+#define ARPHRD_DLCI    15              /* Frame Relay DLCI             */
+
 /* Dummy types for non ARP hardware */
 #define ARPHRD_SLIP    256
 #define ARPHRD_CSLIP   257
 #define ARPHRD_RSRVD   260             /* Notional KISS type           */
 #define ARPHRD_ADAPT   264
 #define ARPHRD_PPP     512
+
 #define ARPHRD_TUNNEL  768             /* IPIP tunnel                  */
 #define ARPHRD_TUNNEL6 769             /* IPIP6 tunnel                 */
-#define ARPHRD_FRAD    770             /* Frame Relay                  */
+#define ARPHRD_FRAD    770             /* Frame Relay Access Device    */
 #define ARPHRD_SKIP    771             /* SKIP vif                     */
 #define ARPHRD_LOOPBACK        772             /* Loopback device              */
 #define ARPHRD_LOCALTLK 773            /* Localtalk device             */
@@ -101,4 +105,22 @@ struct arphdr
 
 };
 
+/* Support for the user space arp daemon, arpd */
+
+#define ARPD_UPDATE    0x01
+#define ARPD_LOOKUP    0x02
+
+struct arpd_request
+{
+       unsigned short  req;                    /* request type */
+       __u32           ip;                     /* ip address of entry */
+       __u32           mask;                   /* netmask - used for proxy */
+       unsigned char   ha[MAX_ADDR_LEN];       /* Hardware address */
+       unsigned long   last_used;              /* For expiry */
+       unsigned long   last_updated;           /* For expiry */
+       unsigned int    flags;                  /* Control status */
+       struct device   *dev;                   /* Device entry is tied to */
+       int             loc;                    /* Debugging call location */
+};
+
 #endif /* _LINUX_IF_ARP_H */
index 3b9f60e43939b6ec447f40ad3c63a55d915d0ae7..5673f6e30b23d810564a009d1eb82869c45f7781 100644 (file)
  *             as published by the Free Software Foundation; either version
  *             2 of the License, or (at your option) any later version.
  */
 #ifndef _LINUX_IF_ETHER_H
 #define _LINUX_IF_ETHER_H
 
-/* IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
-   and FCS/CRC (frame check sequence). */
+/*
+ *     IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble
+ *     and FCS/CRC (frame check sequence). 
+ */
+
 #define ETH_ALEN       6               /* Octets in one ethernet addr   */
 #define ETH_HLEN       14              /* Total octets in header.       */
 #define ETH_ZLEN       60              /* Min. octets in frame sans FCS */
 #define ETH_DATA_LEN   1500            /* Max. octets in payload        */
 #define ETH_FRAME_LEN  1514            /* Max. octets in frame sans FCS */
 
+/*
+ *     These are the defined Ethernet Protocol ID's.
+ */
 
-/* These are the defined Ethernet Protocol ID's. */
 #define ETH_P_LOOP     0x0060          /* Ethernet Loopback packet     */
 #define ETH_P_ECHO     0x0200          /* Ethernet Echo packet         */
 #define ETH_P_PUP      0x0400          /* Xerox PUP packet             */
 #define ETH_P_WAN_PPP   0x0007          /* Dummy type for WAN PPP frames*/
 #define ETH_P_PPP_MP    0x0008          /* Dummy type for PPP MP frames */
 #define ETH_P_LOCALTALK 0x0009         /* Localtalk pseudeo type       */
+#define ETH_P_PPPTALK  0x0010          /* Dummy type for Atalk over PPP*/
 
-/* This is an Ethernet frame header. */
-struct ethhdr {
-  unsigned char                h_dest[ETH_ALEN];       /* destination eth addr */
-  unsigned char                h_source[ETH_ALEN];     /* source ether addr    */
-  unsigned short       h_proto;                /* packet type ID field */
+/*
+ *     This is an Ethernet frame header.
+ */
+struct ethhdr 
+{
+       unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
+       unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
+       unsigned short  h_proto;                /* packet type ID field */
 };
 
-/* Ethernet statistics collection data. */
-struct enet_statistics{
-  int  rx_packets;                     /* total packets received       */
-  int  tx_packets;                     /* total packets transmitted    */
-  int  rx_errors;                      /* bad packets received         */
-  int  tx_errors;                      /* packet transmit problems     */
-  int  rx_dropped;                     /* no space in linux buffers    */
-  int  tx_dropped;                     /* no space available in linux  */
-  int  multicast;                      /* multicast packets received   */
-  int  collisions;
+/*
+ *     Ethernet statistics collection data. 
+ */
+struct enet_statistics
+{
+       int     rx_packets;             /* total packets received       */
+       int     tx_packets;             /* total packets transmitted    */
+       int     rx_errors;              /* bad packets received         */
+       int     tx_errors;              /* packet transmit problems     */
+       int     rx_dropped;             /* no space in linux buffers    */
+       int     tx_dropped;             /* no space available in linux  */
+       int     multicast;              /* multicast packets received   */
+       int     collisions;
 
-  /* detailed rx_errors: */
-  int  rx_length_errors;
-  int  rx_over_errors;                 /* receiver ring buff overflow  */
-  int  rx_crc_errors;                  /* recved pkt with crc error    */
-  int  rx_frame_errors;                /* recv'd frame alignment error */
-  int  rx_fifo_errors;                 /* recv'r fifo overrun          */
-  int  rx_missed_errors;               /* receiver missed packet       */
+       /* detailed rx_errors: */
+       int     rx_length_errors;
+       int     rx_over_errors;         /* receiver ring buff overflow  */
+       int     rx_crc_errors;          /* recved pkt with crc error    */
+       int     rx_frame_errors;        /* recv'd frame alignment error */
+       int     rx_fifo_errors;         /* recv'r fifo overrun          */
+       int     rx_missed_errors;       /* receiver missed packet       */
 
-  /* detailed tx_errors */
-  int  tx_aborted_errors;
-  int  tx_carrier_errors;
-  int  tx_fifo_errors;
-  int  tx_heartbeat_errors;
-  int  tx_window_errors;
+       /* detailed tx_errors */
+       int     tx_aborted_errors;
+       int     tx_carrier_errors;
+       int     tx_fifo_errors;
+       int     tx_heartbeat_errors;
+       int     tx_window_errors;
 };
 
+
 #endif /* _LINUX_IF_ETHER_H */
diff --git a/include/linux/if_frad.h b/include/linux/if_frad.h
new file mode 100644 (file)
index 0000000..25e9abe
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * DLCI/FRAD   Definitions for Frame Relay Access Devices.  DLCI devices are
+ *             created for each DLCI associated with a FRAD.  The FRAD driver
+ *             is not truely a network device, but the lower level device
+ *             handler.  This allows other FRAD manufacturers to use the DLCI
+ *             code, including it's RFC1490 encapsulation along side the current
+ *             implementation for the Sangoma cards.
+ *
+ * Version:    @(#)if_ifrad.h  0.10    23 Mar 96
+ *
+ * Author:     Mike McLagan <mike.mclagan@linux.org>
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _FRAD_H_
+#define _FRAD_H_
+
+/* Stuctures and constants associated with the DLCI device driver */
+
+#define DLCI_DEVADD    (SIOCDEVPRIVATE)
+#define DLCI_DEVDEL    (SIOCDEVPRIVATE + 1)
+
+struct dlci_add
+{
+   char  devname[IFNAMSIZ];
+   short dlci;
+};
+
+#define DLCI_GET_CONF  (SIOCDEVPRIVATE + 2)
+#define DLCI_SET_CONF  (SIOCDEVPRIVATE + 3)
+
+/* These are related to the Sangoma FRAD */
+struct dlci_conf {
+   short flags;
+   short CIR_fwd;
+   short Bc_fwd;
+   short Be_fwd;
+   short CIR_bwd;
+   short Bc_bwd;
+   short Be_bwd; 
+
+/* these are part of the status read */
+   short Tc_fwd;
+   short Tc_bwd;
+   short Tf_max;
+   short Tb_max;
+};
+
+#define DLCI_GET_SLAVE (SIOCDEVPRIVATE + 4)
+
+/* configuration flags for DLCI */
+#define DLCI_IGNORE_CIR_OUT    0x0001
+#define DLCI_ACCOUNT_CIR_IN    0x0002
+#define DLCI_BUFFER_IF         0x0008
+
+#define DLCI_VALID_FLAGS       0x000B
+
+
+/* defines for the actual Frame Relay hardware */
+#define FRAD_GET_CONF  (SIOCDEVPRIVATE)
+#define FRAD_SET_CONF  (SIOCDEVPRIVATE + 1)
+
+#define FRAD_LAST_IOCTL        FRAD_SET_CONF
+
+struct frad_conf 
+{
+   short station;
+   short flags;
+   short kbaud;
+   short clocking;
+   short mtu;
+   short T391;
+   short T392;
+   short N391;
+   short N392;
+   short N393;
+   short CIR_fwd;
+   short Bc_fwd;
+   short Be_fwd;
+   short CIR_bwd;
+   short Bc_bwd;
+   short Be_bwd;
+
+/* Add new fields here, above is a mirror of the sangoma_conf */
+
+};
+
+#define FRAD_STATION_CPE       0x0000
+#define FRAD_STATION_NODE      0x0001
+
+#define FRAD_TX_IGNORE_CIR     0x0001
+#define FRAD_RX_ACCOUNT_CIR    0x0002
+#define FRAD_DROP_ABORTED      0x0004
+#define FRAD_BUFFERIF          0x0008
+#define FRAD_STATS             0x0010
+#define FRAD_MCI               0x0100
+#define FRAD_AUTODLCI          0x8000
+#define FRAD_VALID_FLAGS       0x811F
+
+#define FRAD_CLOCK_INT         0x0001
+#define FRAD_CLOCK_EXT         0x0000
+
+#ifdef __KERNEL__
+
+struct fradhdr
+{
+   /* these are the fields of an RFC 1490 header               */
+   unsigned char  control;
+   unsigned char  pad;         /* for IP packets, this can be the NLPID */
+   unsigned char  NLPID;
+   unsigned char  OUI[3];
+   unsigned short PID;
+};
+
+/* see RFC 1490 for the definition of the following */
+#define FRAD_I_UI              0x03
+
+#define FRAD_P_PADDING         0x00
+#define FRAD_P_Q933            0x08
+#define FRAD_P_SNAP            0x80
+#define FRAD_P_CLNP            0x81
+#define FRAD_P_IP              0xCC
+
+struct dlci_local
+{
+   struct enet_statistics stats;
+   struct device          *slave;
+   struct dlci_conf       config;
+   int                    configured;
+
+   /* callback function */
+   void              (*receive)(struct sk_buff *skb, struct device *);
+};
+
+struct frad_local
+{
+   struct enet_statistics stats;
+   struct timer_list timer;
+
+   /* devices which this FRAD is slaved to */
+   struct device     *master[CONFIG_DLCI_MAX];
+   short             dlci[CONFIG_DLCI_MAX];
+
+   /* callback functions */
+   int               (*activate)(struct device *, struct device *);
+   int               (*deactivate)(struct device *, struct device *);
+   int               (*assoc)(struct device *, struct device *);
+   int               (*deassoc)(struct device *, struct device *);
+   int               (*dlci_conf)(struct device *, struct device *, int get);
+
+   int               initialized;      /* mem_start, port, irq set ? */
+   int               configured;       /* has this device been configured */
+   int               type;             /* adapter type */
+   int               state;            /* state of the S502/8 control latch */
+   int               buffer;           /* current buffer for S508 firmware */
+   struct frad_conf  config;
+};
+
+int register_frad(const char *name);
+int unregister_frad(const char *name);
+
+#endif __KERNEL__
+
+#endif
index 61629332b90fe457496b79157fd47ab4a02aa776..545f1b7f07a88f758ebbb175c09987c99d37ec0f 100644 (file)
 
 /* This is an Token-Ring frame header. */
 struct trh_hdr {
-       unsigned char   ac;     /* access control field */
-       unsigned char   fc;     /* frame control field */
-       unsigned char   daddr[TR_ALEN]; /* destination address */
-       unsigned char   saddr[TR_ALEN]; /* source address */
-       unsigned short  rcf;    /* route control field */
-       unsigned short  rseg[8];/* routing registers */
+       __u8  ac;                       /* access control field */
+       __u8  fc;                       /* frame control field */
+       __u8  daddr[TR_ALEN];           /* destination address */
+       __u8  saddr[TR_ALEN];           /* source address */
+       __u16 rcf;                      /* route control field */
+       __u16 rseg[8];                  /* routing registers */
 };
 
 /* This is an Token-Ring LLC structure */
 struct trllc {
-       unsigned char   dsap;   /* destination SAP */
-       unsigned char   ssap;   /* source SAP */
-       unsigned char   llc;    /* LLC control field */
-       unsigned char   protid[3];      /* protocol id */
-       unsigned short  ethertype;      /* ether type field */
+       __u8  dsap;                     /* destination SAP */
+       __u8  ssap;                     /* source SAP */
+       __u8  llc;                      /* LLC control field */
+       __u8  protid[3];                /* protocol id */
+       __u16 ethertype;                /* ether type field */
 };
 
-
 /* Token-Ring statistics collection data. */
-struct tr_statistics{
-  int  rx_packets;                     /* total packets received       */
-  int  tx_packets;                     /* total packets transmitted    */
-  int  rx_errors;                      /* bad packets received         */
-  int  tx_errors;                      /* packet transmit problems     */
-  int  rx_dropped;                     /* no space in linux buffers    */
-  int  tx_dropped;                     /* no space available in linux  */
-  int  multicast;                      /* multicast packets received   */
-  int   transmit_collision;
+struct tr_statistics {
+       int rx_packets;                 /* total packets received       */
+       int tx_packets;                 /* total packets transmitted    */
+       int rx_errors;                  /* bad packets received         */
+       int tx_errors;                  /* packet transmit problems     */
+       int rx_dropped;                 /* no space in linux buffers    */
+       int tx_dropped;                 /* no space available in linux  */
+       int multicast;                  /* multicast packets received   */
+       int transmit_collision;
 
-       /* detailed Token-Ring errors. See IBM Token-Ring Network Architecture
-      for more info */
+       /* detailed Token-Ring errors. See IBM Token-Ring Network
+          Architecture for more info */
 
        int line_errors;
        int internal_errors;
@@ -88,7 +87,6 @@ struct tr_statistics{
        int frequency_errors;
        int token_errors;
        int dummy1;
-       
 };
 
 /* source routing stuff */
index d10deaa975ed2659dd03d2cbe6737f4530679812..68c9b34582eebab58f4191efaa1240615f469ecf 100644 (file)
@@ -10,8 +10,8 @@
 #define GIO_FONTX      0x4B6B  /* get font using struct consolefontdesc */
 #define PIO_FONTX      0x4B6C  /* set font using struct consolefontdesc */
 struct consolefontdesc {
-       u_short charcount;      /* characters in font (256 or 512) */
-       u_short charheight;     /* scan lines per character (1-32) */
+       unsigned short charcount;       /* characters in font (256 or 512) */
+       unsigned short charheight;      /* scan lines per character (1-32) */
        char *chardata;         /* font data in expanded form */
 };
 
@@ -58,19 +58,19 @@ typedef char scrnmap_t;
 
 #define GIO_UNIMAP     0x4B66  /* get unicode-to-font mapping from kernel */
 struct unipair {
-       u_short unicode;
-       u_short fontpos;
+       unsigned short unicode;
+       unsigned short fontpos;
 };
 struct unimapdesc {
-       u_short entry_ct;
+       unsigned short entry_ct;
        struct unipair *entries;
 };
 #define PIO_UNIMAP     0x4B67  /* put unicode-to-font mapping in kernel */
 #define PIO_UNIMAPCLR  0x4B68  /* clear table, possibly advise hash algorithm */
 struct unimapinit {
-       u_short advised_hashsize;  /* 0 if no opinion */
-       u_short advised_hashstep;  /* 0 if no opinion */
-       u_short advised_hashlevel; /* 0 if no opinion */
+       unsigned short advised_hashsize;  /* 0 if no opinion */
+       unsigned short advised_hashstep;  /* 0 if no opinion */
+       unsigned short advised_hashlevel; /* 0 if no opinion */
 };
 
 #define UNI_DIRECT_BASE 0xF000 /* start of Direct Font Region */
@@ -95,9 +95,9 @@ struct unimapinit {
 #define KDSKBLED       0x4B65  /* set led flags (not lights) */
 
 struct kbentry {
-       u_char kb_table;
-       u_char kb_index;
-       u_short kb_value;
+       unsigned char kb_table;
+       unsigned char kb_index;
+       unsigned short kb_value;
 };
 #define                K_NORMTAB       0x00
 #define                K_SHIFTTAB      0x01
@@ -108,14 +108,14 @@ struct kbentry {
 #define KDSKBENT       0x4B47  /* sets one entry in translation table */
 
 struct kbsentry {
-       u_char kb_func;
-       u_char kb_string[512];
+       unsigned char kb_func;
+       unsigned char kb_string[512];
 };
 #define KDGKBSENT      0x4B48  /* gets one function key string entry */
 #define KDSKBSENT      0x4B49  /* sets one function key string entry */
 
 struct kbdiacr {
-        u_char diacr, base, result;
+        unsigned char diacr, base, result;
 };
 struct kbdiacrs {
         unsigned int kb_cnt;    /* number of entries in following array */
index c6769c1ffb78934bb9bafed1905d1fda34c3b1c2..49719cc76f6631a0e578d746f54bfb63ec4e2964 100644 (file)
@@ -8,6 +8,7 @@
 #define KERNELD_CANCEL_RELEASE_MODULE 5 /* "rmmod" */
 #define KERNELD_REQUEST_ROUTE 6 /* from net/ipv4/route.c */
 #define KERNELD_BLANKER 7 /* from drivers/char/console.c */
+#define KERNELD_ARP 256 /* from net/ipv4/arp.c */
 
 #define IPC_KERNELD 00040000   /* use the kerneld message channel */
 #define KERNELD_MAXCMD 0x7ffeffff
index 3724bb0e980076784b215efe0929b4c0c9473b90..1e75b4cab72430da8a3e9600872cee68f1cc9ae4 100644 (file)
@@ -12,6 +12,8 @@
 
 #define LO_NAME_SIZE   64
 #define LO_KEY_SIZE    32
+
+#ifdef __KERNEL__
        
 struct loop_device {
        int             lo_number;
@@ -39,6 +41,9 @@ typedef       int (* transfer_proc_t)(struct loop_device *, int cmd,
  * Loop flags
  */
 #define LO_FLAGS_DO_BMAP       0x00000001
+#define LO_FLAGS_READ_ONLY     0x00000002
+
+#endif /* __KERNEL__ */
 
 struct loop_info {
        int             lo_number;      /* ioctl r/o */
index 8cc90a1aa1f8661a2a51b8a68c4b160da5c705dc..53c683c04d4e5e17706479aae498e1c6949818d6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Definitions for the Mitsumi CDROM interface
  * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.8
+ * VERSION: 1.9
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 4db2ca25dee8bb346a616882528d2fc90af7beb5..1cdbc6902a9f9931e4f6c8493d16a3b4fb991258 100644 (file)
@@ -34,18 +34,16 @@ struct ncp_fs_info {
        int    buffer_size;     /* The negotiated buffer size, to be
                                   used for read/write requests! */
 
-       /* Not used yet, but here some day the namespace numbers will be
-          stored. */
        int    volume_number;
        __u32  directory_id;
 };     
 
-#define        NCP_IOC_NCPREQUEST              _IOR('n', 1, unsigned char *)
-#define        NCP_IOC_GETMOUNTUID             _IOR('u', 1, uid_t)
-#define NCP_IOC_CONN_LOGGED_IN          _IO('l', 1)
+#define        NCP_IOC_NCPREQUEST              _IOR('n', 1, struct ncp_ioctl_request)
+#define        NCP_IOC_GETMOUNTUID             _IOW('n', 2, uid_t)
+#define NCP_IOC_CONN_LOGGED_IN          _IO('n', 3)
 
 #define NCP_GET_FS_INFO_VERSION (1)
-#define NCP_IOC_GET_FS_INFO             _IOWR('i', 1, unsigned char *)
+#define NCP_IOC_GET_FS_INFO             _IOWR('n', 4, struct ncp_fs_info)
 
 /*
  * The packet size to allocate. One page should be enough.
index 1fbe98a0f04b4ca766567c1437a3c551dcd9657e..68e9158680a0263d93c59174875ee02e582be608 100644 (file)
@@ -83,6 +83,7 @@ struct socket {
   struct wait_queue    **wait;         /* ptr to place to wait on      */
   struct inode         *inode;
   struct fasync_struct  *fasync_list;  /* Asynchronous wake up list    */
+  struct file          *file;          /* File back pointer for gc     */
 };
 
 #define SOCK_INODE(S)  ((S)->inode)
index 8685ff0eda87a1c326ee0940fc68a61f52f32a36..c93eb5465dcabed96d611706530124abc68652fd 100644 (file)
@@ -187,6 +187,8 @@ struct device
 #define HAVE_HEADER_CACHE
   void                   (*header_cache_bind)(struct hh_cache **hhp, struct device *dev, unsigned short htype, __u32 daddr);
   void                   (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char *  haddr);
+#define HAVE_CHANGE_MTU
+  int                    (*change_mtu)(struct device *dev, int new_mtu);            
 };
 
 
index 448734bfc4c61b88ac6eacf0b12259540ea91279..79f03ce804b50c3a4f0f10061a1e267fad92dde7 100644 (file)
@@ -43,7 +43,7 @@
 #define STOP_TIMEOUT           1000            /* for poll wait */
 #define RESET_WAIT             1000            /* busy wait at drive reset */
 
-/* # of buffer for block size conversion. 6 is optimal for my setup (P75),
+/* # of buffers for block size conversion. 6 is optimal for my setup (P75),
    giving 280 kb/s, with 0.4% CPU usage. Experiment to find your optimal
    setting */
 #define N_BUFS         6
index 6994f359d0d2e45c49465ec64604339f82fac335..d9298113ed5c986cab9c23e81be827a408cc5746 100644 (file)
  *       PCI-CPU bridge or PCI-ISA bridge.
  *     - If you can't find the actual information in your hardware
  *       booklet, try to read the references of the chip on the board.
- *     - Send all that, with the word PCIPROBE in the subject,
- *       to frederic@cao-vlsi.ibp.fr, and I'll add your device to 
- *       the list as soon as possible
- *             fred.
+ *     - Send all that to linux-pcisupport@cao-vlsi.ibp.fr,
+ *       and I'll add your device to the list as soon as possible
+ *
+ * BEFORE you send a mail, please check the latest linux releases
+ * to be sure it has not been recently added.
+ *
+ *        Thanks
+ *             Frederic Potter.
  */
 
 
 #define PCI_DEVICE_ID_CIRRUS_5434_4    0x00a4
 #define PCI_DEVICE_ID_CIRRUS_5434_8    0x00a8
 #define PCI_DEVICE_ID_CIRRUS_5436      0x00ac
-#define PCI_DEVICE_ID_CIRRUS_6205      0x0205
 #define PCI_DEVICE_ID_CIRRUS_6729      0x1100
 #define PCI_DEVICE_ID_CIRRUS_7542      0x1200
 #define PCI_DEVICE_ID_CIRRUS_7543      0x1202
 #define PCI_DEVICE_ID_CT_65548         0x00dc
 
 #define PCI_VENDOR_ID_MIRO             0x1031
+#define PCI_DEVICE_ID_MIRO_36050       0x5601
 
 #define PCI_VENDOR_ID_FD               0x1036
 #define PCI_DEVICE_ID_FD_36C70         0x0000
 #define PCI_VENDOR_ID_SI               0x1039
 #define PCI_DEVICE_ID_SI_6201          0x0001
 #define PCI_DEVICE_ID_SI_6202          0x0002
+#define PCI_DEVICE_ID_SI_6205          0x0205
 #define PCI_DEVICE_ID_SI_503           0x0008
 #define PCI_DEVICE_ID_SI_501           0x0406
 #define PCI_DEVICE_ID_SI_496           0x0496
 #define PCI_DEVICE_ID_VIA_82C416       0x1571
 
 #define PCI_VENDOR_ID_VORTEX           0x1119
-#define PCI_DEVICE_ID_VORTEX_GDT       0x0001
+#define PCI_DEVICE_ID_VORTEX_GDT60x0   0x0000
+#define PCI_DEVICE_ID_VORTEX_GDT6000B  0x0001
+#define PCI_DEVICE_ID_VORTEX_GDT6x10   0x0002
+#define PCI_DEVICE_ID_VORTEX_GDT6x20   0x0003
+#define PCI_DEVICE_ID_VORTEX_GDT6530   0x0004
+#define PCI_DEVICE_ID_VORTEX_GDT6550   0x0005
+#define PCI_DEVICE_ID_VORTEX_GDT6x17   0x0006
+#define PCI_DEVICE_ID_VORTEX_GDT6x27   0x0007
+#define PCI_DEVICE_ID_VORTEX_GDT6537   0x0008
+#define PCI_DEVICE_ID_VORTEX_GDT6557   0x0009
+#define PCI_DEVICE_ID_VORTEX_GDT6x15   0x000a
+#define PCI_DEVICE_ID_VORTEX_GDT6x25   0x000b
+#define PCI_DEVICE_ID_VORTEX_GDT6535   0x000c
+#define PCI_DEVICE_ID_VORTEX_GDT6555   0x000d
 
 #define PCI_VENDOR_ID_EF               0x111a
 #define PCI_DEVICE_ID_EF_ATM_FPGA      0x0000
 
 #define PCI_VENDOR_ID_FORE             0x1127
 #define PCI_DEVICE_ID_FORE_PCA200PC    0x0210
+#define PCI_DEVICE_ID_FORE_PCA200E     0x0300
 
 #define PCI_VENDOR_ID_IMAGINGTECH      0x112f
 #define PCI_DEVICE_ID_IMAGINGTECH_ICPCI        0x0000
diff --git a/include/linux/posix_types.h b/include/linux/posix_types.h
new file mode 100644 (file)
index 0000000..87c17c7
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef _LINUX_POSIX_TYPES_H
+#define _LINUX_POSIX_TYPES_H
+
+#define _GNU_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+#ifndef NULL
+# define NULL          ((void *) 0)
+#endif
+
+/*
+ * This allows for 256 file descriptors: if NR_OPEN is ever grown
+ * beyond that you'll have to change this too. But 256 fd's seem to be
+ * enough even for such "real" unices like SunOS, so hopefully this is
+ * one limit that doesn't have to be changed.
+ *
+ * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in
+ * <sys/time.h> (and thus <linux/time.h>) - but this is a more logical
+ * place for them. Solved by having dummy defines in <sys/time.h>.
+ */
+
+/*
+ * Those macros may have been defined in <gnu/types.h>. But we always
+ * use the ones here. 
+ */
+#undef __NFDBITS
+#define __NFDBITS      (8 * sizeof(unsigned int))
+
+#undef __FD_SETSIZE
+#define __FD_SETSIZE   256
+
+#undef __FDSET_INTS
+#define __FDSET_INTS   (__FD_SETSIZE/__NFDBITS)
+
+#undef __FDELT
+#define        __FDELT(d)      ((d) / __NFDBITS)
+
+#undef __FDMASK
+#define        __FDMASK(d)     (1 << ((d) % __NFDBITS))
+
+typedef struct fd_set {
+       unsigned int fds_bits [__FDSET_INTS];
+} __fd_set;
+
+#include <asm/posix_types.h>
+
+/* bsd */
+
+typedef unsigned char  __u_char;
+typedef unsigned short __u_short;
+typedef unsigned int   __u_int;
+typedef unsigned long  __u_long;
+
+#endif /* _LINUX_POSIX_TYPES_H */
index 86cfa94604ac2cf27bee63e039eeaf07f7c48059..cb51539ff9f3e5b7f0ba7b5b3faece4bef6e9efd 100644 (file)
@@ -260,7 +260,7 @@ struct task_struct {
 #define PF_PTRACED     0x00000010      /* set if ptrace (0) has been called. */
 #define PF_TRACESYS    0x00000020      /* tracing system calls */
 #define PF_FORKNOEXEC  0x00000040      /* forked but didn't exec */
-#define PF_SUPERPREV   0x00000100      /* used super-user privileges */
+#define PF_SUPERPRIV   0x00000100      /* used super-user privileges */
 #define PF_DUMPCORE    0x00000200      /* dumped core */
 #define PF_SIGNALED    0x00000400      /* killed by a signal */
 
@@ -362,7 +362,7 @@ extern void free_irq(unsigned int irq, void *dev_id);
 extern inline int suser(void)
 {
        if (current->euid == 0)
-               current->flags |= PF_SUPERPREV;
+               current->flags |= PF_SUPERPRIV;
        return (current->euid == 0);
 }
 
diff --git a/include/linux/sdla.h b/include/linux/sdla.h
new file mode 100644 (file)
index 0000000..26fcd8c
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * INET                An implementation of the TCP/IP protocol suite for the LINUX
+ *             operating system.  INET is implemented using the  BSD Socket
+ *             interface as the means of communication with the user level.
+ *
+ *             Global definitions for the Frame relay interface.
+ *
+ * Version:    @(#)if_ifrad.h  0.10    23 Mar 96
+ *
+ * Author:     Mike McLagan <mike.mclagan@linux.org>
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+
+#ifndef SDLA_H
+#define SDLA_H
+
+/* adapter type */
+#define SDLA_TYPES
+#define SDLA_S502A                     5020
+#define SDLA_S502E                     5021
+#define SDLA_S503                      5030
+#define SDLA_S507                      5070
+#define SDLA_S508                      5080
+#define SDLA_S509                      5090
+#define SDLA_UNKNOWN                   -1
+
+/* port selection flags for the S508 */
+#define SDLA_S508_PORT_V35             0x00
+#define SDLA_S508_PORT_RS232           0x02
+
+/* Z80 CPU speeds */
+#define SDLA_CPU_3M                    0x00
+#define SDLA_CPU_5M                    0x01
+#define SDLA_CPU_7M                    0x02
+#define SDLA_CPU_8M                    0x03
+#define SDLA_CPU_10M                   0x04
+#define SDLA_CPU_16M                   0x05
+#define SDLA_CPU_12M                   0x06
+
+/* some private IOCTLs */
+#define SDLA_IDENTIFY                  (FRAD_LAST_IOCTL + 1)
+#define SDLA_CPUSPEED                  (FRAD_LAST_IOCTL + 2)
+#define SDLA_PROTOCOL                  (FRAD_LAST_IOCTL + 3)
+
+#define SDLA_CLEARMEM                  (FRAD_LAST_IOCTL + 4)
+#define SDLA_WRITEMEM                  (FRAD_LAST_IOCTL + 5)
+#define SDLA_READMEM                   (FRAD_LAST_IOCTL + 6)
+
+struct sdla_mem {
+   int  addr;
+   int  len;
+   void *data;
+};
+
+#define SDLA_START                     (FRAD_LAST_IOCTL + 7)
+#define SDLA_STOP                      (FRAD_LAST_IOCTL + 8)
+
+/* some offsets in the Z80's memory space */
+#define SDLA_NMIADDR                   0x0000
+#define SDLA_CONF_ADDR                 0x0010
+#define SDLA_S502A_NMIADDR             0x0066
+#define SDLA_CODE_BASEADDR             0x0100
+
+/* largest handlable block of data */
+#define SDLA_MAX_DATA                  4080
+#define SDLA_MAX_MTU                   4072    /* MAX_DATA - sizeof(fradhdr) */
+#define SDLA_MAX_DLCI                  24
+
+struct sdla_conf {
+   short station;
+   short config;
+   short kbaud;
+   short clocking;
+   short max_frm;
+   short T391;
+   short T392;
+   short N391;
+   short N392;
+   short N393;
+   short CIR_fwd;
+   short Bc_fwd;
+   short Be_fwd;
+   short CIR_bwd;
+   short Bc_bwd;
+   short Be_bwd;
+};
+
+struct sdla_dlci {
+   short config;
+   short CIR_fwd;
+   short Bc_fwd;
+   short Be_fwd;
+   short CIR_bwd;
+   short Bc_bwd;
+   short Be_bwd; 
+
+/* these are part of the status READ */
+   short Tc_fwd;
+   short Tc_bwd;
+   short Tf_max;
+   short Tb_max;
+};
+
+#ifndef __KERNEL__
+
+void sdla(void *cfg_info, char *dev, struct frad_conf *conf, int quiet);
+
+#else
+
+/* important Z80 window addresses */
+#define SDLA_CONTROL_WND               0xE000
+
+#define SDLA_502_CMD_BUF               0xEF60
+#define SDLA_502_RCV_BUF               0xA900
+#define        SDLA_502_TXN_AVAIL              0xFFF1
+#define SDLA_502_RCV_AVAIL             0xFFF2
+#define SDLA_502_EVENT_FLAGS           0xFFF3
+#define SDLA_502_MDM_STATUS            0xFFF4
+#define SDLA_502_IRQ_INTERFACE         0xFFFD
+#define SDLA_502_IRQ_PERMISSION                0xFFFE
+#define SDLA_502_DATA_OFS              0x0010
+
+#define SDLA_508_CMD_BUF               0xE000
+#define SDLA_508_TXBUF_INFO            0xF100
+#define SDLA_508_RXBUF_INFO            0xF120
+#define SDLA_508_EVENT_FLAGS           0xF003
+#define SDLA_508_MDM_STATUS            0xF004
+#define SDLA_508_IRQ_INTERFACE         0xF010
+#define SDLA_508_IRQ_PERMISSION                0xF011
+#define SDLA_508_TSE_OFFSET            0xF012
+
+/* Event flags */
+#define SDLA_EVENT_STATUS              0x01
+#define SDLA_EVENT_DLCI_STATUS         0x02
+#define SDLA_EVENT_BAD_DLCI            0x04
+#define SDLA_EVENT_LINK_DOWN           0x40
+
+/* IRQ Trigger flags */
+#define SDLA_INTR_RX                   0x01
+#define SDLA_INTR_TX                   0x02
+#define SDLA_INTR_MODEM                        0x04
+#define SDLA_INTR_COMPLETE             0x08
+#define SDLA_INTR_STATUS               0x10
+#define SDLA_INTR_TIMER                        0x20
+
+/* DLCI status bits */
+#define SDLA_DLCI_DELETED              0x01
+#define SDLA_DLCI_ACTIVE               0x02
+#define SDLA_DLCI_WAITING              0x04
+#define SDLA_DLCI_NEW                  0x08
+#define SDLA_DLCI_INCLUDED             0x40
+
+/* valid command codes */
+#define        SDLA_INFORMATION_WRITE          0x01
+#define        SDLA_INFORMATION_READ           0x02
+#define SDLA_ISSUE_IN_CHANNEL_SIGNAL   0x03
+#define        SDLA_SET_DLCI_CONFIGURATION     0x10
+#define        SDLA_READ_DLCI_CONFIGURATION    0x11
+#define        SDLA_DISABLE_COMMUNICATIONS     0x12
+#define        SDLA_ENABLE_COMMUNICATIONS      0x13
+#define        SDLA_READ_DLC_STATUS            0x14
+#define        SDLA_READ_DLC_STATISTICS        0x15
+#define        SDLA_FLUSH_DLC_STATISTICS       0x16
+#define        SDLA_LIST_ACTIVE_DLCI           0x17
+#define        SDLA_FLUSH_INFORMATION_BUFFERS  0x18
+#define        SDLA_ADD_DLCI                   0x20
+#define        SDLA_DELETE_DLCI                0x21
+#define        SDLA_ACTIVATE_DLCI              0x22
+#define        SDLA_DEACTIVATE_DLCI            0x23
+#define        SDLA_READ_MODEM_STATUS          0x30
+#define        SDLA_SET_MODEM_STATUS           0x31
+#define        SDLA_READ_COMMS_ERR_STATS       0x32
+#define SDLA_FLUSH_COMMS_ERR_STATS     0x33
+#define        SDLA_READ_CODE_VERSION          0x40
+#define SDLA_SET_IRQ_TRIGGER           0x50
+#define SDLA_GET_IRQ_TRIGGER           0x51
+
+/* In channel signal types */
+#define SDLA_ICS_LINK_VERIFY           0x02
+#define SDLA_ICS_STATUS_ENQ            0x03
+
+/* modem status flags */
+#define SDLA_MODEM_DTR_HIGH            0x01
+#define SDLA_MODEM_RTS_HIGH            0x02
+#define SDLA_MODEM_DCD_HIGH            0x08
+#define SDLA_MODEM_CTS_HIGH            0x20
+
+/* used for RET_MODEM interpretation */
+#define SDLA_MODEM_DCD_LOW             0x01
+#define SDLA_MODEM_CTS_LOW             0x02
+
+/* return codes */
+#define SDLA_RET_OK                    0x00
+#define SDLA_RET_COMMUNICATIONS                0x01
+#define SDLA_RET_CHANNEL_INACTIVE      0x02
+#define SDLA_RET_DLCI_INACTIVE         0x03
+#define SDLA_RET_DLCI_CONFIG           0x04
+#define SDLA_RET_BUF_TOO_BIG           0x05
+#define SDLA_RET_NO_DATA               0x05
+#define SDLA_RET_BUF_OVERSIZE          0x06
+#define SDLA_RET_CIR_OVERFLOW          0x07
+#define SDLA_RET_NO_BUFF               0x08
+#define SDLA_RET_TIMEOUT               0x0A
+#define SDLA_RET_MODEM                 0x10
+#define SDLA_RET_CHANNEL_OFF           0x11
+#define SDLA_RET_CHANNEL_ON            0x12
+#define SDLA_RET_DLCI_STATUS           0x13
+#define SDLA_RET_DLCI_UNKNOWN          0x14
+#define SDLA_RET_COMMAND_INVALID       0x1F
+
+/* Configuration flags */
+#define SDLA_DIRECT_RECV               0x0080
+
+/* IRQ selection flags */
+#define SDLA_IRQ_RECEIVE               0x01
+#define SDLA_IRQ_TRANSMIT              0x02
+#define SDLA_IRQ_MODEM_STAT            0x04
+#define SDLA_IRQ_COMMAND               0x08
+#define SDLA_IRQ_CHANNEL               0x10
+#define SDLA_IRQ_TIMER                 0x20
+
+/* definitions for PC memory mapping */
+#define SDLA_8K_WINDOW                 0x01
+#define SDLA_S502_SEG_A                        0x10
+#define SDLA_S502_SEG_C                        0x20
+#define SDLA_S502_SEG_D                        0x00
+#define SDLA_S502_SEG_E                        0x30
+#define SDLA_S507_SEG_A                        0x00
+#define SDLA_S507_SEG_B                        0x40
+#define SDLA_S507_SEG_C                        0x80
+#define SDLA_S507_SEG_E                        0xC0
+#define SDLA_S508_SEG_A                        0x00
+#define SDLA_S508_SEG_C                        0x10
+#define SDLA_S508_SEG_D                        0x08
+#define SDLA_S508_SEG_E                        0x18
+
+/* SDLA adapter port constants */
+#define SDLA_IO_EXTENTS                        0x04
+       
+#define SDLA_REG_CONTROL               0x00
+#define SDLA_REG_PC_WINDOW             0x01    /* offset for PC window select latch */
+#define SDLA_REG_Z80_WINDOW            0x02    /* offset for Z80 window select latch */
+#define SDLA_REG_Z80_CONTROL           0x03    /* offset for Z80 control latch */
+       
+#define SDLA_S502_STS                  0x00    /* status reg for 502, 502E, 507 */
+#define SDLA_S508_GNRL                 0x00    /* general purp. reg for 508 */
+#define SDLA_S508_STS                  0x01    /* status reg for 508 */
+#define SDLA_S508_IDR                  0x02    /* ID reg for 508 */
+       
+/* control register flags */
+#define SDLA_S502A_START               0x00    /* start the CPU */
+#define SDLA_S502A_INTREQ              0x02
+#define SDLA_S502A_INTEN               0x04
+#define SDLA_S502A_HALT                        0x08    /* halt the CPU */      
+#define SDLA_S502A_NMI                 0x10    /* issue an NMI to the CPU */
+
+#define SDLA_S502E_CPUEN               0x01
+#define SDLA_S502E_ENABLE              0x02
+#define SDLA_S502E_INTACK              0x04
+       
+#define SDLA_S507_ENABLE               0x01
+#define SDLA_S507_IRQ3                 0x00
+#define SDLA_S507_IRQ4                 0x20
+#define SDLA_S507_IRQ5                 0x40
+#define SDLA_S507_IRQ7                 0x60
+#define SDLA_S507_IRQ10                        0x80
+#define SDLA_S507_IRQ11                        0xA0
+#define SDLA_S507_IRQ12                        0xC0
+#define SDLA_S507_IRQ15                        0xE0
+       
+#define SDLA_HALT                      0x00
+#define SDLA_CPUEN                     0x02
+#define SDLA_MEMEN                     0x04
+#define SDLA_S507_EPROMWR              0x08
+#define SDLA_S507_EPROMCLK             0x10
+#define SDLA_S508_INTRQ                        0x08
+#define SDLA_S508_INTEN                        0x10
+
+struct sdla_cmd {
+   char  opp_flag              __attribute__((packed));
+   char  cmd                   __attribute__((packed));
+   short length                        __attribute__((packed));
+   char  retval                        __attribute__((packed));
+   short dlci                  __attribute__((packed));
+   char  flags                 __attribute__((packed));
+   short rxlost_int            __attribute__((packed));
+   long  rxlost_app            __attribute__((packed));
+   char  reserve[2]            __attribute__((packed));
+   char  data[SDLA_MAX_DATA]   __attribute__((packed));        /* transfer data buffer */
+};
+
+struct intr_info {
+   char  flags         __attribute__((packed));
+   short txlen         __attribute__((packed));
+   char  irq           __attribute__((packed));
+   char  flags2                __attribute__((packed));
+   short timeout       __attribute__((packed));
+};
+
+/* found in the 508's control window at RXBUF_INFO */
+struct buf_info {
+   unsigned short rse_num      __attribute__((packed));
+   unsigned long  rse_base     __attribute__((packed));
+   unsigned long  rse_next     __attribute__((packed));
+   unsigned long  buf_base     __attribute__((packed));
+   unsigned short reserved     __attribute__((packed));
+   unsigned long  buf_top      __attribute__((packed));
+};
+
+/* structure pointed to by rse_base in RXBUF_INFO struct */
+struct buf_entry {
+   char  opp_flag      __attribute__((packed));
+   short length                __attribute__((packed));
+   short dlci          __attribute__((packed));
+   char  flags         __attribute__((packed));
+   short timestamp     __attribute__((packed));
+   short reserved[2]   __attribute__((packed));
+   long  buf_addr      __attribute__((packed));
+};
+
+#endif
+
+#endif
index 5393660346492873e653f97d51d2b68299737871..72984f1541c65903e3d9e9670f2ef65da1f37a91 100644 (file)
@@ -14,7 +14,6 @@ extern void smp_boot_cpus(void);              /* Boot processor call to load the other CPU's
 extern void smp_callin(void);                  /* Processor call in. Must hold processors until .. */
 extern void smp_commence(void);                        /* Multiprocessors may now schedule */
 extern int smp_num_cpus;
-extern int smp_top_cpu;                                /* Top CPU number  */
 extern int smp_threads_ready;                  /* True once the per process idle is forked */
 #ifdef __SMP_PROF__
 extern volatile unsigned long smp_spins[NR_CPUS];      /* count of interrupt spins */
@@ -48,7 +47,6 @@ extern volatile int smp_msg_id;
  
 #define smp_num_cpus                   1
 #define smp_processor_id()             0
-#define smp_top_cpu                    0
 #define smp_message_pass(t,m,d,w)      
 #define smp_threads_ready              1
 #define kernel_lock()
index bbea1e1527b99fbbd82c8e4369bf3ab72686bcd8..31f96f821f310897f3676b38ff18dcb1e5b662ef 100644 (file)
@@ -96,6 +96,8 @@ struct msghdr
 #define SOL_TCP                6
 #define SOL_UDP                17
 
+#ifdef __KERNEL__
+
 /* IP options */
 #define IP_TOS         1
 #define        IPTOS_LOWDELAY          0x10
@@ -111,6 +113,7 @@ struct msghdr
 #define IP_ADD_MEMBERSHIP              35
 #define IP_DROP_MEMBERSHIP             36
 
+#endif /* __KERNEL__ */
 
 /* These need to appear somewhere around here */
 #define IP_DEFAULT_MULTICAST_TTL        1
index ee20a0b12ad4ca8760c4c3eb81fb8ae68bb49a2a..b03c12bc5ed7354799b23b34a387f4a09cf25669 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef _LINUX_SOCKIOS_H
 #define _LINUX_SOCKIOS_H
 
+#include <asm/sockios.h>
+
 /* Routing table calls. */
 #define SIOCADDRT      0x890B          /* add routing table entry      */
 #define SIOCDELRT      0x890C          /* delete routing table entry   */
index 6e1bc50a8aa9a95ee774b97d31a4205aceb8bcb1..9c0519feaa351f66c9d82e878a4d4017dd5a49b3 100644 (file)
@@ -5,6 +5,16 @@
  * 'tty.h' defines some structures used by tty_io.c and some defines.
  */
 
+/*
+ * These constants are also useful for user-level apps (e.g., VC
+ * resizing).
+ */
+#define MIN_NR_CONSOLES        1       /* must be at least 1 */
+#define MAX_NR_CONSOLES        63      /* serial lines start at 64 */
+#define MAX_NR_USER_CONSOLES 63        /* must be root to allocate above this */
+               /* Note: the ioctl VT_GETSTATE does not work for
+                  consoles 16 and higher (since it returns a short) */
+
 #ifdef __KERNEL__
 #include <linux/fs.h>
 #include <linux/termios.h>
  * (Note: the *_driver.minor_start values 1, 64, 128, 192 are
  * hardcoded at present.)
  */
-#define MIN_NR_CONSOLES        1       /* must be at least 1 */
-#define MAX_NR_CONSOLES        63      /* serial lines start at 64 */
-#define MAX_NR_USER_CONSOLES 63        /* must be root to allocate above this */
-               /* Note: the ioctl VT_GETSTATE does not work for
-                  consoles 16 and higher (since it returns a short) */
 #define NR_PTYS                256
 #define NR_LDISCS      16
 
index 43c04a5e02e75daa7ce8288e3dfc408a861dd15b..b4a73da50bc4ec2255af632746bb94f247bf6e15 100644 (file)
@@ -1,68 +1,92 @@
 #ifndef _LINUX_TYPES_H
 #define _LINUX_TYPES_H
 
-/*
- * This allows for 256 file descriptors: if NR_OPEN is ever grown beyond that
- * you'll have to change this too. But 256 fd's seem to be enough even for such
- * "real" unices like SunOS, so hopefully this is one limit that doesn't have
- * to be changed.
- *
- * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in <sys/time.h>
- * (and thus <linux/time.h>) - but this is a more logical place for them. Solved
- * by having dummy defines in <sys/time.h>.
- */
+#include <linux/posix_types.h>
+#include <asm/types.h>
 
-/*
- * Those macros may have been defined in <gnu/types.h>. But we always
- * use the ones here. 
- */
-#undef __NFDBITS
-#define __NFDBITS      (8 * sizeof(unsigned int))
+#ifndef _LINUX_TYPES_DONT_EXPORT
 
-#undef __FD_SETSIZE
-#define __FD_SETSIZE   256
+typedef __fd_set       fd_set;
+typedef __dev_t                dev_t;
+typedef __ino_t                ino_t;
+typedef __mode_t       mode_t;
+typedef __nlink_t      nlink_t;
+typedef __off_t                off_t;
+typedef __pid_t                pid_t;
+typedef __uid_t                uid_t;
+typedef __gid_t                gid_t;
+typedef __daddr_t      daddr_t;
 
-#undef __FDSET_INTS
-#define __FDSET_INTS   (__FD_SETSIZE/__NFDBITS)
+/* bsd */
 
-typedef struct fd_set {
-       unsigned int fds_bits [__FDSET_INTS];
-} fd_set;
+typedef __u_char       u_char;
+typedef __u_short      u_short;
+typedef __u_int                u_int;
+typedef __u_long       u_long;
 
-#include <asm/types.h>
+/*
+ * The following typedefs are also protected by individual ifdefs for
+ * historical reasons:
+ */
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef __size_t       size_t;
+#endif
 
-#ifndef NULL
-#define NULL ((void *) 0)
+#ifndef _SSIZE_T
+#define _SSIZE_T
+typedef __ssize_t      ssize_t;
 #endif
 
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-#define _LOFF_T
-typedef long long loff_t;
+#ifndef _PTRDIFF_T
+#define _PTRDIFF_T
+typedef __ptrdiff_t    ptrdiff_t;
 #endif
 
-/* bsd */
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
+#ifndef _TIME_T
+#define _TIME_T
+typedef __time_t       time_t;
+#endif
+
+#ifndef _CLOCK_T
+#define _CLOCK_T
+typedef __clock_t      clock_t;
+#endif
+
+#ifndef _CADDR_T
+#define _CADDR_T
+typedef __caddr_t      caddr_t;
+#endif
 
 /* sysv */
-typedef unsigned char unchar;
-typedef unsigned short ushort;
-typedef unsigned int uint;
-typedef unsigned long ulong;
+typedef unsigned char  unchar;
+typedef unsigned short ushort;
+typedef unsigned int   uint;
+typedef unsigned long  ulong;
+
+#endif /* _LINUX_TYPES_DONT_EXPORT */
+
+/*
+ * Below are truly Linux-specific types that should never collide with
+ * any application/library that wants linux/types.h.
+ */
 
-typedef char *caddr_t;
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+
+typedef long long      __loff_t;
 
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned int tcflag_t;
+#ifndef _LINUX_TYPES_DONT_EXPORT
+#define _LOFF_T
+typedef __loff_t       loff_t;
+#endif
+
+#endif
 
 struct ustat {
-       daddr_t f_tfree;
-       ino_t f_tinode;
-       char f_fname[6];
-       char f_fpack[6];
+       __daddr_t       f_tfree;
+       __ino_t         f_tinode;
+       char            f_fname[6];
+       char            f_fpack[6];
 };
 
-#endif
+#endif /* _LINUX_TYPES_H */
index 768a6b80475a2408a8d946258c255f31f03f06a2..9f95b0bea5b3a86951a6e85d2b218785234a004c 100644 (file)
@@ -19,9 +19,9 @@ struct vt_mode {
 #define                VT_ACKACQ       0x02    /* acknowledge switch */
 
 struct vt_stat {
-       ushort v_active;        /* active vt */
-       ushort v_signal;        /* signal to send */
-       ushort v_state;         /* vt bitmask */
+       unsigned short v_active;        /* active vt */
+       unsigned short v_signal;        /* signal to send */
+       unsigned short v_state;         /* vt bitmask */
 };
 #define VT_GETSTATE    0x5603  /* get global vt state info */
 #define VT_SENDSIG     0x5604  /* signal to send to bitmask of vts */
@@ -33,19 +33,19 @@ struct vt_stat {
 #define VT_DISALLOCATE 0x5608  /* free memory associated to vt */
 
 struct vt_sizes {
-       ushort v_rows;          /* number of rows */
-       ushort v_cols;          /* number of columns */
-       ushort v_scrollsize;    /* number of lines of scrollback */
+       unsigned short v_rows;          /* number of rows */
+       unsigned short v_cols;          /* number of columns */
+       unsigned short v_scrollsize;    /* number of lines of scrollback */
 };
 #define VT_RESIZE      0x5609  /* set kernel's idea of screensize */
 
 struct vt_consize {
-        ushort v_rows;         /* number of rows */
-       ushort v_cols;          /* number of columns */
-       ushort v_vlin;          /* number of pixel rows on screen */
-       ushort v_clin;          /* number of pixel rows per character */
-       ushort v_vcol;          /* number of pixel columns on screen */
-       ushort v_ccol;          /* number of pixel columns per character */
+       unsigned short v_rows;  /* number of rows */
+       unsigned short v_cols;  /* number of columns */
+       unsigned short v_vlin;  /* number of pixel rows on screen */
+       unsigned short v_clin;  /* number of pixel rows per character */
+       unsigned short v_vcol;  /* number of pixel columns on screen */
+       unsigned short v_ccol;  /* number of pixel columns per character */
 };
 #define VT_RESIZEX      0x560A  /* set kernel's idea of screensize + more */
 #define VT_LOCKSWITCH   0x560B  /* disallow vt switching */
index d79ebcc09b1dd399f84de58ca89e3ecbe3f3f2e6..93f4c0a7adb968ffe96676abff96a15d15478b75 100644 (file)
@@ -1,9 +1,9 @@
 extern void unix_proto_init(struct net_proto *pro);
-
+extern struct proto_ops unix_proto_ops;
+extern void unix_inflight(struct file *fp);
+extern void unix_notinflight(struct file *fp);
 typedef struct sock unix_socket;
 
-extern int unix_gc_free;
-extern void unix_gc_add(struct sock *sk, struct file *fp);
-extern void unix_gc_remove(struct file *fp);
+unix_socket *unix_socket_list;
 
 #define UNIX_MAX_FD    8
diff --git a/include/net/gc.h b/include/net/gc.h
new file mode 100644 (file)
index 0000000..0b28c09
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *     Interface routines assumed by gc()
+ *
+ *     Copyright (C) Barak A. Pearlmutter.
+ *     Released under the GPL version 2 or later.
+ *
+ */
+
+typedef struct object *pobj;   /* pointer to a guy of the type we gc */
+
+/*
+ *     How to mark and unmark objects
+ */
+
+extern void gc_mark(pobj);
+extern void gc_unmark(pobj);
+extern int gc_marked(pobj);
+
+/* 
+ *     How to count and access an object's children
+ */
+
+extern int n_children(pobj);   /* how many children */
+extern pobj child_n(pobj, int);        /* child i, numbered 0..n-1 */
+
+/*
+ *     How to access the root set
+ */
+
+extern int root_size(void);    /* number of things in root set */
+extern pobj root_elt(int);     /* element i of root set, numbered 0..n-1 */
+
+/*
+ *     How to access the free list
+ */
+
+extern void clear_freelist(void);
+extern void add_to_free_list(pobj);
+
+/*
+ *     How to iterate through all objects in memory
+ */
+
+extern int N_OBJS;
+extern pobj obj_number(int);
+
index 96c624053336e66d33c58bbe4909cdc082537ed0..9b8ba7a0b2c01464e4e0575b66b32fe84e3cbeee 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef _NET_INET_IPX_H_
 #define _NET_INET_IPX_H_
 
+#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/datalink.h>
 #include <linux/ipx.h>
index 52c676be27b98e45b76c7ae8c76a4ca2822addf7..03d7c3d6611f468eb87a771215d371be03e77938 100644 (file)
@@ -1,2 +1,7 @@
-struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+#ifndef _NET_P8022_H
+#define _NET_P8022_H
 
+extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+extern void unregister_8022_client(unsigned char type);
+
+#endif
index b69859dbd20ca57cc8371f6b74d8c668cffcca96..49a68f7e9b120dc061bdb5a302516f4eb41aebd3 100644 (file)
@@ -1,2 +1,7 @@
-struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+#ifndef _NET_PSNAP_H
+#define _NET_PSNAP_H
 
+extern struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+extern void unregister_snap_client(unsigned char *desc);
+
+#endif
index 81252107b76e252085bb84d9b062c12730f92786..3cb02ae91bde60ad8033f40e3e07e5082d296709 100644 (file)
 #include <net/netrom.h>
 #endif
 #endif
-#ifdef CONFIG_IPX
+
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 #include <net/ipx.h>
 #endif
-#ifdef CONFIG_ATALK
+
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
 #include <linux/atalk.h>
 #endif
 
@@ -73,6 +75,9 @@ struct unix_opt
        struct inode *          inode;
        struct semaphore        readsem;
        struct sock *           other;
+       int                     marksweep;
+#define MARKED                 1
+       int                     inflight;
 };
 
 /*
@@ -92,7 +97,7 @@ struct inet_packet_opt
  *     Once the IPX ncpd patches are in these are going into protinfo
  */
 
-#ifdef CONFIG_IPX 
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 struct ipx_opt
 {
        ipx_address             dest_addr;
@@ -261,12 +266,12 @@ struct sock
        union
        {
                struct unix_opt af_unix;
-#ifdef CONFIG_ATALK
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
                struct atalk_sock       af_at;
 #endif
-#ifdef CONFIG_IPX
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
                struct ipx_opt          af_ipx;
-#endif         
+#endif
 #ifdef CONFIG_INET
                struct inet_packet_opt  af_packet;
 #ifdef CONFIG_NUTCP            
index e63493ffd22d03e83e3ef07a727270b0108a14fb..e8179846ff6a6a0477d457b2e505dbee2c6fb2e8 100644 (file)
@@ -586,32 +586,29 @@ asmlinkage void start_secondary(void)
  
 static void smp_init(void)
 {
-       int i=0;
+       int i, j;
        smp_boot_cpus();
        
        /*
         *      Create the slave init tasks as sharing pid 0.
+        *
+        *      This should only happen if we have virtual CPU numbers
+        *      higher than 0.
         */
 
-       for (i=0; i<NR_CPUS; i++)
+       for (i=1; i<smp_num_cpus; i++)
        {
+               j = cpu_logical_map[i];
                /*
-                *      This should only do anything if the mapping
-                *      corresponds to a live CPU which is not the boot CPU.
+                *      We use kernel_thread for the idlers which are
+                *      unlocked tasks running in kernel space.
                 */
-               if (cpu_number_map[i] > 0)
-               {
-                       /*
-                        *      We use kernel_thread for the idlers which are
-                        *      unlocked tasks running in kernel space.
-                        */
-                       kernel_thread(cpu_idle, NULL, CLONE_PID);
-                       /*
-                        *      Don't assume linear processor numbering
-                        */
-                       current_set[i]=task[cpu_number_map[i]];
-                       current_set[i]->processor=i;
-               }
+               kernel_thread(cpu_idle, NULL, CLONE_PID);
+               /*
+                *      Don't assume linear processor numbering
+                */
+               current_set[j]=task[i];
+               current_set[j]->processor=j;
        }
 }              
 
index 01c085766b7764b9105fad785561fbbb4efcd933..2b8e6d13ba1fa3aff1d983e196364f150b1d8429 100644 (file)
@@ -49,7 +49,9 @@ int send_sig(unsigned long sig,struct task_struct * p,int priv)
        if (!p || sig > 32)
                return -EINVAL;
        if (!priv && ((sig != SIGCONT) || (current->session != p->session)) &&
-           (current->euid != p->euid) && (current->euid != p->uid) && !suser())
+           (current->euid ^ p->euid) && (current->euid ^ p->uid) &&
+           (current->uid ^ p->euid) && (current->uid ^ p->uid) &&
+           !suser())
                return -EPERM;
        if (!sig)
                return 0;
index e02b6b7fb13691fbc5c1a018ce6f256e3b4dec19..16ed1d1a1b68dddf197e0cd9e9238985778d209f 100644 (file)
@@ -227,7 +227,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
        p->kernel_stack_page = new_stack;
        *(unsigned long *) p->kernel_stack_page = STACK_MAGIC;
        p->state = TASK_UNINTERRUPTIBLE;
-       p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPREV);
+       p->flags &= ~(PF_PTRACED|PF_TRACESYS|PF_SUPERPRIV);
        p->flags |= PF_FORKNOEXEC;
        p->pid = get_pid(clone_flags);
        p->next_run = NULL;
index e4c80aad2d68ca4909948d6d27ffca97eb7d6bb4..29c7883648d86ffc696801c8ad0ed7b3c1ac8686 100644 (file)
 
 extern unsigned char aux_device_present, kbd_read_mask;
 
-#ifdef CONFIG_NET
-#include <linux/in.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/firewall.h>
-#include <linux/trdevice.h>
-
-#ifdef CONFIG_AX25
-#include <net/ax25.h>
-#endif
-#ifdef CONFIG_INET
-#include <linux/ip.h>
-#include <linux/etherdevice.h>
-#include <net/protocol.h>
-#include <net/arp.h>
-#include <net/ip.h>
-#include <net/udp.h>
-#include <net/tcp.h>
-#include <net/icmp.h>
-#include <net/route.h>
-#include <linux/net_alias.h>
-#endif
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-#endif
 #ifdef CONFIG_PCI
 #include <linux/bios32.h>
 #include <linux/pci.h>
@@ -96,17 +70,9 @@ extern void blkdev_release(struct inode * inode);
 
 extern void *sys_call_table;
 
-#if    defined(CONFIG_ULTRA)   ||      defined(CONFIG_WD80x3)          || \
-       defined(CONFIG_EL2)     ||      defined(CONFIG_NE2000)          || \
-       defined(CONFIG_E2100)   ||      defined(CONFIG_HPLAN_PLUS)      || \
-       defined(CONFIG_HPLAN)   ||      defined(CONFIG_AC3200)
-#include "../drivers/net/8390.h"
-#endif
-
 extern int sys_tz;
 extern int request_dma(unsigned int dmanr, char * deviceID);
 extern void free_dma(unsigned int dmanr);
-extern int (*rarp_ioctl_hook)(int,void*);
 
 struct symbol_table symbol_table = {
 #include <linux/symtab_begin.h>
@@ -251,6 +217,7 @@ struct symbol_table symbol_table = {
        X(unregister_binfmt),
        X(search_binary_handler),
        X(prepare_binprm),
+       X(remove_arg_zero),
 
        /* execution environment registration */
        X(lookup_exec_domain),
@@ -339,94 +306,7 @@ struct symbol_table symbol_table = {
 
        /* Miscellaneous access points */
        X(si_meminfo),
-#ifdef CONFIG_NET
-       /* Socket layer registration */
-       X(sock_register),
-       X(sock_unregister),
-       /* Socket layer support routines */
-       X(skb_recv_datagram),
-       X(skb_free_datagram),
-       X(skb_copy_datagram),
-       X(skb_copy_datagram_iovec),
-       X(datagram_select),
-#ifdef CONFIG_FIREWALL
-       /* Firewall registration */
-       X(register_firewall),
-       X(unregister_firewall),
-#endif
-#ifdef CONFIG_INET     
-       /* Internet layer registration */
-       X(inet_add_protocol),
-       X(inet_del_protocol),
-       X(rarp_ioctl_hook),
-       X(init_etherdev),
-       X(ip_rt_route),
-       X(icmp_send),
-       X(ip_options_compile),
-       X(ip_rt_put),
-       X(arp_send),
-#ifdef CONFIG_IP_FORWARD
-       X(ip_forward),
-#endif
-#if    defined(CONFIG_ULTRA)   ||      defined(CONFIG_WD80x3)          || \
-       defined(CONFIG_EL2)     ||      defined(CONFIG_NE2000)          || \
-       defined(CONFIG_E2100)   ||      defined(CONFIG_HPLAN_PLUS)      || \
-       defined(CONFIG_HPLAN)   ||      defined(CONFIG_AC3200)
-       /* If 8390 NIC support is built in, we will need these. */
-       X(ei_open),
-       X(ei_close),
-       X(ei_debug),
-       X(ei_interrupt),
-       X(ethdev_init),
-       X(NS8390_init),
-#endif
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-#endif
-       /* Device callback registration */
-       X(register_netdevice_notifier),
-       X(unregister_netdevice_notifier),
-#ifdef CONFIG_NET_ALIAS
-       X(register_net_alias_type),
-       X(unregister_net_alias_type),
-#endif
-#endif
 
-       /* support for loadable net drivers */
-#ifdef CONFIG_AX25
-       X(ax25_encapsulate),
-       X(ax25_rebuild_header), 
-#endif 
-#ifdef CONFIG_INET
-       X(register_netdev),
-       X(unregister_netdev),
-       X(ether_setup),
-       X(eth_type_trans),
-       X(eth_copy_and_sum),
-       X(alloc_skb),
-       X(kfree_skb),
-       X(skb_clone),
-       X(dev_alloc_skb),
-       X(dev_kfree_skb),
-       X(netif_rx),
-       X(dev_tint),
-       X(irq2dev_map),
-       X(dev_add_pack),
-       X(dev_remove_pack),
-       X(dev_get),
-       X(dev_ioctl),
-       X(dev_queue_xmit),
-       X(dev_base),
-       X(dev_close),
-       X(arp_find),
-       X(n_tty_ioctl),
-       X(tty_register_ldisc),
-       X(kill_fasync),
-#ifdef CONFIG_FIREWALL
-       X(call_in_firewall),
-#endif
-#endif
 #ifndef CONFIG_SCSI
        /*
         * With no scsi configured, we still need to export a few
index 992b2d23e2c2ca090eed1852f79e10d304ff6cbd..e9f6eeff2703078b6bea84ba315726109fea7041 100644 (file)
@@ -38,7 +38,7 @@
  *
  * On 1-Aug-95:  <Matti.Aarnio@utu.fi>  altered code to use same style as
  *              do  /proc/net/XXX  "files".  Namely allow more than 4kB
- *              (or what the block size if) output.
+ *              (or what the block size is) output.
  *
  *     - Use dummy syscall functions for users who disable all
  *       module support. Similar to kernel/sys.c (Paul Gortmaker)
index 932affd97ce2304a2899e89d693c6c234e61bd86..0a2e656a1a0f055083af5c2ed4af38d93043ed2b 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * 'sched.c' is the main kernel file. It contains scheduling primitives
  * (sleep_on, wakeup, schedule etc) as well as a number of simple system
- * call functions (type getpid(), which just extracts a field from
+ * call functions (type getpid()), which just extract a field from
  * current-task
  */
 
@@ -136,13 +136,11 @@ static inline void add_to_runqueue(struct task_struct * p)
        if ((0!=p->pid) && smp_threads_ready)
        {
                int i;
-               for (i=0;i<=smp_top_cpu;i++)
+               for (i=0;i<smp_num_cpus;i++)
                {
-                       if (cpu_number_map[i]==-1)
-                               continue;
-                       if (0==current_set[i]->pid) 
+                       if (0==current_set[cpu_logical_map[i]]->pid) 
                        {
-                               smp_message_pass(i, MSG_RESCHEDULE, 0L, 0);
+                               smp_message_pass(cpu_logical_map[i], MSG_RESCHEDULE, 0L, 0);
                                break;
                        }
                }
@@ -929,14 +927,13 @@ static void update_process_times(unsigned long ticks, unsigned long system)
                update_one_process(p, ticks, ticks-system, system);
        }
 #else
-       int cpu,i;
+       int cpu,j;
        cpu = smp_processor_id();
-       for (i=0;i<=smp_top_cpu;i++)
+       for (j=0;j<smp_num_cpus;j++)
        {
+               int i = cpu_logical_map[j];
                struct task_struct *p;
                
-               if(cpu_number_map[i]==-1)
-                       continue;
 #ifdef __SMP_PROF__
                if (test_bit(i,&smp_idle_map)) 
                        smp_idle_count[i]++;
index c9bbf14551546591b52e4d770504d435e2065487..3812d45831c60bb5d863a38f958164e88b2dc909 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/fcntl.h>
 #include <linux/acct.h>
 #include <linux/tty.h>
-#include <sys/sysmacros.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -297,12 +296,12 @@ int acct_process(long exitcode)
       ac.ac_etime = CURRENT_TIME - ac.ac_btime;
       ac.ac_uid   = current->uid;
       ac.ac_gid   = current->gid;
-      ac.ac_tty   = (current)->tty == NULL ? -1 : 
-         makedev (4, current->tty->device);
+      ac.ac_tty   = (current)->tty == NULL ? -1 :
+         MKDEV(4, current->tty->device);
       ac.ac_flag  = 0;
       if (current->flags & PF_FORKNOEXEC)
          ac.ac_flag |= AFORK;
-      if (current->flags & PF_SUPERPREV)
+      if (current->flags & PF_SUPERPRIV)
          ac.ac_flag |= ASU;
       if (current->flags & PF_DUMPCORE)
          ac.ac_flag |= ACORE;
index 60c2659d17019ab3cba6d09a5bafa235b90071fb..19552c98fd5c06cacc7ac436341a6fc18bb620e6 100644 (file)
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-O_OBJS  := memory.o mmap.o filemap.o mprotect.o mlock.o \
+O_OBJS  := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
            kmalloc.o vmalloc.o \
            swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
 
index 82965a7ff6bee7a33699397630d547610dae16a1..e561177b977f573d6d539fac3edf444b42e5a7c7 100644 (file)
@@ -734,16 +734,23 @@ bad_area:
        return -EFAULT;
 }
 
-static inline void get_empty_page(struct task_struct * tsk, struct vm_area_struct * vma, pte_t * page_table)
+static inline void get_empty_page(struct task_struct * tsk, struct vm_area_struct * vma,
+       pte_t * page_table, int write_access)
 {
-       unsigned long tmp;
+       pte_t pte;
 
-       if (!(tmp = get_free_page(GFP_KERNEL))) {
-               oom(tsk);
-               put_page(page_table, BAD_PAGE);
-               return;
+       pte = pte_wrprotect(mk_pte(ZERO_PAGE, vma->vm_page_prot));
+       if (write_access) {
+               unsigned long page = get_free_page(GFP_KERNEL);
+               pte = pte_mkwrite(mk_pte(page, vma->vm_page_prot));
+               vma->vm_mm->rss++;
+               tsk->min_flt++;
+               if (!page) {
+                       oom(tsk);
+                       pte = BAD_PAGE;
+               }
        }
-       put_page(page_table, pte_mkwrite(mk_pte(tmp, vma->vm_page_prot)));
+       put_page(page_table, pte);
 }
 
 /*
@@ -894,9 +901,7 @@ void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma,
        }
        address &= PAGE_MASK;
        if (!vma->vm_ops || !vma->vm_ops->nopage) {
-               ++vma->vm_mm->rss;
-               ++tsk->min_flt;
-               get_empty_page(tsk, vma, page_table);
+               get_empty_page(tsk, vma, page_table, write_access);
                return;
        }
        ++tsk->maj_flt;
index af307e5ba3a9929cf63bfa1c5c2647708d4ab8a1..e350aa3dea339c924b81200acc41a35d0e9557ff 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
 #include <asm/system.h>
 #include <asm/pgtable.h>
 
-/*
- * Map memory not associated with any file into a process
- * address space.  Adjacent memory is merged.
- */
-static inline int anon_map(struct inode *ino, struct file * file, struct vm_area_struct * vma)
-{
-       if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
-               return -ENOMEM;
-       return 0;
-}
-
 /*
  * description of effects of mapping type and prot in current implementation.
  * this is due to the limited x86 page protection hardware.  The expected
@@ -53,7 +42,6 @@ pgprot_t protection_map[16] = {
 unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
        unsigned long prot, unsigned long flags, unsigned long off)
 {
-       int error;
        struct vm_area_struct * vma;
 
        if ((len = PAGE_ALIGN(len)) == 0)
@@ -165,15 +153,15 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
 
        do_munmap(addr, len);   /* Clear old maps */
 
-       if (file)
-               error = file->f_op->mmap(file->f_inode, file, vma);
-       else
-               error = anon_map(NULL, NULL, vma);
+       if (file) {
+               int error = file->f_op->mmap(file->f_inode, file, vma);
        
-       if (error) {
-               kfree(vma);
-               return error;
+               if (error) {
+                       kfree(vma);
+                       return error;
+               }
        }
+
        flags = vma->vm_flags;
        insert_vm_struct(current, vma);
        merge_segments(current, vma->vm_start, vma->vm_end);
diff --git a/mm/mremap.c b/mm/mremap.c
new file mode 100644 (file)
index 0000000..70d91bd
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ *     linux/mm/remap.c
+ *
+ *     (C) Copyright 1996 Linus Torvalds
+ */
+
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/shm.h>
+#include <linux/errno.h>
+#include <linux/mman.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <linux/swap.h>
+
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr)
+{
+       pgd_t * pgd;
+       pmd_t * pmd;
+       pte_t * pte = NULL;
+
+       pgd = pgd_offset(mm, addr);
+       if (pgd_none(*pgd))
+               goto end;
+       if (pgd_bad(*pgd)) {
+               printk("move_one_page: bad source pgd (%08lx)\n", pgd_val(*pgd));
+               pgd_clear(pgd);
+               goto end;
+       }
+
+       pmd = pmd_offset(pgd, addr);
+       if (pmd_none(*pmd))
+               goto end;
+       if (pmd_bad(*pmd)) {
+               printk("move_one_page: bad source pmd (%08lx)\n", pmd_val(*pmd));
+               pmd_clear(pmd);
+               goto end;
+       }
+
+       pte = pte_offset(pmd, addr);
+       if (pte_none(*pte))
+               pte = NULL;
+end:
+       return pte;
+}
+
+static inline pte_t *alloc_one_pte(struct mm_struct *mm, unsigned long addr)
+{
+       pmd_t * pmd;
+       pte_t * pte = NULL;
+
+       pmd = pmd_alloc(pgd_offset(mm, addr), addr);
+       if (pmd)
+               pte = pte_alloc(pmd, addr);
+       return pte;
+}
+
+static inline int copy_one_pte(pte_t * src, pte_t * dst)
+{
+       int error = 0;
+       pte_t pte = *src;
+
+       if (!pte_none(pte)) {
+               error++;
+               if (dst) {
+                       pte_clear(src);
+                       set_pte(dst, pte);
+                       error--;
+               }
+       }
+       return error;
+}
+
+static int move_one_page(struct mm_struct *mm, unsigned long old_addr, unsigned long new_addr)
+{
+       int error = 0;
+       pte_t * src;
+
+       src = get_one_pte(mm, old_addr);
+       if (src)
+               error = copy_one_pte(src, alloc_one_pte(mm, new_addr));
+       return error;
+}
+
+static int move_page_tables(struct mm_struct * mm,
+       unsigned long new_addr, unsigned long old_addr, unsigned long len)
+{
+       unsigned long offset = len;
+
+       invalidate_range(mm, old_addr, old_addr + len);
+
+       /*
+        * This is not the clever way to do this, but we're taking the
+        * easy way out on the assumption that most remappings will be
+        * only a few pages.. This also makes error recovery easier.
+        */
+       while (offset) {
+               offset -= PAGE_SIZE;
+               if (move_one_page(mm, old_addr + offset, new_addr + offset))
+                       goto oops_we_failed;
+       }
+       return 0;
+
+       /*
+        * Ok, the move failed because we didn't have enough pages for
+        * the new page table tree. This is unlikely, but we have to
+        * take the possibility into account. In that case we just move
+        * all the pages back (this will work, because we still have
+        * the old page tables)
+        */
+oops_we_failed:
+       while ((offset += PAGE_SIZE) < len)
+               move_one_page(mm, new_addr + offset, old_addr + offset);
+       invalidate_range(mm, new_addr, new_addr + len);
+       zap_page_range(mm, new_addr, new_addr + len);
+       return -1;
+}
+
+static inline unsigned long move_vma(struct vm_area_struct * vma,
+       unsigned long addr, unsigned long old_len, unsigned long new_len)
+{
+       struct vm_area_struct * new_vma;
+
+       new_vma = (struct vm_area_struct *)
+               kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+       if (new_vma) {
+               unsigned long new_addr = get_unmapped_area(addr, new_len);
+
+               if (new_addr && !move_page_tables(current->mm, new_addr, addr, old_len)) {
+                       *new_vma = *vma;
+                       new_vma->vm_start = new_addr;
+                       new_vma->vm_end = new_addr+new_len;
+                       new_vma->vm_offset = vma->vm_offset + (addr - vma->vm_start);
+                       if (new_vma->vm_inode)
+                               new_vma->vm_inode->i_count++;
+                       if (new_vma->vm_ops && new_vma->vm_ops->open)
+                               new_vma->vm_ops->open(new_vma);
+                       insert_vm_struct(current, new_vma);
+                       merge_segments(current, new_vma->vm_start, new_vma->vm_end);
+                       do_munmap(addr, old_len);
+                       return new_addr;
+               }
+               kfree(new_vma);
+       }
+       return -ENOMEM;
+}
+
+/*
+ * Expand (or shrink) an existing mapping, potentially moving it at the
+ * same time (controlled by the "may_move" flag and available VM space)
+ */
+asmlinkage unsigned long sys_mremap(unsigned long addr,
+       unsigned long old_len, unsigned long new_len,
+       int may_move)
+{
+       struct vm_area_struct *vma;
+
+       if (addr & ~PAGE_MASK)
+               return -EINVAL;
+       old_len = PAGE_ALIGN(old_len);
+       new_len = PAGE_ALIGN(new_len);
+       if (old_len == new_len)
+               return addr;
+
+       /*
+        * Always allow a shrinking remap: that just unmaps
+        * the unnecessary pages..
+        */
+       if (old_len > new_len) {
+               do_munmap(addr+new_len, old_len - new_len);
+               return addr;
+       }
+
+       /*
+        * Ok, we need to grow..
+        */
+       vma = find_vma(current, addr);
+       if (!vma || vma->vm_start > addr)
+               return -EFAULT;
+       /* We can't remap across vm area boundaries */
+       if (old_len > vma->vm_end - addr)
+               return -EFAULT;
+       if (vma->vm_flags & VM_LOCKED) {
+               unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
+               locked += new_len - old_len;
+               if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+                       return -EAGAIN;
+       }
+
+       /* old_len exactly to the end of the area.. */
+       if (old_len == vma->vm_end - addr) {
+               unsigned long max_addr = TASK_SIZE;
+               if (vma->vm_next)
+                       max_addr = vma->vm_next->vm_start;
+               /* can we just expand the current mapping? */
+               if (max_addr - addr >= new_len) {
+                       int pages = (new_len - old_len) >> PAGE_SHIFT;
+                       vma->vm_end = addr + new_len;
+                       current->mm->total_vm += pages;
+                       if (vma->vm_flags & VM_LOCKED)
+                               current->mm->locked_vm += pages;
+                       return addr;
+               }
+       }
+
+       /*
+        * We weren't able to just expand or shrink the area,
+        * we need to create a new one and move it..
+        */
+       if (!may_move)
+               return -ENOMEM;
+       return move_vma(vma, addr, old_len, new_len);
+}
index ad6590d282c232a24ecc2c539e155c7b9071e3f4..550ac3826623c8e13fe3dca8b30069145522e0ef 100644 (file)
@@ -15,12 +15,12 @@ O_OBJS += tr.o
 endif
 
 ifdef CONFIG_IPX
-O_OBJS += p8022.o psnap.o
+OX_OBJS += p8022.o psnap.o
 endif
 
 ifdef CONFIG_ATALK
 ifndef CONFIG_IPX
-O_OBJS += p8022.o psnap.o
+OX_OBJS += p8022.o psnap.o
 endif
 endif
 
index 198591eee282e2c273c09f79b1e0d666fcf0bd73..f8754e5c065099931931d81129e6c6c2974eec2b 100644 (file)
@@ -1,8 +1,10 @@
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/datalink.h>
 #include <linux/mm.h>
 #include <linux/in.h>
+#include <net/p8022.h>
 
 static struct datalink_proto *p8022_list = NULL;
 
@@ -65,12 +67,20 @@ static struct packet_type p8022_packet_type =
        NULL,
        NULL,
 };
+
+static struct symbol_table p8022_proto_syms = {
+#include <linux/symtab_begin.h>
+       X(register_8022_client),
+       X(unregister_8022_client),
+#include <linux/symtab_end.h>
+};
  
 
 void p8022_proto_init(struct net_proto *pro)
 {
        p8022_packet_type.type=htons(ETH_P_802_2);
        dev_add_pack(&p8022_packet_type);
+       register_symtab(&p8022_proto_syms);
 }
        
 struct datalink_proto *
@@ -96,3 +106,24 @@ register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct
        return proto;
 }
 
+void unregister_8022_client(unsigned char type)
+{
+       struct datalink_proto *tmp, **clients = &p8022_list;
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+
+       while ((tmp = *clients) != NULL)
+       {
+               if (tmp->type[0] == type) {
+                       *clients = tmp->next;
+                       kfree_s(tmp, sizeof(struct datalink_proto));
+                       break;
+               } else {
+                       clients = &tmp->next;
+               }
+       }
+
+       restore_flags(flags);
+}
index 4015fb7e49e01874ed82c9c59e0a756d09b633ed..57bd6a74a10acfad6f79c8f0b10b583c72af267e 100644 (file)
@@ -29,3 +29,9 @@ make_8023_client(void)
        return proto;
 }
 
+void destroy_8023_client(struct datalink_proto *dl)
+{
+       if (dl)
+               kfree_s(dl,sizeof(struct datalink_proto));
+}
+
index 619c05c94333f8ad1e6d4662aa5c8199021ab91c..4f17352ab58665344a0f1b589be4488d14b8451c 100644 (file)
@@ -10,6 +10,7 @@
  *             2 of the License, or (at your option) any later version.
  */
  
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/datalink.h>
@@ -81,12 +82,20 @@ static void snap_datalink_header(struct datalink_proto *dl, struct sk_buff *skb,
 /*
  *     Set up the SNAP layer
  */
+
+static struct symbol_table snap_proto_syms = {
+#include <linux/symtab_begin.h>
+       X(register_snap_client),
+       X(unregister_snap_client),
+#include <linux/symtab_end.h>
+};
  
 void snap_proto_init(struct net_proto *pro)
 {
        snap_dl=register_8022_client(0xAA, snap_rcv);
        if(snap_dl==NULL)
                printk("SNAP - unable to register with 802.2\n");
+       register_symtab(&snap_proto_syms);
 }
        
 /*
@@ -116,3 +125,31 @@ struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(
        return proto;
 }
 
+/*
+ *     Unregister SNAP clients. Protocols no longer want to play with us ...
+ */
+
+void unregister_snap_client(unsigned char *desc)
+{
+       struct datalink_proto **clients = &snap_list;
+       struct datalink_proto *tmp;
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+
+       while ((tmp = *clients) != NULL)
+       {
+               if (memcmp(tmp->type,desc,5) == 0)
+               {
+                       *clients = tmp->next;
+                       kfree_s(tmp, sizeof(struct datalink_proto));
+                       break;
+               }
+               else
+                       clients = &tmp->next;
+       }
+
+       restore_flags(flags);
+}
+
index 4dc4f28be7ceec26dd190b42cdb1581e0a1fe54a..ae21864c095a9d85bce5dab25acdec4e723967d0 100644 (file)
@@ -10,11 +10,11 @@ if [ "$CONFIG_INET" = "y" ]; then
   source net/ipv4/Config.in
 fi
 comment ' '
-bool 'The IPX protocol' CONFIG_IPX
-if [ "$CONFIG_IPX" = "y" ]; then
+tristate 'The IPX protocol' CONFIG_IPX
+if [ ! "$CONFIG_IPX" = "n" ]; then
   bool 'Full internal IPX network' CONFIG_IPX_INTERN
 fi
-bool 'Appletalk DDP' CONFIG_ATALK
+tristate 'Appletalk DDP' CONFIG_ATALK
 bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25
 if [ "$CONFIG_AX25" = "y" ]; then
   bool 'AX.25 over Ethernet' CONFIG_BPQETHER
index e971b0525d12081011d54d168bf8599da61ec934..5cca88018813715814a02e65ca529d9a56c15b61 100644 (file)
@@ -10,6 +10,7 @@
 MOD_SUB_DIRS := ipv4
 ALL_SUB_DIRS := 802 ax25 core ethernet ipv4 ipx unix appletalk netrom
 SUB_DIRS     := 802 core ethernet unix
+MOD_LIST_NAME := NET_MISC_MODULES
 
 ifeq ($(CONFIG_INET),y)
 SUB_DIRS += ipv4
@@ -17,10 +18,18 @@ endif
 
 ifeq ($(CONFIG_IPX),y)
 SUB_DIRS += ipx
+else
+  ifeq ($(CONFIG_IPX),m)
+  MOD_SUB_DIRS += ipx
+  endif
 endif
 
 ifeq ($(CONFIG_ATALK),y)
 SUB_DIRS += appletalk
+else
+  ifeq ($(CONFIG_ATALK),m)
+  MOD_SUB_DIRS += appletalk
+  endif
 endif
 
 ifeq ($(CONFIG_NETROM),y)
@@ -33,6 +42,10 @@ endif
 
 L_TARGET     := network.a
 L_OBJS      := socket.o protocols.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o))
+ifeq ($(CONFIG_MODULES),y)
+LX_OBJS = netsyms.o
+endif
+
 M_OBJS      :=
 
 ifeq ($(CONFIG_NETLINK),y)
index 8bfe8f721ee05674871551313d4a162ca2e8f349..3980cd9e4cb505f296f04d95f138a8b5fae09fd9 100644 (file)
@@ -9,6 +9,7 @@
 
 O_TARGET := appletalk.o
 O_OBJS  := aarp.o ddp.o
+M_OBJS   := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
 
index ce7acc2b4c3933f3942f7aafcb5d2a76df4317a2..bd138e0859e7f95551faf9c2b233aae2f5ead7e2 100644 (file)
@@ -26,7 +26,6 @@
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/if_ether.h>
-#include <linux/if_arp.h>
 #include <linux/inet.h>
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_arp.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <linux/atalk.h>
 
-#ifdef CONFIG_ATALK
 /*
  *     Lists of aarp entries
  */
@@ -790,10 +788,11 @@ static struct notifier_block aarp_notifier={
        0
 };
 
+static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
+
 
 void aarp_proto_init(void)
 {
-       static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
        if((aarp_dl=register_snap_client(aarp_snap_id, aarp_rcv))==NULL)
                printk("Unable to register AARP with SNAP.\n");
        init_timer(&aarp_timer);
@@ -803,4 +802,43 @@ void aarp_proto_init(void)
        add_timer(&aarp_timer);
        register_netdevice_notifier(&aarp_notifier);
 }
-#endif
+
+
+#ifdef MODULE
+
+/* Free all the entries in an aarp list. Caller should turn off interrupts. */
+static void free_entry_list(struct aarp_entry *list)
+{
+       struct aarp_entry *tmp;
+
+       while (list != NULL)
+       {
+               tmp = list->next;
+               aarp_expire(list);
+               list = tmp;
+       }
+}
+
+/* General module cleanup. Called from cleanup_module() in ddp.c. */
+void aarp_cleanup_module(void)
+{
+       unsigned long flags;
+       int i;
+
+       save_flags(flags);
+       cli();
+
+       del_timer(&aarp_timer);
+       unregister_netdevice_notifier(&aarp_notifier);
+       unregister_snap_client(aarp_snap_id);
+
+       for (i = 0; i < AARP_HASH_SIZE; i++)
+       {
+               free_entry_list(resolved[i]);
+               free_entry_list(unresolved[i]);
+       }
+
+       restore_flags(flags);
+}
+
+#endif  /* MODULE */
index 29b72bb799396e52baf87ad469e81290aaeb032d..de582793f97efa0cfc96d78d3d578b6d5b6c467f 100644 (file)
@@ -20,6 +20,9 @@
  *             Alan Cox                :       Supports new ARPHRD_LOOPBACK
  *             Christer Weinigel       :       Routing and /proc fixes.
  *             Bradford Johnson        :       Locatalk.
+ *             Tom Dyas                :       Module support.
+ *             Alan Cox                :       Hooks for PPP (based on the
+ *                                             localtalk hook).
  *
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
  *             ASYNC I/O
  */
  
+#include <linux/config.h>
+#include <linux/module.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/if_ether.h>
-#include <linux/if_arp.h>
 #include <linux/route.h>
 #include <linux/inet.h>
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_arp.h>
 #include <linux/skbuff.h>
 #include <linux/termios.h>     /* For TIOCOUTQ/INQ */
 #include <net/datalink.h>
@@ -62,7 +66,6 @@
 #include <linux/stat.h>
 #include <linux/firewall.h>
 
-#ifdef CONFIG_ATALK
 
 #undef APPLETALK_DEBUG
 
@@ -214,7 +217,10 @@ static void atalk_destroy_socket(atalk_socket *sk)
        }
        
        if(sk->wmem_alloc == 0 && sk->rmem_alloc == 0 && sk->dead)
+       {
                kfree_s(sk,sizeof(*sk));
+               MOD_DEC_USE_COUNT;
+       }
        else
        {
                /*
@@ -256,7 +262,7 @@ int atalk_get_info(char *buffer, char **start, off_t offset, int length, int dum
                        ntohs(s->protinfo.af_at.dest_net),
                        s->protinfo.af_at.dest_node,
                        s->protinfo.af_at.dest_port);
-               len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc);
+               len += sprintf (buffer+len,"%08X:%08X ", s->wmem_alloc, s->rmem_alloc);
                len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid);
                
                /* Are we still dumping unwanted data then discard the record */
@@ -359,8 +365,8 @@ static int atif_probe_device(struct atalk_iface *atif)
  *     now for the 1.4 release as is.
  *
  */
-       if(atif->dev->type == ARPHRD_LOCALTLK &&
-               atif->dev->do_ioctl) 
+       if((atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP)
+               && atif->dev->do_ioctl) 
        {
                /* fake up the request and pass it down */
                sa = (struct sockaddr_at*)&atreq.ifr_addr;
@@ -753,7 +759,7 @@ int atif_ioctl(int cmd, void *arg)
                        if(sa->sat_family!=AF_APPLETALK)
                                return -EINVAL;
                        if(dev->type!=ARPHRD_ETHER&&dev->type!=ARPHRD_LOOPBACK
-                               &&dev->type!=ARPHRD_LOCALTLK)
+                               &&dev->type!=ARPHRD_LOCALTLK && dev->type!=ARPHRD_PPP)
                                return -EPROTONOSUPPORT;
                        nr=(struct netrange *)&sa->sat_zero[0];
                        /*
@@ -1133,6 +1139,9 @@ static int atalk_create(struct socket *sock, int protocol)
                        kfree_s((void *)sk,sizeof(*sk));
                        return(-ESOCKTNOSUPPORT);
        }
+
+       MOD_INC_USE_COUNT;
+
        sk->dead=0;
        sk->next=NULL;
        sk->broadcast=0;
@@ -1400,7 +1409,8 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
 /*
  *     Receive a packet (in skb) from device dev. This has come from the SNAP decoder, and on entry
  *     skb->h.raw is the DDP header, skb->len is the DDP length. The physical headers have been 
- *     extracted.
+ *     extracted. PPP should probably pass frames marked as for this layer
+ *     [ie ARPHRD_ETHERTALK]
  */
  
 static int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
@@ -2005,11 +2015,22 @@ struct packet_type ltalk_packet_type=
        NULL
 };
 
+struct packet_type ppptalk_packet_type=
+{
+       0,
+       NULL,
+       atalk_rcv,
+       NULL,
+       NULL
+};
+
+static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B};
+
+
 /* Called by proto.c on kernel start up */
 
 void atalk_proto_init(struct net_proto *pro)
 {
-       static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B};
        (void) sock_register(atalk_proto_ops.family, &atalk_proto_ops);
        if ((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL)
                printk("Unable to register DDP with SNAP.\n");
@@ -2017,6 +2038,9 @@ void atalk_proto_init(struct net_proto *pro)
        ltalk_packet_type.type=htons(ETH_P_LOCALTALK);  
        dev_add_pack(&ltalk_packet_type);
        
+       ppptalk_packet_type.type=htons(ETH_P_PPPTALK);
+       dev_add_pack(&ppptalk_packet_type);
+       
        register_netdevice_notifier(&ddp_notifier);
        aarp_proto_init();
 
@@ -2039,6 +2063,71 @@ void atalk_proto_init(struct net_proto *pro)
                atalk_if_get_info
        });
 
-       printk("Appletalk 0.16 for Linux NET3.033\n");
+       printk("Appletalk 0.17 for Linux NET3.034\n");
 }
-#endif
+
+#ifdef MODULE
+
+int init_module(void)
+{
+       atalk_proto_init(NULL);
+       register_symtab(0);
+       return 0;
+}
+
+/*
+ *     FIX THIS: If there are any routes/devices configured
+ *     for appletalk we must not be unloaded.
+ */
+/* Remove all route entries. Interrupts must be off. */
+extern inline void free_route_list(void)
+{
+       struct atalk_route *list = atalk_router_list, *tmp;
+
+       while (list != NULL)
+       {
+               tmp = list->next;
+               kfree_s(list, sizeof(struct atalk_route));
+               list = tmp;
+       }
+}
+
+/* Remove all interface entries. Interrupts must be off. */
+extern inline void free_interface_list(void)
+{
+       struct atalk_iface *list = atalk_iface_list, *tmp;
+
+       while (list != NULL)
+       {
+               tmp = list->next;
+               kfree_s(list, sizeof(struct atalk_iface));
+               list = tmp;
+       }
+}
+
+void cleanup_module(void)
+{
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+
+       aarp_cleanup_module();
+
+       proc_net_unregister(PROC_NET_ATALK);
+       proc_net_unregister(PROC_NET_AT_ROUTE);
+       proc_net_unregister(PROC_NET_ATIF);
+       unregister_netdevice_notifier(&ddp_notifier);
+       dev_remove_pack(&ltalk_packet_type);
+       dev_remove_pack(&ppptalk_packet_type);
+       unregister_snap_client(ddp_snap_id);
+       sock_unregister(atalk_proto_ops.family);
+
+       free_route_list();
+       free_interface_list();
+
+       restore_flags(flags);
+}
+
+#endif  /* MODULE */
index b38a53d1588bc938e55eb02b0168eb79f2121640..e000000f5ff44b434225d90f5c8935fdd0098cf5 100644 (file)
@@ -2310,7 +2310,7 @@ static int ax25_get_info(char *buffer, char **start, off_t offset, int length, i
                len += sprintf(buffer + len, " %s", ax25->dama_slave? " slave" : "    no");
 
                if (ax25->sk != NULL) {
-                       len += sprintf(buffer + len, " %5ld %5ld\n",
+                       len += sprintf(buffer + len, " %5d %5d\n",
                                ax25->sk->wmem_alloc,
                                ax25->sk->rmem_alloc);
                } else {
@@ -2419,7 +2419,7 @@ void ax25_proto_init(struct net_proto *pro)
                ax25_cs_get_info
        });
 
-       printk("G4KLX/GW4PTS AX.25 for Linux. Version 0.31 BETA for Linux NET3.032 (Linux 1.3.53)\n");
+       printk("G4KLX/GW4PTS AX.25 for Linux. Version 0.32 BETA for Linux NET3.034 (Linux 1.3.77)\n");
 
 #ifdef CONFIG_BPQETHER
        proc_net_register(&(struct proc_dir_entry) {
@@ -2584,7 +2584,7 @@ int ax25_rebuild_header(unsigned char *bp, struct device *dev, unsigned long des
                         *      freeing it).
                         */
                        struct sk_buff *ourskb=skb_clone(skb, GFP_ATOMIC);
-                       dev_kfree_skb(skb, FREE_READ);
+                       dev_kfree_skb(skb, FREE_WRITE);
                        if(ourskb==NULL)
                                return 1;                       
                        skb_pull(ourskb, AX25_HEADER_LEN - 1);  /* Keep PID */
index b91328db9f7fe4c65f6e680483ff8648309a780e..4c0b1473c67bffa5d63f7a1bdbe252d20c2bf926 100644 (file)
@@ -655,7 +655,6 @@ void net_bh(void)
         
                else
                        kfree_skb(skb, FREE_WRITE);
-
                /*
                 *      Again, see if we can transmit anything now. 
                 *      [Ought to take this out judging by tests it slows
@@ -1142,8 +1141,14 @@ static int dev_ifsioc(void *arg, unsigned int getset)
                         
                        if(ifr.ifr_mtu<68)
                                return -EINVAL;
-                       dev->mtu = ifr.ifr_mtu;
-                       ret = 0;
+
+                        if (dev->change_mtu)
+                               ret = (*dev->change_mtu)(dev, ifr.ifr_mtu);
+                        else
+                        {
+                               dev->mtu = ifr.ifr_mtu;
+                               ret = 0;
+                       }
                        break;
        
                case SIOCGIFMEM:        /* Get the per device memory space. We can add this but currently
@@ -1301,6 +1306,8 @@ extern int lance_init(void);
 extern int ni65_init(void);
 extern int pi_init(void);
 extern int dec21040_init(void);
+extern void sdla_setup(void);
+extern void dlci_setup(void);
 
 int net_dev_init(void)
 {
@@ -1332,6 +1339,12 @@ int net_dev_init(void)
 #if defined(CONFIG_DEC_ELCP)
        dec21040_init();
 #endif 
+#if defined(CONFIG_DLCI)
+        dlci_setup();
+#endif
+#if defined(CONFIG_SDLA)
+        sdla_setup();
+#endif
        /*
         *      SLHC if present needs attaching so other people see it
         *      even if not opened.
index 5ed5c841be591d39e1b81b69717cb17dcc7149e0..812d3586439965cda3a68f0886a796ca1659668f 100644 (file)
@@ -30,3 +30,8 @@ make_EII_client(void)
        return proto;
 }
 
+void destroy_EII_client(struct datalink_proto *dl)
+{
+       if (dl)
+               kfree_s(dl, sizeof(struct datalink_proto));
+}
index be359c2c4c703e949cb2e6bba836d43c7133fe6a..66a64e0fcfe4ed1e282945f4a79178424abd83c4 100644 (file)
@@ -21,6 +21,9 @@ fi
 if [ "$CONFIG_NET_ALIAS" = "y" ]; then
        tristate 'IP: aliasing support' CONFIG_IP_ALIAS
 fi
+if [ "$CONFIG_KERNELD" = "y" ]; then
+       bool 'IP: ARP daemon support (experimental)' CONFIG_ARPD
+fi
 comment '(it is safe to leave these untouched)'
 bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP
 tristate 'IP: Reverse ARP' CONFIG_INET_RARP
index c0ee24fc614b98388137ae859f74b7cf412d67fd..b14563efe0639d03079355ad2a099c1614d9b715 100644 (file)
@@ -1463,7 +1463,7 @@ void inet_proto_init(struct net_proto *pro)
        int i;
 
 
-       printk("Swansea University Computer Society TCP/IP for NET3.033\n");
+       printk("Swansea University Computer Society TCP/IP for NET3.034\n");
 
        /*
         *      Tell SOCKET that we are alive... 
index 0a6ee986dda2cd7136e58dffb29c26944e8aca7e..cbd42960417c8959f95d05e96597180c9d643c3c 100644 (file)
@@ -18,7 +18,6 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
- *
  * Fixes:
  *             Alan Cox        :       Removed the ethernet assumptions in Florian's code
  *             Alan Cox        :       Fixed some small errors in the ARP logic
@@ -53,6 +52,8 @@
  *             Eckes           :       ARP ioctl control errors.
  *             Alexey Kuznetsov:       Arp free fix.
  *             Manuel Rodriguez:       Gratutious ARP.
+ *              Jonathan Layes  :       Added arpd support through kerneld 
+ *                                      message queue (960314)
  */
 
 /* RFC1122 Status:
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/errno.h>
-#include <linux/if_arp.h>
 #include <linux/in.h>
 #include <linux/mm.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_arp.h>
 #include <linux/trdevice.h>
 #include <linux/skbuff.h>
 #include <linux/proc_fs.h>
 #ifdef CONFIG_NET_ALIAS
 #include <linux/net_alias.h>
 #endif
+#ifdef CONFIG_ARPD
+#include <linux/kerneld.h>
+#endif /* CONFIG_ARPD */
 
 #include <asm/system.h>
 #include <asm/segment.h>
@@ -189,6 +193,14 @@ static unsigned int arp_bh_mask;
 
 static struct arp_table *arp_backlog;
 
+/* If we have arpd configured, assume that we will be running arpd and keep
+   the internal cache small */
+#ifdef CONFIG_ARPD
+#define ARP_MAXSIZE    256
+#endif /* CONFIG_ARPD */
+
+static unsigned int arp_size = 0;
+
 static void arp_run_bh(void);
 static void arp_check_expire (unsigned long);  
 
@@ -340,6 +352,7 @@ static void arp_free_entry(struct arp_table *entry)
        restore_flags(flags);
 
        kfree_s(entry, sizeof(struct arp_table));
+       --arp_size;
        return;
 }
 
@@ -368,6 +381,179 @@ static __inline__ int arp_count_hhs(struct arp_table * entry)
        return count;
 }
 
+
+/*
+ *     Force the expiry of an entry in the internal cache so the memory
+ *     can be used for a new request or for loading a query from arpd.
+ *     I'm not really sure what the best algorithm should be, so I just
+ *     search for the oldest.  NOTE:  make sure the cache is locked before
+ *      jumping into this function!  If someone wants to do something
+ *     other than searching the whole cache, by all means do so!
+ */
+
+#ifdef CONFIG_ARPD
+static int arp_force_expire(void)
+{
+       int i;
+       struct arp_table *entry = NULL;
+       struct arp_table **pentry = NULL;
+       struct arp_table **oldest_entry = NULL, **last_resort = NULL;
+       unsigned long oldest_used = ~0;
+
+#if RT_CACHE_DEBUG >= 2
+       printk("Looking for something to force expire.\n");
+#endif
+       for (i = 0; i < ARP_TABLE_SIZE; i++)
+       {
+               pentry = &arp_tables[i];
+
+               while ((entry = *pentry) != NULL)
+               {
+                       if (entry->last_used < oldest_used)
+                       {
+                               if (arp_count_hhs(entry) == 0)
+                               {
+                                       oldest_entry = pentry;
+                               }
+                               last_resort = pentry;
+                               oldest_used = entry->last_used;
+                       }
+                       pentry = &entry->next;  /* go to next entry */
+               }
+       }
+       if (oldest_entry == NULL)
+       {
+               if (last_resort == NULL)
+                       return -1;
+               oldest_entry = last_resort;
+       }
+               
+       entry = *oldest_entry;
+       *oldest_entry = (*oldest_entry)->next;
+#if RT_CACHE_DEBUG >= 2
+       printk("Force expiring %08x\n", entry->ip);
+#endif
+       arp_free_entry(entry);
+       return 0;
+}
+#endif /* CONFIG_ARPD */
+
+
+static void arpd_update(struct arp_table * entry, int loc)
+{
+#ifdef CONFIG_ARPD
+       static struct arpd_request arpreq;
+
+       arpreq.req = ARPD_UPDATE;
+       arpreq.ip = entry->ip;
+       arpreq.mask = entry->mask;
+       memcpy (arpreq.ha, entry->ha, MAX_ADDR_LEN);
+       arpreq.loc = loc;
+       arpreq.last_used = entry->last_used;
+       arpreq.last_updated = entry->last_updated;
+       arpreq.flags = entry->flags;
+       arpreq.dev = entry->dev;
+
+       kerneld_send(KERNELD_ARP, 0, sizeof(arpreq),
+                               (char *) &arpreq, NULL);
+#endif /* CONFIG_ARPD */
+}
+
+/* 
+ * Allocate memory for a new entry.  If we are at the maximum limit
+ * of the internal ARP cache, arp_force_expire() an entry.  NOTE:  
+ * arp_force_expire() needs the cache to be locked, so therefore
+ * arp_add_entry() should only be called with the cache locked too!
+ */
+
+static struct arp_table * arp_add_entry(void)
+{
+       struct arp_table * entry;
+
+#ifdef CONFIG_ARPD
+       if (arp_size >= ARP_MAXSIZE)
+       {
+               if (arp_force_expire() < 0)
+                       return NULL;
+       }
+#endif /* CONFIG_ARPD */
+
+       entry = (struct arp_table *)
+               kmalloc(sizeof(struct arp_table),GFP_ATOMIC);
+
+       if (entry != NULL)
+               ++arp_size;
+       return entry;
+}
+
+
+/*
+ * Lookup ARP entry by (addr, dev) pair in the arpd.
+ */
+
+static struct arp_table * arpd_lookup(u32 addr, unsigned short flags, 
+                                               struct device * dev,
+                                               int loc)
+{
+#ifdef CONFIG_ARPD
+       static struct arpd_request arpreq, retreq;
+       struct arp_table * entry;
+       int rv, i;
+
+       arpreq.req = ARPD_LOOKUP;
+       arpreq.ip = addr;
+       arpreq.loc = loc;
+
+       rv = kerneld_send(KERNELD_ARP, 
+                       sizeof(retreq) | KERNELD_WAIT,
+                       sizeof(arpreq),
+                       (char *) &arpreq,
+                       (char *) &retreq);
+       /* don't worry about rv != 0 too much, it's probably
+          because arpd isn't running or an entry couldn't
+          be found */
+
+       if (rv != 0)
+               return NULL;
+       if (dev != retreq.dev)
+               return NULL;
+       if (! memcmp (retreq.ha, "\0\0\0\0\0\0", 6))
+               return NULL;
+
+       arp_fast_lock();
+       entry = arp_add_entry();
+       arp_unlock();
+
+       if (entry == NULL)
+               return NULL;
+
+       entry->next = NULL;
+       entry->last_used = retreq.last_used;
+       entry->last_updated = retreq.last_updated;
+       entry->flags = retreq.flags;
+       entry->ip = retreq.ip;
+       entry->mask = retreq.mask;
+       memcpy (entry->ha, retreq.ha, MAX_ADDR_LEN);
+       arpreq.dev = entry->dev;
+
+       skb_queue_head_init(&entry->skb);
+       entry->hh = NULL;
+       entry->retries = 0;
+
+#if RT_CACHE_DEBUG >= 2
+       printk("Inserting arpd entry %08x\n in local cache.", entry->ip);
+#endif
+       i = HASH(entry->ip);
+       arp_fast_lock();
+       entry->next = arp_tables[i]->next;
+       arp_tables[i]->next = entry;
+       arp_unlock();
+       return entry;
+#endif /* CONFIG_ARPD */
+       return NULL;
+}
+
+
 /*
  * Invalidate all hh's, so that higher level will not try to use it.
  */
@@ -1015,6 +1201,7 @@ gratuitous:
                if (!(entry->flags & ATF_PERM)) {
                        memcpy(entry->ha, sha, dev->addr_len);
                        entry->last_updated = jiffies;
+                       arpd_update(entry, __LINE__);
                }
                if (!(entry->flags & ATF_COM))
                {
@@ -1042,11 +1229,13 @@ gratuitous:
                if (grat) 
                        goto end;
 
-               entry = (struct arp_table *)kmalloc(sizeof(struct arp_table),GFP_ATOMIC);
+                entry = arp_add_entry();
                if(entry == NULL)
                {
                        arp_unlock();
+#if RT_CACHE_DEBUG >= 2
                        printk("ARP: no memory for new arp entry\n");
+#endif
                        kfree_skb(skb, FREE_READ);
                        return 0;
                }
@@ -1060,6 +1249,7 @@ gratuitous:
                entry->timer.data = (unsigned long)entry;
                memcpy(entry->ha, sha, dev->addr_len);
                entry->last_updated = entry->last_used = jiffies;
+               arpd_update(entry, __LINE__);
 /*
  *     make entry point to     'correct' device
  */
@@ -1077,7 +1267,7 @@ gratuitous:
                }
                else
                {
-#if RT_CACHE_DEBUG >= 1
+#if RT_CACHE_DEBUG >= 2
                        printk("arp_rcv: %08x backlogged\n", entry->ip);
 #endif
                        arp_enqueue(&arp_backlog, entry);
@@ -1142,6 +1332,8 @@ int arp_query(unsigned char *haddr, u32 paddr, struct device * dev)
        arp_fast_lock();
 
        entry = arp_lookup(paddr, 0, dev);
+       if (entry == NULL)
+               entry = arpd_lookup(paddr, 0, dev, __LINE__);
 
        if (entry != NULL)
        {
@@ -1149,10 +1341,12 @@ int arp_query(unsigned char *haddr, u32 paddr, struct device * dev)
                if (entry->flags & ATF_COM)
                {
                        memcpy(haddr, entry->ha, dev->addr_len);
+                       arpd_update(entry, __LINE__);
                        arp_unlock();
                        return 1;
                }
        }
+       arpd_update(entry, __LINE__);
        arp_unlock();
        return 0;
 }
@@ -1218,6 +1412,8 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev,
         *      Find an entry
         */
        entry = arp_lookup(paddr, 0, dev);
+       if (entry == NULL)
+               entry = arpd_lookup(paddr, 0, dev, __LINE__);
 
        if (entry != NULL)      /* It exists */
        {
@@ -1267,6 +1463,7 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev,
                
                entry->last_used = jiffies;
                memcpy(haddr, entry->ha, dev->addr_len);
+               arpd_update(entry, __LINE__);
                if (skb)
                        skb->arp = 1;
                arp_unlock();
@@ -1277,8 +1474,7 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev,
         *      Create a new unresolved entry.
         */
        
-       entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
-                                       GFP_ATOMIC);
+       entry = arp_add_entry();
        if (entry != NULL)
        {
                entry->last_updated = entry->last_used = jiffies;
@@ -1288,6 +1484,7 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev,
                memset(entry->ha, 0, dev->addr_len);
                entry->dev = dev;
                entry->hh    = NULL;
+               arpd_update(entry, __LINE__);
                init_timer(&entry->timer);
                entry->timer.function = arp_expire_request;
                entry->timer.data = (unsigned long)entry;
@@ -1307,7 +1504,7 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev,
                }
                else
                {
-#if RT_CACHE_DEBUG >= 1
+#if RT_CACHE_DEBUG >= 2
                        printk("arp_find: %08x backlogged\n", entry->ip);
 #endif
                        arp_enqueue(&arp_backlog, entry);
@@ -1457,6 +1654,8 @@ int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short ht
        arp_fast_lock();
 
        entry = arp_lookup(paddr, 0, dev);
+       if (entry == NULL)
+               entry = arpd_lookup(paddr, 0, dev, __LINE__);
 
        if (entry)
        {
@@ -1498,6 +1697,7 @@ int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short ht
                hh->hh_refcnt++;
                restore_flags(flags);
                entry->last_used = jiffies;
+               arpd_update(entry, __LINE__);
                arp_unlock();
                return 0;
        }
@@ -1507,8 +1707,7 @@ int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short ht
         *      Create a new unresolved entry.
         */
        
-       entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
-                                       GFP_ATOMIC);
+       entry = arp_add_entry();
        if (entry == NULL)
        {
                kfree_s(hh, sizeof(struct hh_cache));
@@ -1523,6 +1722,7 @@ int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short ht
        memset(entry->ha, 0, dev->addr_len);
        entry->dev = dev;
        entry->hh = hh;
+       arpd_update(entry, __LINE__);
        ATOMIC_INCR(&hh->hh_refcnt);
        init_timer(&entry->timer);
        entry->timer.function = arp_expire_request;
@@ -1731,6 +1931,8 @@ static int arp_req_set(struct arpreq *r, struct device * dev)
         */
        
        entry = arp_lookup(ip, r->arp_flags & ~ATF_NETMASK, dev);
+       if (entry == NULL)
+               entry = arpd_lookup(ip, r->arp_flags & ~ATF_NETMASK, dev, __LINE__);
 
        if (entry)
        {
@@ -1744,8 +1946,7 @@ static int arp_req_set(struct arpreq *r, struct device * dev)
        
        if (entry == NULL)
        {
-               entry = (struct arp_table *) kmalloc(sizeof(struct arp_table),
-                                       GFP_ATOMIC);
+               entry = arp_add_entry();
                if (entry == NULL)
                {
                        arp_unlock();
@@ -1782,6 +1983,7 @@ static int arp_req_set(struct arpreq *r, struct device * dev)
                ha = dev->dev_addr;
        memcpy(entry->ha, ha, dev->addr_len);
        entry->last_updated = entry->last_used = jiffies;
+       arpd_update(entry, __LINE__);
        entry->flags = r->arp_flags | ATF_COM;
        if ((entry->flags & ATF_PUBL) && (entry->flags & ATF_NETMASK))
        {
@@ -1816,6 +2018,9 @@ static int arp_req_get(struct arpreq *r, struct device *dev)
        arp_fast_lock();
 
        entry = arp_lookup(si->sin_addr.s_addr, r->arp_flags|ATF_NETMASK, dev);
+       if (entry == NULL)
+               entry = arpd_lookup(si->sin_addr.s_addr, 
+                                       r->arp_flags|ATF_NETMASK, dev, __LINE__);
 
        if (entry == NULL)
        {
index 18339851638d21292a5904589e7750ceb4b19b25..e9507c99d12612f6d5245bda093c8581b7ae6c54 100644 (file)
 #include <net/ip_alias.h>
 
 /*
- * AF_INET alias init
+ *     AF_INET alias init
  */
-static int 
-ip_alias_init_1(struct net_alias_type *this, struct net_alias *alias, struct sockaddr *sa)
+static int ip_alias_init_1(struct net_alias_type *this, struct net_alias *alias, struct sockaddr *sa)
 {
 #ifdef ALIAS_USER_LAND_DEBUG
-  printk("alias_init(%s) called.\n", alias->name);
+       printk("alias_init(%s) called.\n", alias->name);
 #endif
-  MOD_INC_USE_COUNT;
-  return 0;
+       MOD_INC_USE_COUNT;
+       return 0;
 }
 
 /*
- * AF_INET alias done
+ *     AF_INET alias done
  */
-static int
-ip_alias_done_1(struct net_alias_type *this, struct net_alias *alias)
+static int ip_alias_done_1(struct net_alias_type *this, struct net_alias *alias)
 {
 #ifdef ALIAS_USER_LAND_DEBUG
-  printk("alias_done(%s) called.\n", alias->name);
+       printk("alias_done(%s) called.\n", alias->name);
 #endif
-  MOD_DEC_USE_COUNT;
-  return 0;
+       MOD_DEC_USE_COUNT;
+       return 0;
 }
 
 /*
- * print alias address info
+ *     Print alias address info
  */
 
-int
-ip_alias_print_1(struct net_alias_type *this, struct net_alias *alias, char *buf, int len)
+int ip_alias_print_1(struct net_alias_type *this, struct net_alias *alias, char *buf, int len)
 {
-  char *p;
+       char *p;
 
-  p = (char *) &alias->dev.pa_addr;
-  return sprintf(buf, "%d.%d.%d.%d",
-                (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
+       p = (char *) &alias->dev.pa_addr;
+       return sprintf(buf, "%d.%d.%d.%d",
+               (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
 }
 
-struct device *
-ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa)
+struct device *ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa)
 {
-  __u32 addr;
-  struct rtable *rt;
+       __u32 addr;
+       struct rtable *rt;
+       struct device *dev=NULL;
   
-  /*
-   * defensive...
-   */
+       /*
+        *      Defensive...    
+        */
   
-  if (main_dev == NULL) return NULL;
-
-  /*
-   * get u32 address. 
-   */
-
-  addr =  (sa)? (*(struct sockaddr_in *)sa).sin_addr.s_addr : 0;
-
-  if (addr == 0) return NULL;
-
-  /*
-   * find 'closest' device to address given. any other suggestions? ...
-   * net_alias module will check if returned device is main_dev's alias
-   */
-
-  rt = ip_rt_route(addr, 0);
-
-  return (rt)? rt->rt_dev : NULL;
-
+       if (main_dev == NULL) 
+               return NULL;
+
+       /*
+        *      Get u32 address. 
+        */
+
+       addr =  (sa)? (*(struct sockaddr_in *)sa).sin_addr.s_addr : 0;
+       if (addr == 0)
+               return NULL;
+
+       /*
+        *      Find 'closest' device to address given. any other suggestions? ...
+        *      net_alias module will check if returned device is main_dev's alias
+        */
+
+       rt = ip_rt_route(addr, 0);
+       if(rt)
+       {
+               dev=rt->rt_dev;
+               ip_rt_put(rt);
+       }
+       return dev;
 }
 
 /*
@@ -114,16 +117,16 @@ ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct
 
 struct net_alias_type ip_alias_type =
 {
-  AF_INET,                     /* type */
-  0,                           /* n_attach */
-  "ip",                                /* name */
-  NULL,                                /* get_addr32() */
-  NULL,                                /* dev_addr_chk() */
-  ip_alias_dev_select,         /* dev_select() */
-  ip_alias_init_1,             /* alias_init_1() */
-  ip_alias_done_1,             /* alias_done_1() */
-  ip_alias_print_1,            /* alias_print_1() */
-  NULL                         /* next */
+       AF_INET,                /* type */
+       0,                      /* n_attach */
+       "ip",                   /* name */
+       NULL,                   /* get_addr32() */
+       NULL,                   /* dev_addr_chk() */
+       ip_alias_dev_select,    /* dev_select() */
+       ip_alias_init_1,        /* alias_init_1() */
+       ip_alias_done_1,        /* alias_done_1() */
+       ip_alias_print_1,       /* alias_print_1() */
+       NULL                    /* next */
 };
 
 /*
@@ -132,7 +135,7 @@ struct net_alias_type ip_alias_type =
 
 int ip_alias_init(void)
 {
-  return register_net_alias_type(&ip_alias_type, AF_INET);
+       return register_net_alias_type(&ip_alias_type, AF_INET);
 }
 
 /*
@@ -141,22 +144,22 @@ int ip_alias_init(void)
 
 int ip_alias_done(void)
 {
-  return unregister_net_alias_type(&ip_alias_type);
+       return unregister_net_alias_type(&ip_alias_type);
 }
 
 #ifdef MODULE
 
 int init_module(void)
 {
-  if (ip_alias_init() != 0)
-    return -EIO;
-  return 0;
+       if (ip_alias_init() != 0)
+               return -EIO;
+       return 0;
 }
 
 void cleanup_module(void)
 {
-  if (ip_alias_done() != 0)
-    printk("ip_alias: can't remove module");
+       if (ip_alias_done() != 0)
+               printk("ip_alias: can't remove module");
 }
 
 #endif /* MODULE */
index 16afa1c168f7edcaeabdc559a0ff9ea931c91904..ab80ea0bc2d563e0880f6f10becadb6cfb9ac46d 100644 (file)
@@ -208,9 +208,10 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag,
                 *      we calculated.
                 */
 #ifndef CONFIG_IP_NO_ICMP_REDIRECT
-               if (dev == dev2 && !((iph->saddr^iph->daddr)&dev->pa_mask) &&
-                   (rt->rt_flags&RTF_MODIFIED) && !opt->srr)
-                       icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
+               if (dev == dev2 && 
+                       !((iph->saddr^dev->pa_addr)&dev->pa_mask) &&
+                       (rt->rt_flags&RTF_MODIFIED) && !opt->srr)
+                               icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
 #endif
 #ifdef CONFIG_IP_MROUTE
        }
index 2797f3abab8e6dfc371b1775ede84391c2ece797..741c235084a3cd771e18c467a814d8359f4dc473 100644 (file)
@@ -641,7 +641,7 @@ void ip_fragment(struct sock *sk, struct sk_buff *skb, struct device *dev, int i
        if (ntohs(iph->frag_off) & IP_DF)
        {
                ip_statistics.IpFragFails++;
-               printk("ip_queue_xmit: frag needed\n");
+               NETDEBUG(printk("ip_queue_xmit: frag needed\n"));
                return;
        }
 
index 7bb3a71bed434e5e8c35d4c8560d6955e4f7d3a2..33516afee24d063806f0c2b159241c24da5ae6a7 100644 (file)
@@ -260,6 +260,17 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 
        skb_trim(skb,ntohs(iph->tot_len));
 
+       /*
+        *      Try to select closest <src,dst> alias device, if any.
+        *      net_alias_dev_rcv_sel32 returns main device if it 
+        *      fails to found other.
+        */
+
+#ifdef CONFIG_NET_ALIAS
+       if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) 
+               skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr);
+#endif
+
        if (iph->ihl > 5) 
        {
                skb->ip_summed = 0;
@@ -275,17 +286,6 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 #endif                                 
        }
        
-       /*
-        *      Try to select closest <src,dst> alias device, if any.
-        *      net_alias_dev_rcv_sel32 returns main device if it 
-        *      fails to found other.
-        */
-
-#ifdef CONFIG_NET_ALIAS
-       if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) 
-               skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr);
-#endif
-
        /*
         *      Account for the packet (even if the packet is
         *      not accepted by the firewall!).
index e0aa0a1a83eaa392b3b3f1c24a65bd3c22395814..13e61b24fee471030e6ea658ad5326a5e5be2f6a 100644 (file)
@@ -71,7 +71,8 @@ get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t of
        off_t begin=0;
   
        s_array = pro->sock_array;
-       len += sprintf(buffer, "sl  local_address rem_address   st tx_queue rx_queue tr tm->when uid\n");
+       len += sprintf(buffer, "sl  local_address rem_address   st tx_queue "
+           "rx_queue tr tm->when uid inode\n");
 /*
  *     This was very pretty but didn't work when a socket is destroyed
  *     at the wrong moment (eg a syn recv socket getting a reset), or
@@ -108,13 +109,16 @@ get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t of
                            timer_active=timer_active2;
                            timer_expires=sp->timer.expires;
                        }
-                       len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08X:%08X %02X:%08lX %08X %d %d\n",
+                       len += sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X"
+                           " %02X %08X:%08X %02X:%08lX %08X %d %d %ld\n",
                                i, src, srcp, dest, destp, sp->state, 
                                format==0?sp->write_seq-sp->rcv_ack_seq:sp->wmem_alloc, 
                                format==0?sp->acked_seq-sp->copied_seq:sp->rmem_alloc,
                                timer_active, timer_expires-jiffies, (unsigned) sp->retransmits,
                                (sp->socket&&SOCK_INODE(sp->socket))?SOCK_INODE(sp->socket)->i_uid:0,
-                               timer_active?sp->timeout:0);
+                               timer_active?sp->timeout:0,
+                               sp->socket && SOCK_INODE(sp->socket) ?
+                               SOCK_INODE(sp->socket)->i_ino : 0);
                        if (timer_active1) add_timer(&sp->retransmit_timer);
                        if (timer_active2) add_timer(&sp->timer);
                        /*
index 61af728280ad275da52518fa6ecf9be34bbfa65b..a63f7d01a3ddec5f326386ce92575f4f2c784701 100644 (file)
@@ -9,6 +9,7 @@
 
 O_TARGET := ipx.o
 O_OBJS   := af_ipx.o
+M_OBJS   := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
 
index efffa18211618f1cde93c113a0ae3e039e36b709..1da11e794e3a150f48015d950399e8a009535794 100644 (file)
  *                     Supports sendmsg/recvmsg
  *     Revision 0.33:  Internal network support, routing changes, uses a
  *                     protocol private area for ipx data.
+ *     Revision 0.34:  Module support. <Jim Freeman>
  *
  *     Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
  *     Neither Greg Page nor Caldera, Inc. admit liability nor provide 
  *     warranty for any of this software. This material is provided 
  *     "AS-IS" and at no charge.               
  */
-  
+
+#include <linux/module.h>
+
 #include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
-#include <linux/ipx.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
+#include <net/ipx.h>
+#include <linux/inet.h>
 #include <linux/route.h>
-#include <linux/skbuff.h>
 #include <net/sock.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <linux/stat.h>
 #include <linux/firewall.h>
 
-#ifdef CONFIG_IPX
+#ifdef MODULE
+static void ipx_proto_finito(void);
+#endif /* def MODULE */
+
 /* Configuration Variables */
 static unsigned char   ipxcfg_max_hops = 16;
 static char            ipxcfg_auto_select_primary = 0;
@@ -89,10 +94,10 @@ static struct datalink_proto        *pEII_datalink = NULL;
 static struct datalink_proto   *p8023_datalink = NULL;
 static struct datalink_proto   *pSNAP_datalink = NULL;
 
-static ipx_interface   *ipx_interfaces = NULL;
 static ipx_route       *ipx_routes = NULL;
-static ipx_interface   *ipx_internal_net = NULL;
+static ipx_interface   *ipx_interfaces = NULL;
 static ipx_interface   *ipx_primary_net = NULL;
+static ipx_interface   *ipx_internal_net = NULL;
 
 static int
 ipxcfg_set_auto_create(char val)
@@ -187,6 +192,7 @@ ipx_destroy_socket(ipx_socket *sk)
        }
        
        kfree_s(sk,sizeof(*sk));
+       MOD_DEC_USE_COUNT;
 }
        
 /* The following code is used to support IPX Interfaces (IPXITF).  An
@@ -194,7 +200,7 @@ ipx_destroy_socket(ipx_socket *sk)
  */
 
 static ipx_route * ipxrtr_lookup(unsigned long);
+
 static void
 ipxitf_clear_primary_net(void)
 {
@@ -324,6 +330,10 @@ ipxitf_down(ipx_interface *intrfc)
                ipx_internal_net = NULL;
 
        kfree_s(intrfc, sizeof(*intrfc));
+       /* sockets still dangling
+        * - must be closed from user space
+        */
+       return;
 }
 
 static int 
@@ -790,6 +800,7 @@ ipxitf_insert(ipx_interface *intrfc)
 
        if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
                ipx_primary_net = intrfc;
+       return;
 }
 
 static int 
@@ -1155,7 +1166,7 @@ ipxrtr_delete(long net)
 /*
  *     Route an outgoing frame from a socket.
  */
+
 static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len)
 {
        struct sk_buff *skb;
@@ -1259,7 +1270,7 @@ ipxrtr_route_skb(struct sk_buff *skb)
 /*
  *     We use a normal struct rtentry for route handling
  */
+
 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
 {
        int err;
@@ -1483,7 +1494,7 @@ static int ipx_rt_get_info(char *buffer, char **start, off_t offset,
 *            Handling for system calls applied via the various interfaces to an IPX socket object                  *
 *                                                                                                                  *
 \*******************************************************************************************************************/
+
 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        switch(cmd)
@@ -1642,6 +1653,7 @@ ipx_create(struct socket *sock, int protocol)
        sk->error_report=def_callback1;
 
        sk->zapped=1;
+       MOD_INC_USE_COUNT;
        return 0;
 }
 
@@ -1830,8 +1842,10 @@ static int ipx_socketpair(struct socket *sock1, struct socket *sock2)
 
 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
 {
-       if(newsock->data)
+       if(newsock->data) {
                kfree_s(newsock->data,sizeof(ipx_socket));
+               MOD_DEC_USE_COUNT;
+       }
        return -EOPNOTSUPP;
 }
 
@@ -2187,7 +2201,7 @@ static struct packet_type ipx_8023_packet_type =
        NULL,
        NULL,
 };
+
 static struct packet_type ipx_dix_packet_type = 
 {
        0,      /* MUTTER ntohs(ETH_P_IPX),*/
@@ -2196,7 +2210,7 @@ static struct packet_type ipx_dix_packet_type =
        NULL,
        NULL,
 };
+
 static struct notifier_block ipx_dev_notifier={
        ipxitf_device_event,
        NULL,
@@ -2206,12 +2220,30 @@ static struct notifier_block ipx_dev_notifier={
 
 extern struct datalink_proto   *make_EII_client(void);
 extern struct datalink_proto   *make_8023_client(void);
+extern void    destroy_EII_client(struct datalink_proto *);
+extern void    destroy_8023_client(struct datalink_proto *);
 
-void ipx_proto_init(struct net_proto *pro)
-{
-       unsigned char   val = 0xE0;
-       unsigned char   snapval[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
+struct proc_dir_entry ipx_procinfo = {
+       PROC_NET_IPX, 3, "ipx", S_IFREG | S_IRUGO,
+       1, 0, 0, 0, &proc_net_inode_operations, ipx_get_info
+};
 
+struct proc_dir_entry ipx_if_procinfo = {
+       PROC_NET_IPX_INTERFACE, 13, "ipx_interface", S_IFREG | S_IRUGO,
+       1, 0, 0, 0, &proc_net_inode_operations, ipx_interface_get_info
+};
+
+struct proc_dir_entry ipx_rt_procinfo = {
+       PROC_NET_IPX_ROUTE, 9, "ipx_route", S_IFREG | S_IRUGO,
+       1, 0, 0, 0, &proc_net_inode_operations, ipx_rt_get_info
+};
+
+static unsigned char   ipx_8022_type = 0xE0;
+static unsigned char   ipx_snap_id[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
+
+void
+ipx_proto_init(struct net_proto *pro)
+{
        (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
 
        pEII_datalink = make_EII_client();
@@ -2222,34 +2254,82 @@ void ipx_proto_init(struct net_proto *pro)
        ipx_8023_packet_type.type=htons(ETH_P_802_3);
        dev_add_pack(&ipx_8023_packet_type);
        
-       if ((p8022_datalink = register_8022_client(val, ipx_rcv)) == NULL)
+       if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL)
                printk("IPX: Unable to register with 802.2\n");
 
-       if ((pSNAP_datalink = register_snap_client(snapval, ipx_rcv)) == NULL)
+       if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL)
                printk("IPX: Unable to register with SNAP\n");
        
        register_netdevice_notifier(&ipx_dev_notifier);
 
-       proc_net_register(&(struct proc_dir_entry) {
-               PROC_NET_IPX, 3, "ipx",
-               S_IFREG | S_IRUGO, 1, 0, 0,
-               0, &proc_net_inode_operations,
-               ipx_get_info
-       });
-       proc_net_register(&(struct proc_dir_entry) {
-               PROC_NET_IPX_INTERFACE, 13, "ipx_interface",
-               S_IFREG | S_IRUGO, 1, 0, 0,
-               0, &proc_net_inode_operations,
-               ipx_interface_get_info
-       });
-       proc_net_register(&(struct proc_dir_entry) {
-               PROC_NET_IPX_ROUTE, 9, "ipx_route",
-               S_IFREG | S_IRUGO, 1, 0, 0,
-               0, &proc_net_inode_operations,
-               ipx_rt_get_info
-       });
+       proc_net_register(&ipx_procinfo);
+       proc_net_register(&ipx_if_procinfo);
+       proc_net_register(&ipx_rt_procinfo);
                
-       printk("Swansea University Computer Society IPX 0.33 for NET3.032\n");
+       printk("Swansea University Computer Society IPX 0.34 for NET3.034\n");
        printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
 }
-#endif
+
+#ifdef MODULE
+/* Note on MOD_{INC,DEC}_USE_COUNT:
+ *
+ * Use counts are incremented/decremented when
+ * sockets are created/deleted.
+ * 
+ * Routes are always associated with an interface, and
+ * allocs/frees will remain properly accounted for by
+ * their associated interfaces.
+ * 
+ * Ergo, before the ipx module can be removed, all IPX
+ * sockets be closed from user space. 
+ */
+
+static void
+ipx_proto_finito(void)
+{      ipx_interface   *ifc;
+
+       while (ipx_interfaces) {
+               ifc = ipx_interfaces;
+               ipx_interfaces = ifc->if_next;
+               ifc->if_next = NULL;
+               ipxitf_down(ifc);
+       }
+
+       proc_net_unregister(PROC_NET_IPX_ROUTE);
+       proc_net_unregister(PROC_NET_IPX_INTERFACE);
+       proc_net_unregister(PROC_NET_IPX);
+
+       unregister_netdevice_notifier(&ipx_dev_notifier);
+
+       unregister_snap_client(ipx_snap_id);
+       pSNAP_datalink = NULL;
+
+       unregister_8022_client(ipx_8022_type);
+       p8022_datalink = NULL;
+
+       dev_remove_pack(&ipx_8023_packet_type);
+       destroy_8023_client(p8023_datalink);
+       p8023_datalink = NULL;
+
+       dev_remove_pack(&ipx_dix_packet_type);
+       destroy_EII_client(pEII_datalink);
+       pEII_datalink = NULL;
+
+       (void) sock_unregister(ipx_proto_ops.family);
+
+       return;
+}
+
+int init_module(void)
+{
+       ipx_proto_init(NULL);
+       register_symtab(0);
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       ipx_proto_finito();
+       return;
+}
+#endif /* def MODULE */
index fc0057a2aa97715ac2877c2fb8655a8b0677351b..d527040f0344a7ee519727e18945edb4371a67ca 100644 (file)
@@ -1274,7 +1274,7 @@ static int nr_get_info(char *buffer, char **start, off_t offset, int length, int
                        ax2asc(&s->nr->user_addr));
                len += sprintf(buffer + len, "%-9s ",
                        ax2asc(&s->nr->dest_addr));
-               len += sprintf(buffer + len, "%-9s %-3s  %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %5ld %5ld\n",
+               len += sprintf(buffer + len, "%-9s %-3s  %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %5d %5d\n",
                        ax2asc(&s->nr->source_addr),
                        devname, s->nr->my_index, s->nr->my_id,
                        s->nr->your_index, s->nr->your_id,
@@ -1341,7 +1341,7 @@ void nr_proto_init(struct net_proto *pro)
 {
        sock_register(nr_proto_ops.family, &nr_proto_ops);
        register_netdevice_notifier(&nr_dev_notifier);
-       printk("G4KLX NET/ROM for Linux. Version 0.4 ALPHA for AX25.030 Linux 1.3.45\n");
+       printk("G4KLX NET/ROM for Linux. Version 0.4 ALPHA for AX25.032 Linux 1.3.77\n");
 
        nr_default.quality    = NR_DEFAULT_QUAL;
        nr_default.obs_count  = NR_DEFAULT_OBS;
index d2ae23be3ae7e024d524ea9b3b2b84977b7b4add..f8529b3fe2f0efc9bce6f2772988f5dcda85003d 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/fcntl.h>
 #include <linux/in.h>
 #include <linux/if_ether.h>    /* For the statistics structure. */
-#include <linux/if_arp.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
@@ -39,6 +38,7 @@
 #include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if_arp.h>
 #include <linux/skbuff.h>
 
 #include <net/ip.h>
diff --git a/net/netsyms.c b/net/netsyms.c
new file mode 100644 (file)
index 0000000..c781152
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ *  linux/net/netsyms.c
+ *
+ *  Symbol table for the linux networking subsystem. Moved here to
+ *  make life simpler in ksyms.c.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/in.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/firewall.h>
+#include <linux/trdevice.h>
+#include <linux/ioport.h>
+
+#ifdef CONFIG_AX25
+#include <net/ax25.h>
+#endif
+
+#ifdef CONFIG_INET
+#include <linux/ip.h>
+#include <linux/etherdevice.h>
+#include <net/protocol.h>
+#include <net/arp.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <net/tcp.h>
+#include <net/icmp.h>
+#include <net/route.h>
+#include <linux/net_alias.h>
+#endif
+
+#ifdef CONFIG_NET_ALIAS
+#include <linux/net_alias.h>
+#endif
+
+#if     defined(CONFIG_ULTRA)   ||      defined(CONFIG_WD80x3)          || \
+        defined(CONFIG_EL2)     ||      defined(CONFIG_NE2000)          || \
+        defined(CONFIG_E2100)   ||      defined(CONFIG_HPLAN_PLUS)      || \
+        defined(CONFIG_HPLAN)   ||      defined(CONFIG_AC3200)
+#include "../drivers/net/8390.h"
+#endif
+
+extern int (*rarp_ioctl_hook)(int,void*);
+
+#ifdef CONFIG_IPX_MODULE
+extern struct datalink_proto   *make_EII_client(void);
+extern struct datalink_proto   *make_8023_client(void);
+extern void destroy_EII_client(struct datalink_proto *);
+extern void destroy_8023_client(struct datalink_proto *);
+#endif
+
+
+static struct symbol_table net_syms = {
+#include <linux/symtab_begin.h>
+
+        /* Socket layer registration */
+        X(sock_register),
+        X(sock_unregister),
+
+        /* Socket layer support routines */
+       X(memcpy_fromiovec),
+       X(sock_setsockopt),
+       X(sock_getsockopt),
+       X(sock_wake_async),
+       X(sock_alloc_send_skb),
+       X(skb_recv_datagram),
+       X(skb_free_datagram),
+       X(skb_copy_datagram),
+       X(skb_copy_datagram_iovec),
+       X(datagram_select),
+
+#ifdef CONFIG_IPX_MODULE
+       X(make_8023_client),
+       X(destroy_8023_client),
+       X(make_EII_client),
+       X(destroy_EII_client),
+#endif
+
+#ifdef CONFIG_FIREWALL
+       /* Firewall registration */
+       X(register_firewall),
+       X(unregister_firewall),
+#endif
+
+#ifdef CONFIG_INET
+       /* Internet layer registration */
+       X(inet_add_protocol),
+       X(inet_del_protocol),
+       X(rarp_ioctl_hook),
+       X(init_etherdev),
+       X(ip_rt_route),
+       X(icmp_send),
+       X(ip_options_compile),
+       X(ip_rt_put),
+       X(arp_send),
+#ifdef CONFIG_IP_FORWARD
+       X(ip_forward),
+#endif
+
+#if    defined(CONFIG_ULTRA)   ||      defined(CONFIG_WD80x3)          || \
+       defined(CONFIG_EL2)     ||      defined(CONFIG_NE2000)          || \
+       defined(CONFIG_E2100)   ||      defined(CONFIG_HPLAN_PLUS)      || \
+       defined(CONFIG_HPLAN)   ||      defined(CONFIG_AC3200)
+       /* If 8390 NIC support is built in, we will need these. */
+       X(ei_open),
+       X(ei_close),
+       X(ei_debug),
+       X(ei_interrupt),
+       X(ethdev_init),
+       X(NS8390_init),
+#endif
+
+#ifdef CONFIG_NET_ALIAS
+#include <linux/net_alias.h>
+#endif
+
+#endif  /* CONFIG_INET */
+
+       /* Device callback registration */
+       X(register_netdevice_notifier),
+       X(unregister_netdevice_notifier),
+
+#ifdef CONFIG_NET_ALIAS
+       X(register_net_alias_type),
+       X(unregister_net_alias_type),
+#endif
+
+        /* support for loadable net drivers */
+#ifdef CONFIG_AX25
+       X(ax25_encapsulate),
+       X(ax25_rebuild_header),
+#endif
+#ifdef CONFIG_INET
+       X(register_netdev),
+       X(unregister_netdev),
+       X(ether_setup),
+       X(eth_type_trans),
+       X(eth_copy_and_sum),
+       X(alloc_skb),
+       X(kfree_skb),
+       X(skb_clone),
+       X(dev_alloc_skb),
+       X(dev_kfree_skb),
+       X(netif_rx),
+       X(dev_tint),
+       X(irq2dev_map),
+       X(dev_add_pack),
+       X(dev_remove_pack),
+       X(dev_get),
+       X(dev_ioctl),
+       X(dev_queue_xmit),
+       X(dev_base),
+       X(dev_close),
+       X(dev_mc_add),
+       X(arp_find),
+       X(n_tty_ioctl),
+       X(tty_register_ldisc),
+       X(kill_fasync),
+#ifdef CONFIG_FIREWALL
+       X(call_in_firewall),
+#endif
+#endif  /* CONFIG_INET */
+
+#include <linux/symtab_end.h>
+};
+
+void export_net_symbols(void)
+{
+       register_symtab(&net_syms);
+}
index 93f06ccbff96839dd687f074c234a90220020197..ea8c28f63fce4bf3955820d51ee2d50b62282e2f 100644 (file)
@@ -18,7 +18,7 @@
 #ifdef CONFIG_INET
 #include <linux/inet.h>
 #endif
-#ifdef CONFIG_IPX
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 #include <net/ipxcall.h>
 #include <net/p8022call.h>
 #endif
@@ -28,8 +28,8 @@
 #include <net/nrcall.h>
 #endif
 #endif
-#ifdef CONFIG_ATALK
-#ifndef CONFIG_IPX
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
+#if ! ( defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) )
 #include <net/p8022call.h>
 #endif
 #include <net/atalkcall.h>
@@ -48,7 +48,8 @@ struct net_proto protocols[] = {
 #ifdef CONFIG_UNIX
   { "UNIX",    unix_proto_init },                      /* Unix domain socket family    */
 #endif
-#if defined(CONFIG_IPX)||defined(CONFIG_ATALK)  
+#if defined(CONFIG_IPX)   || defined(CONFIG_IPX_MODULE) || \
+    defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
   { "802.2",   p8022_proto_init },                     /* 802.2 demultiplexor          */
   { "SNAP",    snap_proto_init },                      /* SNAP demultiplexor           */
 #endif
@@ -72,5 +73,3 @@ struct net_proto protocols[] = {
 #endif
   { NULL,      NULL            }                       /* End marker                   */
 };
-
-
index 367537a06243cd9f855d6be706028855997d0e51..50e1deee3fe16c18ffff370cbc13276c8c9eb4ec 100644 (file)
@@ -33,6 +33,7 @@
  *                                     for NetROM and future kernel nfsd type
  *                                     stuff.
  *             Alan Cox        :       sendmsg/recvmsg basics.
+ *             Tom Dyas        :       Export net symbols.
  *
  *
  *             This program is free software; you can redistribute it and/or
 #include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/firewall.h>
+#include <linux/kerneld.h>
 
 #include <net/netlink.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
 
+#ifdef CONFIG_MODULES
+extern void export_net_symbols(void);
+#endif
+
 static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
                      int whence);
 static int sock_read(struct inode *inode, struct file *file, char *buf,
@@ -255,6 +261,7 @@ struct socket *sock_alloc(void)
        sock->conn = NULL;
        sock->iconn = NULL;
        sock->next = NULL;
+       sock->file = NULL;
        sock->wait = &inode->i_wait;
        sock->inode = inode;            /* "backlink": we could use pointer arithmetic instead */
        sock->fasync_list = NULL;
@@ -302,6 +309,7 @@ void sock_release(struct socket *sock)
        if (peersock)
                sock_release_peer(peersock);
        --sockets_in_use;       /* Bookkeeping.. */
+       sock->file=NULL;
        iput(SOCK_INODE(sock));
 }
 
@@ -506,6 +514,19 @@ int sock_wake_async(struct socket *sock, int how)
  *     family, then create a fresh socket.
  */
 
+static int find_protocol_family(int family)
+{
+       register int i;
+       for (i = 0; i < NPROTO; i++)
+       {
+               if (pops[i] == NULL)
+                       continue;
+               if (pops[i]->family == family)
+                       return i;
+       }
+       return -1;
+}
+
 asmlinkage int sys_socket(int family, int type, int protocol)
 {
        int i, fd;
@@ -513,14 +534,20 @@ asmlinkage int sys_socket(int family, int type, int protocol)
        struct proto_ops *ops;
 
        /* Locate the correct protocol family. */
-       for (i = 0; i < NPROTO; ++i) 
+       i = find_protocol_family(family);
+
+#ifdef CONFIG_KERNELD
+       /* Attempt to load a protocol module if the find failed. */
+       if (i < 0)
        {
-               if (pops[i] == NULL) continue;
-               if (pops[i]->family == family) 
-                       break;
+               char module_name[30];
+               sprintf(module_name,"net-pf-%d",family);
+               request_module(module_name);
+               i = find_protocol_family(family);
        }
+#endif
 
-       if (i == NPROTO) 
+       if (i < 0)
        {
                return -EINVAL;
        }
@@ -565,6 +592,8 @@ asmlinkage int sys_socket(int family, int type, int protocol)
                return(-EINVAL);
        }
 
+       sock->file=current->files->fd[fd];
+
        return(fd);
 }
 
@@ -745,7 +774,8 @@ asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_ad
                sock_release(newsock);
                return(-EINVAL);
        }
-
+       sock->file=current->files->fd[fd];
+       
        if (upeer_sockaddr)
        {
                newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1);
@@ -1347,7 +1377,7 @@ void sock_init(void)
 {
        int i;
 
-       printk("Swansea University Computer Society NET3.033 for Linux 1.3.50\n");
+       printk("Swansea University Computer Society NET3.034 for Linux 1.3.77\n");
 
        /*
         *      Initialize all address (protocol) families. 
@@ -1383,6 +1413,14 @@ void sock_init(void)
         */
 
        proto_init();
+
+       /*
+        *      Export networking symbols to the world.
+        */
+
+#ifdef CONFIG_MODULES
+       export_net_symbols();
+#endif
 }
 
 int socket_get_info(char *buffer, char **start, off_t offset, int length)
index e8932fc0adc5418b57cb797823bcf543b693cef0..0ecfd096ce731c20a40ff0b39cb6b89e4cfa5888 100644 (file)
@@ -26,6 +26,7 @@
  *                                     Mike Shaver's work.
  *             Marty Leisner   :       Fixes to fd passing
  *             Nick Nevin      :       recvmsg bugfix.
+ *             Alan Cox        :       Started proper garbage collector
  *
  * Known differences from reference BSD that was tested:
  *
@@ -69,7 +70,7 @@
 #include <net/af_unix.h>
 #include <linux/proc_fs.h>
 
-static unix_socket *unix_socket_list=NULL;
+unix_socket *unix_socket_list=NULL;
 
 #define min(a,b)       (((a)<(b))?(a):(b))
 
@@ -745,19 +746,12 @@ static int unix_fd_copy(struct sock *sk, struct cmsghdr *cmsg, struct file **fp)
                        return -EBADF;
        }
        
-       /*
-        *      Make sure the garbage collector can cope.
-        */
-        
-       if(unix_gc_free<num)
-               return -ENOBUFS;
-       
         /* add another reference to these files */
        for(i=0; i< num; i++)
        {
                fp[i]=current->files->fd[fdp[i]];
                fp[i]->f_count++;
-               unix_gc_add(sk, fp[i]);
+               unix_inflight(fp[i]);
        }
        
        return num;
@@ -773,7 +767,7 @@ static void unix_fd_free(struct sock *sk, struct file **fp, int num)
        for(i=0;i<num;i++)
        {
                close_fp(fp[i]);
-               unix_gc_remove(fp[i]);
+               unix_notinflight(fp[i]);
        }
 }
 
@@ -851,7 +845,7 @@ static void unix_detach_fds(struct sk_buff *skb, struct cmsghdr *cmsg)
                ufp[ufn]=fp[i];
                *cmfptr++=ufn;
                FD_CLR(ufn,&current->files->close_on_exec);
-               unix_gc_remove(fp[i]);
+               unix_notinflight(fp[i]);
        }
        /*
         *      Dump those that don't
@@ -859,7 +853,7 @@ static void unix_detach_fds(struct sk_buff *skb, struct cmsghdr *cmsg)
        for(;i<fdnum;i++)
        {
                close_fp(fp[i]);
-               unix_gc_remove(fp[i]);
+               unix_notinflight(fp[i]);
        }
        kfree(skb->h.filp);
        skb->h.filp=NULL;
@@ -1265,17 +1259,19 @@ static int unix_get_info(char *buffer, char **start, off_t offset, int length, i
        int len=0;
        unix_socket *s=unix_socket_list;
        
-       len+= sprintf(buffer,"Num       RefCount Protocol Flags    Type St Path\n");
+       len+= sprintf(buffer,"Num       RefCount Protocol Flags    Type St "
+           "Inode Path\n");
        
        while(s!=NULL)
        {
-               len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X",
+               len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X %5ld",
                        s,
                        s->protinfo.af_unix.locks,
                        0,
                        s->socket->flags,
                        s->socket->type,
-                       s->socket->state);
+                       s->socket->state,
+                       s->socket->inode ? s->socket->inode->i_ino : 0);
                if(s->protinfo.af_unix.name!=NULL)
                        len+=sprintf(buffer+len, " %s\n", s->protinfo.af_unix.name);
                else
@@ -1299,7 +1295,7 @@ static int unix_get_info(char *buffer, char **start, off_t offset, int length, i
 }
 #endif
 
-static struct proto_ops unix_proto_ops = {
+struct proto_ops unix_proto_ops = {
        AF_UNIX,
        
        unix_create,
index 67d9e06c9c277e639e1de9b7c30d6c7fdb93bf30..70bf274759a74df7f8857028304e8ee51fb6c713 100644 (file)
@@ -1,13 +1,38 @@
 /*
- * NET3:       Garbage Collector For AF_UNIX sockets (STUB)
+ * NET3:       Garbage Collector For AF_UNIX sockets (STUBS)
  *
- * Authors:    
+ * Garbage Collector:
+ *     Copyright (C) Barak A. Pearlmutter.
+ *     Released under the GPL version 2 or later.
  *
- *             This program is free software; you can redistribute it and/or
- *             modify it under the terms of the GNU General Public License
- *             as published by the Free Software Foundation; either version
- *             2 of the License, or (at your option) any later version.
- * Fixes:
+ * NOTE:
+ *     We don't actually call this yet. I'm finishing some tests before I
+ *     enable it. The bold can add it in themselves.
+ *
+ * Chopped about by Alan Cox 22/3/96 to make it fit the AF_UNIX socket problem.
+ * If it doesnt work blame me, it worked when Barak sent it.
+ *
+ * Assumptions:
+ *
+ *  - object w/ a bit
+ *  - free list
+ *
+ * Current optimizations:
+ *
+ *  - explicit stack instead of recursion
+ *  - tail recurse on first born instead of immediate push/pop
+ *
+ *  Future optimizations:
+ *
+ *  - don't just push entire root set; process in place
+ *  - use linked list for internal stack
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     as published by the Free Software Foundation; either version
+ *     2 of the License, or (at your option) any later version.
+ *
+ *  Fixes:
  *
  */
  
 #include <net/tcp.h>
 #include <net/af_unix.h>
 #include <linux/proc_fs.h>
+
+/* Internal data structures and random procedures: */
+
+#define MAX_STACK 1000         /* Maximum depth of tree (about 1 page) */
+static unix_socket **stack;    /* stack of objects to mark */
+static int in_stack = 0;       /* first free entry in stack */
+
+
+extern inline unix_socket *unix_get_socket(struct file *filp)
+{
+       struct socket *s;
+       /*
+        *      Socket ?
+        */
+       if(filp->f_inode->i_mode!=S_IFSOCK)
+               return NULL;
+       s=&(filp->f_inode->u.socket_i);
+       /*
+        *      AF_UNIX ?
+        */
+       if(s->ops!=&unix_proto_ops)
+               return NULL;
+       /*
+        *      Got one.
+        */
+       return s->data; 
+}
+
+/*
+ *     Keep the number of times in flight count for the file
+ *     descriptor if it is for an AF_UNIX socket.
+ */
+void unix_inflight(struct file *fp)
+{
+       unix_socket *s=unix_get_socket(fp);
+       if(s)
+               s->protinfo.af_unix.inflight++;
+}
+
+void unix_notinflight(struct file *fp)
+{
+       unix_socket *s=unix_get_socket(fp);
+       if(s)
+               s->protinfo.af_unix.inflight--;
+}
+
+
 /*
- *     Garbage Collector Stubs
+ *     Garbage Collector Support Functions
  */
  
+extern inline void push_stack(unix_socket *x)
+{
+       if (in_stack == MAX_STACK)
+               panic("can't push onto full stack");
+       stack[in_stack++] = x;
+}
 
-int unix_gc_free=128;          /* GC slots free */
+extern inline unix_socket *pop_stack(void)
+{
+       if (in_stack == 0)
+               panic("can't pop empty gc stack");
+       return stack[--in_stack];
+}
+
+extern inline int empty_stack(void)
+{
+       return in_stack == 0;
+}
 
-void unix_gc_remove(struct file *fp)
+extern inline void maybe_mark_and_push(unix_socket *x)
 {
-       ;
+       if (x->protinfo.af_unix.marksweep&MARKED)
+               return;
+       x->protinfo.af_unix.marksweep|=MARKED;
+       push_stack(x);
 }
 
-void unix_gc_add(struct sock *sk, struct file *fp)
+
+/* The external entry point: unix_gc() */
+
+void unix_gc(void)
 {
-       ;
+       static int in_unix_gc=0;
+       unix_socket *s;
+       unix_socket *next;
+       
+       /*
+        *      Avoid a recursive GC.
+        */
+
+       if(in_unix_gc)
+               return;
+       in_unix_gc=1;
+       
+       stack=(unix_socket **)get_free_page(GFP_KERNEL);
+       
+       /*
+        *      Assume everything is now unmarked 
+        */
+
+       /* Invariant to be maintained:
+               - everything marked is either:
+               -- (a) on the stack, or
+               -- (b) has all of its children marked
+               - everything on the stack is always marked
+               - nothing is ever pushed onto the stack twice, because:
+               -- nothing previously marked is ever pushed on the stack
+        */
+
+       /*
+        *      Push root set
+        */
+
+       for(s=unix_socket_list;s!=NULL;s=s->next)
+       {
+               /*
+                *      If all instances of the descriptor are not
+                *      in flight we are in use.
+                */
+               if(s->socket && s->socket->file && s->socket->file->f_count > s->protinfo.af_unix.inflight)
+                       maybe_mark_and_push(s);
+       }
+
+       /*
+        *      Mark phase 
+        */
+
+       while (!empty_stack())
+       {
+               unix_socket *x = pop_stack();
+               unix_socket *f=NULL,*sk;
+               struct sk_buff *skb;
+tail:          
+               skb=skb_peek(&x->receive_queue);
+               
+               /*
+                *      Loop through all but first born 
+                */
+               
+               while(skb && skb != (struct sk_buff *)&x->receive_queue)
+               {
+                       /*
+                        *      Do we have file descriptors ?
+                        */
+                       if(skb->h.filp)
+                       {
+                               /*
+                                *      Process the descriptors of this socket
+                                */
+                               int nfd=*(int *)skb->h.filp;
+                               struct file **fp=(struct file **)(skb->h.filp+sizeof(int));
+                               while(nfd--)
+                               {
+                                       /*
+                                        *      Get the socket the fd matches if
+                                        *      it indeed does so
+                                        */
+                                       if((sk=unix_get_socket(*fp++))!=NULL)
+                                       {
+                                               /*
+                                                *      Remember the first, mark the
+                                                *      rest.
+                                                */
+                                               if(f==NULL)
+                                                       f=sk;
+                                               else
+                                                       maybe_mark_and_push(sk);
+                                       }
+                               }
+                       }
+                       skb=skb->next;
+               }
+               /*
+                *      Handle first born specially 
+                */
+
+               if (f) 
+               {
+                       if (!(f->protinfo.af_unix.marksweep&MARKED))
+                       {
+                               f->protinfo.af_unix.marksweep|=MARKED;
+                               x=f;
+                               f=NULL;
+                               goto tail;
+                       }
+               }
+       }
+
+       /*
+        *      Sweep phase.  NOTE: this part dominates the time complexity 
+        */
+
+       for(s=unix_socket_list;s!=NULL;s=next)
+       {
+               next=s->next;
+               if (!(s->protinfo.af_unix.marksweep&MARKED))
+               {
+                       /*
+                        *      We exist only in the passing tree of sockets
+                        *      that is no longer connected to active descriptors
+                        *      Time to die..
+                        */
+                       if(s->socket && s->socket->file)
+                               close_fp(s->socket->file);
+               }
+               else
+                       s->protinfo.af_unix.marksweep&=~MARKED; /* unmark everything for next collection */
+       }
+       
+       in_unix_gc=0;
+       
+       free_page((long)stack);
 }
index 16cb97798ceb67a00e9575280f28cda02ba75fca..f037bd04b8b531c8a12af28cb9d2ccef2d0bd29c 100644 (file)
@@ -9,7 +9,7 @@
 #
 # Please send comments / questions / bug fixes to raymondc@microsoft.com.
 #
-#              ***** IMPORTANT COMPATABILITY NOTE ****
+#              ***** IMPORTANT COMPATIBILITY NOTE ****
 # If configuration changes are made which might adversely effect 
 # Menuconfig or xconfig, please notify the respective authors so that 
 # those utilities can be updated in parallel.
@@ -39,6 +39,9 @@
 #
 # 150296 Dick Streefland (dicks@tasking.nl) - report new configuration
 # items and ask for a value even when doing a "make oldconfig"
+#
+# 200396 Tom Dyas (tdyas@eden.rutgers.edu) - when the module option is
+# chosen for an item, define the macro <option_name>_MODULE
 
 #
 # Make sure we're really running bash.
@@ -141,6 +144,7 @@ function define_bool () {
         "m")
                echo "$1=m" >>$CONFIG
                echo "#undef  $1" >>$CONFIG_H
+               echo "#define $1_MODULE 1" >>$CONFIG_H
                ;;
 
         "n")
index 8aa31eaf91897de38a660efc53625ac2a171a893..bc64da1d298fafa24b2e84b8f93ca5b71e1dbf68 100644 (file)
@@ -40,6 +40,180 @@ single_menu_mode=
 #
 set -h
 
+
+
+
+
+#
+# Load the functions used by the config.in files.
+#
+# I do this because these functions must be redefined depending
+# on whether they are being called for interactive use or for
+# saving a configuration to a file.
+#
+# Thank the heavens bash supports nesting function definitions.
+#
+load_functions () {
+
+#
+# Additional comments
+#
+function comment () {
+       comment_ctr=$[ comment_ctr + 1 ]
+       echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
+}
+
+#
+# Don't need this yet, but we don't want to puke either.
+#
+function define_bool () {
+       :       
+}
+
+#
+# Create a boolean (Yes/No) function for our current menu
+# which calls our local bool function.
+#
+function bool () {
+       eval $2=\${$2:-'n'}  x=\$$2
+
+       case $x in
+       y|m) yes='ON' no='OFF' flag="*"
+          ;;
+       n) yes='OFF' no='ON' flag=" "
+          ;;
+       esac
+
+       echo -ne "'$2' '($flag) $1' " >>MCmenu
+
+       echo -e "function $2 () { l_bool '$1' '$yes' '$no' '$2' }\n" \
+               >>MCradiolists
+}
+
+#
+# Create a tristate (Yes/No/Module) radiolist function
+# which calls our local tristate function.
+#
+# Collapses to a boolean (Yes/No) if module support is disabled.
+#
+function tristate () {
+       if [ "$CONFIG_MODULES" != "y" ]
+       then
+               bool "$1" "$2"
+       else
+               eval $2=\${$2:-'n'}  x=\$$2
+       
+               case $x in
+               y) yes='ON'  no='OFF' module='OFF' flag="*"
+               ;;
+               m) yes='OFF' no='OFF' module='ON' flag="M"
+               ;;
+               *) yes='OFF' no='ON'  module='OFF' flag=" "
+               ;;
+               esac
+       
+               echo -ne "'$2' '<$flag> $1' " >>MCmenu
+       
+               echo -e "
+               function $2 () { \
+                       l_tristate '$1' '$yes' '$no' '$module' '$2'
+               }"  >>MCradiolists
+       fi
+}
+
+#
+# Create a tristate radiolist function which is dependent on
+# another kernel configuration option.
+#
+# Quote from the original configure script:
+#
+#       If the option we depend upon is a module,
+#       then the only allowable options are M or N.  If Y, then
+#       this is a normal tristate.  This is used in cases where modules
+#       are nested, and one module requires the presence of something
+#       else in the kernel.
+#
+function dep_tristate () {
+       if [ "$CONFIG_MODULES" != "y" ]
+       then
+               bool "$1" "$2"
+       else
+               if  eval [ "_$3" != "_m" ]
+               then
+                       tristate "$1" "$2" $3
+               else
+                       mod_bool "$1" "$2"
+               fi
+       fi
+}
+
+#
+# Add a menu item which will call our local int function.
+# 
+function int () {
+       eval $2=\${$2:-"$3"} x=\$$2
+
+       echo -ne "'$2' '($x) $1' " >>MCmenu
+
+       echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' }\n" >>MCradiolists
+}
+
+#
+# Add a menu item which will call our local int function.
+# 
+function hex () {
+       eval $2=\${$2:-"$3"} x=\${$2##*[x,X]}
+
+       echo -ne "'$2' '($x) $1' " >>MCmenu
+
+       echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' }\n" >>MCradiolists
+}
+
+#
+# Add a menu item which will call our local One-of-Many choice list.
+#
+function choice () {
+       #
+       # Need to remember params cause the're gonna get reset.
+       #
+       title=$1
+       choices=$2
+       default=$3
+       current=
+
+       #
+       # Find out if one of the choices is already set.
+       # If it's not then make it the default.
+       #
+       set -- $choices
+       firstchoice=$2
+
+       while [ -n "$2" ]
+       do
+               if eval [ "_\$$2" = "_y" ]
+               then
+                       current=$1
+                       break
+               fi
+               shift ; shift
+       done
+
+       : ${current:=$default}
+
+       echo -ne "'$firstchoice' '($current) $title' " >>MCmenu
+
+       echo -e "
+       function $firstchoice () {
+               l_choice '$title' \"$choices\" $current
+       }\n" >>MCradiolists
+}
+
+} # END load_functions()
+
+
+
+
+
 #
 # Extract available help for an option from Configure.help
 # and send it to standard output.
@@ -107,21 +281,6 @@ function menu_name () {
        >MCradiolists
 }
 
-#
-# Additional comments
-#
-function comment () {
-       comment_ctr=$[ comment_ctr + 1 ]
-       echo -ne "': $comment_ctr' '--- $1' " >>MCmenu
-}
-
-#
-# Don't need this yet, but we don't want to puke either.
-#
-function define_bool () {
-       :       
-}
-
 #
 # Add a submenu option to the menu currently under construction.
 #
@@ -146,27 +305,6 @@ function l_soundcfg () {
        $MAKE -C drivers/sound config
 }
 
-
-#
-# Create a boolean (Yes/No) function for our current menu
-# which calls our local bool function.
-#
-function bool () {
-       eval $2=\${$2:-'n'}  x=\$$2
-
-       case $x in
-       y|m) yes='ON' no='OFF' flag="*"
-          ;;
-       n) yes='OFF' no='ON' flag=" "
-          ;;
-       esac
-
-       echo -ne "'$2' '($flag) $1' " >>MCmenu
-
-       echo -e "function $2 () { l_bool '$1' '$yes' '$no' '$2' }\n" \
-               >>MCradiolists
-}
-
 #
 # Handle a boolean (Yes/No) option.
 #
@@ -202,7 +340,7 @@ function mod_bool () {
           ;;
        esac
 
-       echo -ne "'$2' '($flag) $1' " >>MCmenu
+       echo -ne "'$2' '<$flag> $1' " >>MCmenu
 
        echo -e "function $2 () { l_mod_bool '$1' '$module' '$no' '$2' }\n" \
                >>MCradiolists
@@ -231,37 +369,6 @@ function l_mod_bool() {
        done
 }
 
-#
-# Create a tristate (Yes/No/Module) radiolist function
-# which calls our local tristate function.
-#
-# Collapses to a boolean (Yes/No) if module support is disabled.
-#
-function tristate () {
-       if [ "$CONFIG_MODULES" != "y" ]
-       then
-               bool "$1" "$2"
-       else
-               eval $2=\${$2:-'n'}  x=\$$2
-       
-               case $x in
-               y) yes='ON'  no='OFF' module='OFF' flag="*"
-               ;;
-               m) yes='OFF' no='OFF' module='ON' flag="M"
-               ;;
-               *) yes='OFF' no='ON'  module='OFF' flag=" "
-               ;;
-               esac
-       
-               echo -ne "'$2' '($flag) $1' " >>MCmenu
-       
-               echo -e "
-               function $2 () { \
-                       l_tristate '$1' '$yes' '$no' '$module' '$2'
-               }"  >>MCradiolists
-       fi
-}
-
 #
 # Handle a tristate (Yes/No/Module) option.
 #
@@ -285,43 +392,6 @@ function l_tristate () {
        done
 }
 
-#
-# Create a tristate radiolist function which is dependent on
-# another kernel configuration option.
-#
-# Quote from the original configure script:
-#
-#       If the option we depend upon is a module,
-#       then the only allowable options are M or N.  If Y, then
-#       this is a normal tristate.  This is used in cases where modules
-#       are nested, and one module requires the presence of something
-#       else in the kernel.
-#
-function dep_tristate () {
-       if [ "$CONFIG_MODULES" != "y" ]
-       then
-               bool "$1" "$2"
-       else
-               if  eval [ "_$3" != "_m" ]
-               then
-                       tristate "$1" "$2" $3
-               else
-                       mod_bool "$1" "$2"
-               fi
-       fi
-}
-
-#
-# Add a menu item which will call our local int function.
-# 
-function int () {
-       eval $2=\${$2:-"$3"} x=\$$2
-
-       echo -ne "'$2' '($x) $1' " >>MCmenu
-
-       echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' }\n" >>MCradiolists
-}
-
 #
 # Create a dialog for entering an integer into a kernel option.
 #
@@ -354,18 +424,6 @@ function l_int () {
        done
 }
 
-
-#
-# Add a menu item which will call our local int function.
-# 
-function hex () {
-       eval $2=\${$2:-"$3"} x=\${$2##*[x,X]}
-
-       echo -ne "'$2' '($x) $1' " >>MCmenu
-
-       echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' }\n" >>MCradiolists
-}
-
 #
 # Create a dialog for entering a hexidecimal into a kernel option.
 #
@@ -400,45 +458,8 @@ function l_hex () {
 }
 
 #
-# Add a menu item which will call our local One-of-Many choice list.
+# Handle a on-of-many choice list.
 #
-function choice () {
-       #
-       # Need to remember params cause the're gonna get reset.
-       #
-       title=$1
-       choices=$2
-       default=$3
-       current=
-
-       #
-       # Find out if one of the choices is already set.
-       # If it's not then make it the default.
-       #
-       set -- $choices
-       firstchoice=$2
-
-       while [ -n "$2" ]
-       do
-               if eval [ "_\$$2" = "_y" ]
-               then
-                       current=$1
-                       break
-               fi
-               shift ; shift
-       done
-
-       : ${current:=$default}
-
-       echo -ne "'$firstchoice' '($current) $title' " >>MCmenu
-
-       echo -e "
-       function $firstchoice () {
-               l_choice '$title' \"$choices\" $current
-       }\n" >>MCradiolists
-}
-
-
 function l_choice () {
        #
        # Need to remember params cause the're gonna get reset.
@@ -590,7 +611,6 @@ function parse_config_files () {
        echo 'default=$1' >>MCmenu0
        echo "menu_name 'Main Menu'" >>MCmenu0
 
-
        if [ "_$single_menu_mode" = "_TRUE" ]
        then
                parser2
@@ -598,6 +618,10 @@ function parse_config_files () {
                parser1
        fi
 
+       echo "comment ''"       >>MCmenu0
+       echo "g_alt_config"     >>MCmenu0
+       echo "s_alt_config"     >>MCmenu0
+
        echo "}" >>MCmenu0
 
        #
@@ -644,7 +668,8 @@ function activate_menu () {
                        default="${selection%% *}"
 
                        case "$selection" in
-                       *"-->"*) show_readme ;;
+                       *"-->"*|\
+                       *"alt_config"*) show_readme ;;
                        *)       eval help $selection ;;
                        esac
                        ;;
@@ -655,17 +680,156 @@ function activate_menu () {
        done
 }
 
+#
+# Create a menu item to load an alternate configuration file.
+#
+g_alt_config () {
+       echo -n "get_alt_config 'Load  an Alternate Configuration File' "\
+               >>MCmenu
+}
+
+#
+# Get alternate config file name and load the 
+# configuration from it.
+#
+get_alt_config () {
+       while true
+       do
+               ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}"
+
+               $DIALOG --backtitle "$backtitle" \
+                       --inputbox "\
+Enter the name of the configuration file you wish to load.  \
+Accept the name shown to restore the configuration you \
+last retrieved.  Leave blank to abort."\
+                       11 55 "$ALT_CONFIG" 2>MCdialog.out
+
+               if [ "$?" = "0" ]
+               then
+                       ALT_CONFIG=`cat MCdialog.out`
+
+                       [ "_" = "_$ALT_CONFIG" ] && break
+
+                       if [ -r "$ALT_CONFIG" ]
+                       then
+                               load_config_file "$ALT_CONFIG"
+                               break
+                       else
+                               echo -ne "\007"
+                               $DIALOG --backtitle "$backtitle" \
+                                       --infobox "File does not exit!"  3 38
+                               sleep 2
+                       fi
+               else
+                       cat <<EOM >help.out
+
+For various reasons, one may wish to keep several different kernel
+configurations available on a single machine.  
+
+If you have saved a previous configuration in a file other than the
+kernel's default, entering the name of the file here will allow you
+to modify that configuration.
+
+If you are uncertain, then you have probably never used alternate 
+configuration files.  You should therefor leave this blank to abort.
+
+EOM
+                       $DIALOG --backtitle "$backtitle"\
+                               --title "Load Alternate Configuration"\
+                               --textbox help.out $LINES $COLS
+               fi
+       done
+
+       rm -f help.out MCdialog.out
+}
+
+#
+# Create a menu item to store an alternate config file.
+#
+s_alt_config () {
+       echo -n "save_alt_config 'Store an Alternate Configuration File' "\
+                >>MCmenu
+}
+
+#
+# Get an alternate config file name and save the current
+# configuration to it.
+#
+save_alt_config () {
+       while true
+       do
+               $DIALOG --backtitle "$backtitle" \
+                       --inputbox "\
+Enter a filename to which this configuration should be saved \
+as an alternate.  Leave blank to abort."\
+                       10 55 "$ALT_CONFIG" 2>MCdialog.out
+
+               if [ "$?" = "0" ]
+               then
+                       ALT_CONFIG=`cat MCdialog.out`
+
+                       [ "_" = "_$ALT_CONFIG" ] && break
+                       
+                       if touch $ALT_CONFIG 2>/dev/null
+                       then
+                               save_configuration $ALT_CONFIG
+                               load_functions  ## RELOAD
+                               break
+                       else
+                               echo -ne "\007"
+                               $DIALOG --backtitle "$backtitle" \
+                                       --infobox "Can't create file!  Probably a nonexistent directory." 3 60
+                               sleep 2
+                       fi
+               else
+                       cat <<EOM >help.out
+
+For various reasons, one may wish to keep different kernel
+configurations available on a single machine.  
+
+Entering a file name here will allow you to later retrieve, modify
+and use the current configuration as an alternate to whatever 
+configuration options you have selected at that time.
+
+If you are uncertain what all this means then you should probably
+leave this blank.
+EOM
+                       $DIALOG --backtitle "$backtitle"\
+                               --title "Store Alternate Configuration"\
+                               --textbox help.out $LINES $COLS
+               fi
+       done
+
+       rm -f help.out MCdialog.out
+}
+
+#
+# Load config options from a file.
+# Converts all "# OPTION is not set" lines to "OPTION=" lines
+#
+function load_config_file () {
+       awk '
+         /# .* is not set.*/ { printf("%s=\n", $2) }
+       ! /# .* is not set.*/ { print }
+       ' $1 >.tmpconfig
+
+       source .tmpconfig
+       rm -f .tmpconfig
+}
+
 #
 # Just what it says.
 #
 save_configuration () {
        ${DIALOG} --backtitle "$backtitle" \
-                 --infobox "Saving your new kernel configuration..."  3 43
+                 --infobox "Saving your kernel configuration..."  3 40
 
        #
        # Now, let's redefine the configuration functions for final
        # output to the config files.
        #
+       # Nested function definitions, YIPEE!
+       #
        function bool () {
                eval define_bool "$2" "\${$2:-n}"
        }
@@ -721,7 +885,7 @@ save_configuration () {
                        ;;
 
                n)
-                       echo "# $1 is not set"  >>$CONFIG
+                       echo "# $1 is not set"  >>$CONFIG
                        echo "#undef  $1"       >>$CONFIG_H
                        ;;
                esac
@@ -787,6 +951,9 @@ save_configuration () {
                fi
        }
 
+       DEF_CONFIG="${1:-.config}"
+       DEF_CONFIG_H="include/linux/autoconf.h"
+
        CONFIG=.tmpconfig
        CONFIG_H=.tmpconfig.h
 
@@ -802,24 +969,30 @@ save_configuration () {
        
        if . $CONFIG_IN >>.menuconfig.log 2>&1
        then
-               #
-               # Create the sound driver's config files for cards
-               # Which are compatible with the new config method.
-               #
-               if [ "_$CONFIG_TRIX"   != "_y" -a\
-                    "_$CONFIG_PSS"    != "_y" -a\
-                    "_$CONFIG_SMWAVE" != "_y"    ]
+               if [ "$DEF_CONFIG" = ".config" ]
                then
-                       make -C drivers/sound kernelconfig >>.menuconfig.log 2>&1
+                       #
+                       # Create the sound driver's config files for cards
+                       # Which are compatible with the new config method.
+                       #
+                       if [ "_$CONFIG_TRIX"   != "_y" -a\
+                            "_$CONFIG_PSS"    != "_y" -a\
+                            "_$CONFIG_SMWAVE" != "_y"   ]
+                       then
+                               make -C drivers/sound kernelconfig >>.menuconfig.log 2>&1
+                       fi
+
+                       mv $CONFIG_H $DEF_CONFIG_H
                fi
 
-               if [ -f .config ]
+               if [ -f "$DEF_CONFIG" ]
                then
-                       rm -f .config.old
-                       mv .config .config.old
+                       rm -f ${DEF_CONFIG}.old
+                       mv $DEF_CONFIG ${DEF_CONFIG}.old
                fi
-               mv .tmpconfig .config
-               mv .tmpconfig.h include/linux/autoconf.h
+
+               mv $CONFIG $DEF_CONFIG
+                       
                return 0
        else
                return 1
@@ -856,18 +1029,20 @@ esac
        
 
 menu_instructions="\
-Arrow keys navigate the menu.  \
+The Arrow keys navigate the menu.  \
 Highlighted letters are hotkeys.  \
-Select an item with <Space Bar> or <Enter>.  \
-When finished press <Esc><Esc> or <X>.  \
-A (*) marks an option to be compiled into the kernel.  \
-An (M) marks an option to be compiled as a module."
+Press the <Space Bar> to select an item.  \
+Press <Esc><Esc> to exit.  \
+Press <?> for Help.  \
+(*) options will be compiled into the kernel.  \
+(M) options will be modules.  \
+< > marks module capable options."
 
 radiolist_instructions="\
 Use the arrow keys to navigate this window or \
 press the hotkey of the item you wish to select \
 followed by the <SPACE BAR>.
-Press <H> for additional information about this option."
+Press <?> for additional information about this option."
 
 inputbox_instructions_int="\
 Please enter a decimal value between 1 and 9999. \
@@ -886,15 +1061,10 @@ kernel_version="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}"
 
 trap "cleanup ; rm -f .menuconfig ; exit 1" 1 2 15
 
+
 #
 # Locate default files.
 #
-DEFAULT=""
-if [ "$1" = "-d" ] ; then
-       DEFAULT="-d"
-       shift
-fi
-
 CONFIG_IN=./config.in
 if [ "$1" != "" ] ; then
        CONFIG_IN=$1
@@ -905,7 +1075,8 @@ if [ -f .config ]; then
   DEFAULTS=.config
 fi
 
-if [ -f $DEFAULTS ]; then
+if [ -f $DEFAULTS ]
+then
   echo "#"
   echo "# Using defaults found in" $DEFAULTS
   echo "#"
@@ -916,10 +1087,10 @@ else
   echo "#"
 fi
 
+
 # Fresh new log.
 >.menuconfig.log
 
-
 $DIALOG        --backtitle "$backtitle" \
        --infobox "Preparing configuration scripts..." 3 40
 
@@ -948,6 +1119,9 @@ then
        echo "# $kernel_version" >.menuconfig
 fi
 
+# Load the functions used by the config.in files.
+load_functions
+
 #
 # Read config.in files and parse them into one shell function per menu.
 #
index bb4d36c395c962bedf162bea37bd50b480e69d79..6d880bef1092d19154a7b9db7ba33c80e4cccad5 100644 (file)
@@ -78,6 +78,22 @@ If Menuconfig quits with an error while saving your configuration,
 you may look in the file /usr/src/linux/.menuconfig.log for
 information which may help you determine the cause.
 
+Alternate Configuration Files
+-----------------------------
+Menuconfig supports the use of alternate configuration files for
+those who, for various reasons, find it necessary to switch 
+between different kernel configurations.
+
+At the end of the main menu you will find two options.  One is
+for saving the current configuration to a file of your choosing.
+The other option is for loading a previously saved alternate
+configuration.
+
+Even if you don't use alternate configuration files, but you 
+find during a Menuconfig session that you have completely messed
+up your settings, you may use the "Load Alternate..." option to
+restore your previously saved settings from ".config" without 
+restarting Menuconfig.
 
 Other information
 -----------------
index 1b5b250f492d62e5eaf62d904bf31c4fb53d1a2d..1d0200fa46814be2f1150a253b7d74d5ea346ac2 100644 (file)
@@ -27,14 +27,15 @@ unsigned char dialog_input_result[MAX_LEN + 1];
  *  Print the termination buttons
  */
 static void
-print_buttons(WINDOW *dialog, int height, int width, int okval, int cancelval)
+print_buttons(WINDOW *dialog, int height, int width, int selected)
 {
     int x = width / 2 - 11;
     int y = height - 2;
 
-    print_button (dialog, "  Ok  ", y, x, okval);
-    print_button (dialog, " Help ", y, x + 14, cancelval);
+    print_button (dialog, "  Ok  ", y, x, selected==0);
+    print_button (dialog, " Help ", y, x + 14, selected==1);
 
+    wmove(dialog, y, x+1+14*selected);
     wrefresh(dialog);
 }
 
@@ -86,7 +87,7 @@ dialog_inputbox (const char *title, const char *prompt, int height, int width,
     draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
              border_attr, dialog_attr);
 
-    print_buttons(dialog, height, width, TRUE, FALSE);
+    print_buttons(dialog, height, width, 0);
 
     /* Set up the initial value */
     wmove (dialog, box_y, box_x);
@@ -180,17 +181,17 @@ dialog_inputbox (const char *title, const char *prompt, int height, int width,
            switch (button) {
            case -1:
                button = 1;     /* Indicates "Cancel" button is selected */
-               print_buttons(dialog, height, width, FALSE, TRUE);
+               print_buttons(dialog, height, width, 1);
                break;
            case 0:
                button = -1;    /* Indicates input box is selected */
-               print_buttons(dialog, height, width, TRUE, FALSE);
+               print_buttons(dialog, height, width, 0);
                wmove (dialog, box_y, box_x + input_x);
                wrefresh (dialog);
                break;
            case 1:
                button = 0;     /* Indicates "OK" button is selected */
-               print_buttons(dialog, height, width, TRUE, FALSE);
+               print_buttons(dialog, height, width, 0);
                break;
            }
            break;
@@ -200,15 +201,15 @@ dialog_inputbox (const char *title, const char *prompt, int height, int width,
            switch (button) {
            case -1:
                button = 0;     /* Indicates "OK" button is selected */
-               print_buttons(dialog, height, width, TRUE, FALSE);
+               print_buttons(dialog, height, width, 0);
                break;
            case 0:
                button = 1;     /* Indicates "Cancel" button is selected */
-               print_buttons(dialog, height, width, FALSE, TRUE);
+               print_buttons(dialog, height, width, 1);
                break;
            case 1:
                button = -1;    /* Indicates input box is selected */
-               print_buttons(dialog, height, width, TRUE, FALSE);
+               print_buttons(dialog, height, width, 0);
                wmove (dialog, box_y, box_x + input_x);
                wrefresh (dialog);
                break;
index 915271507ad907879e166dadec687057c31401a5..0e6f1111ab4bbc8b5e099ed3bc15b7c79eb11c71 100644 (file)
@@ -220,7 +220,7 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
                        (items[(scroll+choice)*2][0] != ':'));
 
            if (key == KEY_UP || key == '-') {
-                if (choice < 6 && scroll) {
+                if (choice < 2 && scroll) {
                    /* Scroll menu down */
                     scrollok (menu, TRUE);
                     wscrl (menu, -1);
@@ -238,7 +238,9 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
                print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
                                 (items[(scroll+choice)*2][0] != ':'));
 
-                if ((choice > 4) && (scroll + max_choice < item_no)) {
+                if ((choice > max_choice-3) &&
+                    (scroll + max_choice < item_no)
+                   ) {
                    /* Scroll menu up */
                    scrollok (menu, TRUE);
                     scroll (menu);