Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Linux Kernel Patch v2.1, patch-2.2.0-pre9 (00/15)

14 views
Skip to first unread message

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part00

lines added deleted
linux/CREDITS : 14 8 0
linux/Documentation/Changes : 315 88 50
linux/Documentation/Configure.help : 104 52 8
linux/Documentation/sgi-visws.txt : 13 13 0
linux/MAINTAINERS : 13 7 0
linux/Makefile : 8 1 1
linux/arch/alpha/kernel/osf_sys.c : 105 44 22
linux/arch/alpha/kernel/process.c : 13 1 5
linux/arch/alpha/kernel/time.c : 62 19 8
linux/arch/arm/kernel/time.c : 23 6 4
linux/arch/i386/config.in : 17 11 0
linux/arch/i386/defconfig : 9 3 0
linux/arch/i386/kernel/Makefile : 16 9 1
linux/arch/i386/kernel/bios32.c : 19 5 1
linux/arch/i386/kernel/entry.S : 8 1 1
linux/arch/i386/kernel/i386_ksyms.c : 7 1 0
linux/arch/i386/kernel/irq.c : 477 223 128
linux/arch/i386/kernel/irq.h : 42 7 7
linux/arch/i386/kernel/process.c : 21 15 0
linux/arch/i386/kernel/setup.c : 151 131 0
linux/arch/i386/kernel/smp.c : 92 22 2
linux/arch/i386/kernel/time.c : 87 35 7
linux/arch/i386/kernel/traps.c : 135 105 3
linux/arch/i386/kernel/visws_apic.c : 407 407 0
linux/arch/m68k/Makefile : 21 9 2
linux/arch/m68k/amiga/config.c : 15 0 2
linux/arch/m68k/atari/atakeyb.c : 8 0 5
linux/arch/m68k/atari/config.c : 15 0 2
linux/arch/m68k/config.in : 50 11 10
linux/arch/m68k/defconfig : 86 28 4
linux/arch/m68k/fpsp040/skeleton.S : 23 4 3
linux/arch/m68k/hp300/config.c : 19 0 6
linux/arch/m68k/ifpsp060/iskeleton.S : 23 4 3
linux/arch/m68k/kernel/entry.S : 287 53 48
linux/arch/m68k/kernel/head.S : 4275 3002 889
linux/arch/m68k/kernel/m68k_defs.c : 81 67 3
linux/arch/m68k/kernel/m68k_ksyms.c : 33 5 3
linux/arch/m68k/kernel/process.c : 109 56 13
linux/arch/m68k/kernel/ptrace.c : 18 6 3
linux/arch/m68k/kernel/setup.c : 36 4 4
linux/arch/m68k/kernel/sys_m68k.c : 133 37 48
linux/arch/m68k/kernel/time.c : 92 33 16
linux/arch/m68k/mac/config.c : 36 1 8
linux/arch/m68k/mac/debug.c : 8 1 1
linux/arch/m68k/mac/mackeyb.c : 8 0 5
linux/arch/m68k/mm/init.c : 406 127 160
linux/arch/m68k/mm/kmap.c : 801 239 457
linux/arch/m68k/mm/memory.c : 191 27 109
linux/arch/mips/kernel/time.c : 63 21 8
linux/arch/ppc/kernel/time.c : 21 8 0
linux/arch/sparc/kernel/time.c : 61 22 8
linux/arch/sparc/mm/srmmu.c : 44 5 5
linux/arch/sparc64/kernel/time.c : 29 9 7
linux/drivers/block/ide-cd.c : 70 28 5
linux/drivers/block/ide-cd.h : 82 39 9
linux/drivers/cdrom/mcdx.h : 7 0 1
linux/drivers/char/console.c : 17 3 1
linux/drivers/char/cyclades.c : 108 19 25
linux/drivers/char/mem.c : 21 1 8
linux/drivers/char/pc_keyb.c : 8 1 1
linux/drivers/char/tty_ioctl.c : 13 2 1
linux/drivers/char/videodev.c : 7 1 0
linux/drivers/isdn/isdn_common.c : 447 130 78
linux/drivers/isdn/isdn_common.h : 19 5 1
linux/drivers/isdn/isdn_net.c : 106 29 13
linux/drivers/isdn/isdn_ppp.c : 68 14 11
linux/drivers/misc/parport_ieee1284.c : 33 13 8
linux/drivers/net/3c59x.c : 8 1 1
linux/drivers/net/Config.in : 19 2 4
linux/drivers/net/at1700.c : 424 142 74
linux/drivers/net/fmv18x.c : 200 62 32
linux/drivers/net/irda/Config.in : 5 1 0
linux/drivers/net/irda/Makefile : 14 8 0
linux/drivers/net/irda/actisys.c : 78 9 9
linux/drivers/net/irda/esi.c : 72 9 10
linux/drivers/net/irda/irport.c : 401 143 100
linux/drivers/net/irda/irtty.c : 35 3 3
linux/drivers/net/irda/pc87108.c : 67 13 11
linux/drivers/net/irda/tekram.c : 59 8 6
linux/drivers/net/irda/uircc.c : 915 915 0
linux/drivers/net/tulip.c : 16 1 2
linux/drivers/pci/pci.c : 21 8 0
linux/drivers/pnp/parport_probe.c : 15 2 2
linux/drivers/scsi/aha152x.c : 7 1 0
linux/drivers/scsi/ini9100u.c : 102 31 55
linux/drivers/scsi/ini9100u.h : 7 1 0
linux/drivers/sound/ad1848.c : 8 1 1
linux/drivers/video/Config.in : 91 19 9
linux/drivers/video/Makefile : 23 5 5
linux/drivers/video/amifb.c : 65 18 6
linux/drivers/video/atafb.c : 78 10 11
linux/drivers/video/atyfb.c : 380 119 41
linux/drivers/video/clgenfb.c : 35 4 6
linux/drivers/video/creatorfb.c : 122 24 9
linux/drivers/video/cvisionppc.h : 51 51 0
linux/drivers/video/cvppcfb.c : 606 0 606
linux/drivers/video/cyberfb.c : 9 1 2
linux/drivers/video/fbcon-iplan2p2.c : 24 2 2
linux/drivers/video/fbcon-iplan2p4.c : 24 2 2
linux/drivers/video/fbcon-iplan2p8.c : 24 2 2
linux/drivers/video/fbcon.c : 107 27 13
linux/drivers/video/fbmem.c : 21 4 4
linux/drivers/video/offb.c : 11 3 1
linux/drivers/video/pm2fb.c : 1494 1494 0
linux/drivers/video/pm2fb.h : 181 181 0
linux/drivers/video/retz3fb.c : 9 1 2
linux/drivers/video/sbusfb.c : 80 11 7
linux/drivers/video/virgefb.c : 87 34 12
linux/fs/Config.in : 12 5 1
linux/fs/namei.c : 17 9 1
linux/fs/proc/array.c : 9 1 2
linux/fs/select.c : 37 31 0
linux/fs/vfat/namei.c : 9 1 1
linux/include/asm-alpha/semaphore.h : 25 4 4
linux/include/asm-i386/cobalt.h : 116 116 0
linux/include/asm-i386/fixmap.h : 30 12 3
linux/include/asm-i386/i82489.h : 25 13 0
linux/include/asm-i386/lithium.h : 40 40 0
linux/include/asm-i386/smp.h : 49 11 22
linux/include/asm-i386/string.h : 35 0 29
linux/include/asm-i386/unistd.h : 8 1 1
linux/include/asm-m68k/bootinfo.h : 27 0 14
linux/include/asm-m68k/entry.h : 161 56 63
linux/include/asm-m68k/ide.h : 8 1 1
linux/include/asm-m68k/init.h : 19 3 3
linux/include/asm-m68k/io.h : 35 29 0
linux/include/asm-m68k/keyboard.h : 12 3 3
linux/include/asm-m68k/machdep.h : 7 0 1
linux/include/asm-m68k/machw.h : 24 12 0
linux/include/asm-m68k/page.h : 17 2 2
linux/include/asm-m68k/pgtable.h : 135 12 67
linux/include/asm-m68k/processor.h : 8 2 0
linux/include/asm-m68k/semaphore.h : 96 32 5
linux/include/asm-m68k/setup.h : 80 10 8
linux/include/asm-m68k/system.h : 22 3 6
linux/include/asm-m68k/traps.h : 35 9 0
linux/include/asm-m68k/unistd.h : 57 1 43
linux/include/asm-m68k/virtconvert.h : 8 1 1
linux/include/asm-sparc64/pgtable.h : 8 1 1
linux/include/linux/fs.h : 8 1 1
linux/include/linux/isdn.h : 28 5 6
linux/include/linux/mm.h : 21 2 2
linux/include/linux/pagemap.h : 8 1 1
linux/include/linux/poll.h : 55 4 34
linux/include/linux/swap.h : 22 9 0
linux/include/linux/timex.h : 16 3 0
linux/include/net/irda/crc.h : 17 2 2
linux/include/net/irda/irda.h : 37 8 7
linux/include/net/irda/irda_device.h : 20 4 3
linux/include/net/irda/irlap_event.h : 24 3 1
linux/include/net/irda/irlpt_cli.h : 47 47 0
linux/include/net/irda/irlpt_cli_fsm.h : 34 34 0
linux/include/net/irda/irlpt_common.h : 184 184 0
linux/include/net/irda/irlpt_server.h : 42 42 0
linux/include/net/irda/irlpt_server_fsm.h : 30 30 0
linux/include/net/irda/irmod.h : 21 4 2
linux/include/net/irda/irobex.h : 67 12 11
linux/include/net/irda/irport.h : 17 2 2
linux/include/net/irda/uircc.h : 121 121 0
linux/include/net/sock.h : 16 2 1
linux/include/video/font.h : 27 0 15
linux/init/main.c : 8 1 1
linux/kernel/ksyms.c : 15 2 0
linux/kernel/sched.c : 142 38 36
linux/kernel/time.c : 287 137 86
linux/mm/filemap.c : 8 1 1
linux/mm/page_alloc.c : 58 8 8
linux/mm/swapfile.c : 15 4 4
linux/mm/vmscan.c : 74 26 23
linux/net/ipv4/ip_output.c : 97 37 6
linux/net/ipv4/tcp_input.c : 30 6 3
linux/net/ipv4/tcp_output.c : 30 6 3
linux/net/ipv4/tcp_timer.c : 16 2 1
linux/net/ipv6/af_inet6.c : 8 1 1
linux/net/irda/Config.in : 15 2 0
linux/net/irda/Makefile : 24 10 1
linux/net/irda/af_irda.c : 26 3 3
linux/net/irda/irda_device.c : 82 20 10
linux/net/irda/iriap.c : 48 6 8
linux/net/irda/irias_object.c : 14 2 2
linux/net/irda/irlan/irlan_cli.c : 43 5 7
linux/net/irda/irlan/irlan_common.c : 17 2 2
linux/net/irda/irlap.c : 320 39 78
linux/net/irda/irlap_event.c : 349 74 43
linux/net/irda/irlap_frame.c : 111 7 21
linux/net/irda/irlmp.c : 104 13 23
linux/net/irda/irlmp_event.c : 202 26 29
linux/net/irda/irlmp_frame.c : 264 68 49
linux/net/irda/irlpt/Config.in : 7 7 0
linux/net/irda/irlpt/Makefile : 48 48 0
linux/net/irda/irlpt/irlpt_cli.c : 599 599 0
linux/net/irda/irlpt/irlpt_cli_fsm.c : 374 374 0
linux/net/irda/irlpt/irlpt_common.c : 512 512 0
linux/net/irda/irlpt/irlpt_srvr.c : 545 545 0
linux/net/irda/irlpt/irlpt_srvr_fsm.c : 182 182 0
linux/net/irda/irmod.c : 102 38 2
linux/net/irda/irobex/irobex.c : 762 167 158
linux/net/irda/irproc.c : 16 1 2
linux/net/irda/irqueue.c : 41 6 6
linux/net/irda/irsysctl.c : 40 12 2
linux/net/irda/irttp.c : 73 5 15
linux/net/irda/wrapper.c : 225 49 57
linux/net/sunrpc/xprt.c : 11 1 4
linux/scripts/tkcond.c : 830 286 471
linux/scripts/tkgen.c : 1936 841 966
linux/scripts/tkparse.c : 1292 515 670
linux/scripts/tkparse.h : 174 92 62
--
Thomas Koenig, Thomas...@ciw.uni-karlsruhe.de, ig...@dkauni2.bitnet.
The joy of engineering is to find a straight line on a double
logarithmic diagram.

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part01

#!/bin/sh
# This is a shell archive
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
# existing files will NOT be overwritten unless -c is specified
#
# This is part 01 of a 15 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
#
if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= patch-2.2.0-pre9 ==============
if test -f 'patch-2.2.0-pre9' -a X"$1" != X"-c"; then
echo 'x - skipping patch-2.2.0-pre9 (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting patch-2.2.0-pre9 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'patch-2.2.0-pre9' &&
diff -u --recursive --new-file v2.2.0-pre8/linux/CREDITS linux/CREDITS
--- v2.2.0-pre8/linux/CREDITS Tue Jan 19 11:32:50 1999
+++ linux/CREDITS Tue Jan 19 10:19:31 1999
@@ -2095,6 +2095,14 @@
X S: 6525 EZ Nijmegen
X S: The Netherlands
X
+N: Ulrich Windl
+E: Ulrich...@rz.uni-regensburg.de
+P: 1024/E843660D CF D7 43 A1 5A 49 14 25 7C 04 A0 6E 4C 3A AC 6D
+D: Supports NTP on Linux. Added PPS code. Fixed bugs in adjtimex().
+S: Alte Regensburger Str. 11a
+S: 93149 Nittenau
+S: Germany
+
X N: Lars Wirzenius
X E: l...@iki.fi
X D: Linux System Administrator's Guide
diff -u --recursive --new-file v2.2.0-pre8/linux/Documentation/Changes linux/Documentation/Changes
--- v2.2.0-pre8/linux/Documentation/Changes Tue Jan 19 11:32:50 1999
+++ linux/Documentation/Changes Tue Jan 19 09:48:01 1999
@@ -2,13 +2,13 @@
X =====
X
X This document is designed to provide a list of the minimum levels of
-software necessary to run the 2.1.x kernels, as well as provide brief
+software necessary to run the 2.2 kernels, as well as provide brief
X instructions regarding any other "Gotchas" users may encounter when
X trying life on the Bleeding Edge. If upgrading from a pre-2.0.x
X kernel, please consult the Changes file included with 2.0.x kernels for
X additional information; most of that information will not be repeated
X here. Basically, this document assumes that your system is already
-functional and running at least 2.0.x.
+functional and running at least 2.0.x kernels.
X
X It is originally based on my "Changes" file for 2.0.x kernels and
X therefore owes credit to the same people as that file (Jared Mauch,
@@ -33,7 +33,7 @@
X Also, don't forget http://www.linuxhq.com/ for all your Linux kernel
X needs.
X
-Last updated: December 12, 1998
+Last updated: January 18, 1999
X Current Author: Chris Ricker (kab...@gatech.edu or chris....@m.cc.utah.edu).
X
X Current Minimal Requirements
@@ -57,12 +57,12 @@
X - Loadlin 1.6a
X - Sh-utils 1.16 ; basename --v
X - Autofs 3.1.1 ; automount --version
-- NFS 2.2beta37 ; showmount --version
+- NFS 2.2beta40 ; showmount --version
X - Bash 1.14.7 ; bash -version
X - Ncpfs 2.2.0 ; ncpmount -v
-- Pcmcia-cs 3.0.6 ; cardmgr -V
+- Pcmcia-cs 3.0.7 ; cardmgr -V
X - PPP 2.3.5 ; pppd -v
-- Util-linux 2.9 ; chsh -v
+- Util-linux 2.9g ; chsh -v
X
X Upgrade notes
X *************
@@ -81,19 +81,21 @@
X ttyS1, etc.).
X
X In addition, some software still works, but needs to be compiled
-against 2.1 headers for complete functionality. Fdutils binaries
+against 2.2 headers for complete functionality. Fdutils binaries
X compiled under 2.0 or earlier kernels should be replaced with ones
-compiled under 2.1, for example.
+compiled under 2.2, for example.
X
- As of 2.1.115, support for the deprecated major 4 /dev/ttyp* devices
-was removed. If necessary (eg, you get "out of pty" error messages when
-you obviously are not out of pty's), create major 3 /dev/tty* and major 2
-/dev/pty* devices (see Documentation/devices.txt for more information).
+ As of 2.1.115, support for the deprecated major 4 /dev/ttyp* devices
+was removed. If necessary (eg, you get "out of pty" error messages when
+you obviously are not out of pty's), create major 3 /dev/tty* and major
+2 /dev/pty* devices (see Documentation/devices.txt for more
+information). In general, you should make sure that your /dev
+directory is up-to-date if you are experiencing any problems.
X
X Optional support for Unix98 pty devices has also been added. If you
-want to use the Unix98 ptys, you should be running at least glibc-2.0.9x,
-and you must switch completely to Unix98 pty's. The general procedure
-for configuring Unix98 pty support is:
+want to use the Unix98 ptys, you should be running at least
+glibc-2.0.9x, and you must switch completely to Unix98 pty's. The
+general procedure for configuring Unix98 pty support is:
X
X - Compile your kernel with CONFIG_UNIX98_PTYS and CONFIG_DEVPTS_FS.
X - mknod /dev/ptmx c 5 2
@@ -119,7 +121,7 @@
X Libc (libc5)
X ============
X
- Linux-2.1.x is ELF-only. You can still compile a.out apps if you
+ Linux-2.2 is ELF-only. You can still compile a.out apps if you
X really want, but your kernel must be compiled ELF. If you can't
X currently compile ELF, consult the ELF howto at
X http://metalab.unc.edu/mdw/HOWTO/ELF-HOWTO.html and upgrade your system
@@ -163,8 +165,8 @@
X Modules
X =======
X
- You need to upgrade to the latest version of modutils-2.1.x for
-development kernels. This version will also work with 2.0.x kernels.
+ You need to upgrade to the latest version of modutils for the Linux
+2.2 kernel. This version will also work with your 2.0 kernel.
X
X As of 2.1.90-pre1, kerneld has been replaced by a kernel thread,
X kmod. See Documentation/kmod.txt for more information. The main
@@ -199,7 +201,7 @@
X Note that the latest compilers (egcs, pgcc, gcc 2.8) may do Bad
X Things while compiling your kernel, particularly if absurd
X optimizations (like -O9) are used. Caveat emptor. Currently, the only
-C compiler available in a binary distribution is egcs. Version 1.0.2
+C compiler available in a binary distribution is egcs. Version 1.0.3
X seems okay; if you have to have a binary, you may be successful using
X that. In general, however, gcc-2.7.2.3 is known to be stable, while
X egcs and others have not been as thoroughly tested yet.
@@ -240,7 +242,13 @@
X ipfwadm.
X
X To use masq forwarding you will need to obtain "ipmasqadm,"
-available from http://juanjox.linuxhq.com/
+available from http://juanjox.linuxhq.com/ .
+
+ DHCP clients for 2.0 do not work with the new networking code in the
+2.2 kernel. You will need to upgrade your dhcpcd / dhcpclient.
+
+ The ISDN code in the stock 2.0 kernel may not work for you. If it
+doesn't, look in ftp://ftp.suse.com/pub/isdn4linux for updated versions.
X
X Memory
X ======
@@ -261,10 +269,10 @@
X Util-linux (including mount)
X ============================
X
- Among other changes in the 2.1.x development, the 128 meg limit on
-IA32 swap partition sizes has been eliminated. To use larger swap
-spaces, you need the new mkswap found in util-linux. You also need to
-upgrade this to get the latest version of mount.
+ Among other changes made in the development of Linux kernel 2.2, the
+128 meg limit on IA32 swap partition sizes has been eliminated. To use
+larger swap spaces, you need the new mkswap found in util-linux. You
+also need to upgrade util-linux to get the latest version of mount.
X
X RPM
X ===
@@ -275,7 +283,7 @@
X DOSEMU
X ======
X
- A new "stable" version of DOSEMU is available for 2.1.x kernels.
+ A new "stable" version of DOSEMU is available for 2.2 kernels.
X Upgrade to 0.98.4 or later.
X
X Loadlin
@@ -325,6 +333,15 @@
X cause problems when compiling modules. Upgrade to at least 1.14 to fix
X this problem.
X
+Sysklogd
+========
+
+ Older versions of sysklogd sometimes segfault under 2.2 kernels.
+Upgrading to the latest release fixes that problem as well as adding
+support for new features like system power-off on halt (with
+appropriate incantations of halt; see the man page) and automatic
+decoding of kernel oopses.
+
X Ncpfs
X =====
X
@@ -335,10 +352,10 @@
X =====
X
X To mount SMB (Samba / Windows) shares, you'll need to use the
-smbmount utility included with recent Samba releases.
+smbmount utility included with release 2.0 of Samba.
X Documentation/filesystems/smbfs.txt has more information about this.
-Note that smbmount must have been built against 2.1.x headers to work
-with 2.1.x; if all else fails, recompile it and hope it works ;-). In
+Note that smbmount must have been built against 2.2 headers to work
+with 2.2; if all else fails, recompile it and hope it works ;-). In
X addition, Mike Warfield has a script and some information at
X http://www.wittsend.com/mhw/smbmount.html that you will probably find
X useful.
@@ -358,19 +375,19 @@
X iBCS
X ====
X
- A new version of iBCS is necessary for 2.1 kernels.
+ A new version of iBCS is necessary for 2.2 kernels.
X
X AppleTalk
X =========
X
X Use the Asun version of netatalk for AppleTalk support, as Umich's
-version is not compatible with 2.1 kernels.
+version is not compatible with 2.2 kernels.
X
X Psmisc
X ======
X
X fuser, which comes with psmisc, reads /proc/*/fd/* to do its job.
-Upgrade psmisc if 2.1 changes to /proc broke the version you're using.
+Upgrade psmisc if 2.2 changes to /proc broke the version you're using.
X
X Tunelp
X ======
@@ -405,6 +422,15 @@
X
X If you're lucky, you'll then have sound....
X
+ You may also need to edit it with
+
+ dd if=/dev/zero of=rvplayer bs=1 count=1 seek=702554 conv=notrunc
+
+ as well. Alternately, download rpopen from
+http://onramp.i2k.com/~jeffd/rpopen/ and pre-load it before you run
+rvplayer (it's a shared object which blocks rvplayer from doing the
+NONBLOCKing open of /dev/dsp).
+
X Quotas
X ======
X
@@ -553,7 +579,7 @@
X ==========
X
X The 2.9 release:
-ftp://ftp.win.tue.nl/pub/linux/util/util-linux-2.9.tar.gz
+ftp://ftp.win.tue.nl/pub/linux/util/util-linux-2.9g.tar.gz
X
X Autofs
X ======
@@ -564,9 +590,9 @@
X NFS
X ===
X
-The user-land 2.2beta37 release:
-ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/nfs-server-2.2beta37.tar.gz
-ftp://linux.nrao.edu/mirrors/fb0429.mathematik.th-darmstadt.de/pub/linux/okir/nfs-server-2.2beta37.tar.gz
+The user-land 2.2beta40 release:
+ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/nfs-server-2.2beta40.tar.gz
+ftp://linux.nrao.edu/mirrors/fb0429.mathematik.th-darmstadt.de/pub/linux/okir/nfs-server-2.2beta40.tar.gz
X
X The kernel-level 12/04/98 release:
X ftp://ftp.yggdrasil.com/private/hjl/knfsd-981204.tar.gz
@@ -585,6 +611,12 @@
X The 3.3 release:
X ftp://ftp.uni-paderborn.de/pub/linux/local/yp/ypbind-3.3.tar.gz
X
+Sysklogd
+========
+
+The 1.3-30 release:
+ftp://metalab.unc.edu/pub/Linux/system/daemons/sysklogd-1.3-30.tar.gz
+
X Bash
X ====
X
@@ -603,14 +635,14 @@
X SMBfs
X =====
X
-The 1.9.18p10 release of Samba:
-ftp://ftp.samba.org/pub/samba/samba-1.9.18p10.tar.gz
+The 2.0.0 release of Samba:
+ftp://ftp.samba.org/pub/samba/samba-2.0.0.tar.gz
X
X Pcmcia-cs
X =========
X
-The 3.0.6 release:
-ftp://hyper.stanford.edu/pub/pcmcia/pcmcia-cs.3.0.6.tar.gz
+The 3.0.7 release:
+ftp://hyper.stanford.edu/pub/pcmcia/pcmcia-cs.3.0.7.tar.gz
X
X Setserial
X =========
@@ -638,6 +670,15 @@
X The 0.4.2 release:
X http://juanjox.linuxhq.com/ipmasqadm-0.4.2.tar.gz
X
+DHCP clients
+============
+
+The 2.0b1p18 ISC dhcpclient release:
+ftp://ftp.isc.org/isc/dhcp/test/dhcp-2.0b1pl8.tar.gz
+
+The 1.3.17-pl2 PhysTech dhcpcd release:
+ftp://ftp.phystech.com/pub/dhcpcd-1.3.17-pl2.tar.gz
+
X iBCS
X ====
X
@@ -693,7 +734,7 @@
X
X Please remember that most of these utils are available on your
X favorite local linux mirror. If you can, please get them from a closer
-site before checking metalab.
+site before checking metalab or tsx-11.
X
X You may also want to check for updated versions of this software in a
X package format for the distribution you use.
@@ -702,20 +743,17 @@
X distribution), most of these are available in RPM format. Check around
X your favorite Red Hat mirror site before installing the non-RPM
X version. Remember, you might need to use the --force option to get the
-upgrade to install. ftp://contrib.redhat.com/ will have almost
-everything you need, and Red Hat 5.2 ships with most necessary software.
+upgrade to install. ftp://contrib.redhat.com/ ,
+ftp://developer.redhat.com/ , or ftp://rawhide.redhat.com/ will have
+almost everything you need, and Red Hat 5.2 ships with most necessary
+software.
X
X Those of you running Debian (or a different distribution that
X supports .deb packages) can look in the "unstable" and
X "project/experimental" directories of your favorite Debian mirror. The
X Debian 2.0 release ships with most packages you need as well.
X
- For others, David Bourgin has put together a package of everything
-necessary to quickly and easily upgrade to 2.1.x. See
-ftp://ftp.wsc.com/pub/freeware/linux/update.linux/kernel-v2.1.x/ for
-more information and the files.
-
-Please send info about any other packages that 2.1.x "broke" or about
-any new features of 2.1.x that require extra or new packages for use to
-Chris Ricker (kab...@gatech.edu or chris....@m.cc.utah.edu).
+Please send info about any other packages that 2.2 "broke" or about any
+new features of 2.2 that require extra or new packages for use to Chris
+Ricker (kab...@gatech.edu or chris....@m.cc.utah.edu).
X
diff -u --recursive --new-file v2.2.0-pre8/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.2.0-pre8/linux/Documentation/Configure.help Tue Jan 19 11:32:50 1999
+++ linux/Documentation/Configure.help Wed Jan 20 11:05:32 1999
@@ -1398,6 +1398,15 @@
X Documentation/mca.txt (and especially the web page given there)
X before attempting to build an MCA bus kernel.
X
+SGI Visal Workstation support
+CONFIG_VISWS
+ The SGI Visual Workstation series is an IA32-based workstation
+ based on SGI systems chips with some legacy PC hardware attached.
+ Say Y here to create a kernel to run on the SGI 320 or 540.
+ A kernel compiled for the Visual Workstation will not run on other
+ PC boards and vice versa.
+ See Documentation/sgi-visws.txt for more.
+
X System V IPC
X CONFIG_SYSVIPC
X Inter Process Communication is a suite of library functions and
@@ -7111,24 +7120,19 @@
X
X If unsure, say N.
X
-/dev/pts filesystem (experimental)
+/dev/pts filesystem for Unix98 PTYs
X CONFIG_DEVPTS_FS
X You should say Y here if you said Y to "Unix98 PTY support" above.
X You'll then get a virtual filesystem which can be mounted on
X /dev/pts with "mount -t devpts". This, together with the pseudo
X terminal master multiplexer /dev/ptmx, is used for pseudo terminal
- support as described in the Open Group's Unix98 standard: in order
+ support as described in The Open Group's Unix98 standard: in order
X to acquire a pseudo terminal, a process opens /dev/ptmx; the number
X of the pseudo terminal is then made available to the process and the
X pseudo terminal slave can be accessed as /dev/pts/<number>. What was
X traditionally /dev/ttyp2 will then be /dev/pts/2, for example. The
X GNU C library glibc 2.1 contains the requisite support for this mode
- of operation.
-
- This code is also available as a module called devpts.o ( = code
- which can be inserted in and removed from the running kernel
- whenever you want). If you want to compile it as a module, say M
- here and read Documentation/modules.txt.
+ of operation; you also need clients that use the Unix98 API.
X
X Unixware slices support (EXPERIMENTAL)
X CONFIG_UNIXWARE_DISKLABEL
@@ -10594,6 +10598,14 @@
X
X If unsure, say Y.
X
+IrDA Debug
+CONFIG_IRDA_DEBUG
+ Say Y here if you want the IrDA subsystem to write debug information to
+ your syslog. You can change the debug level in
+ /proc/sys/net/irda/debug
+
+ If unsure, say Y (since it makes it easier to find the bugs).
+
X IrLAP Compression support
X CONFIG_IRDA_COMPRESSION
X Compression is _not_ part of the IrDA(tm) protocol specification,
@@ -10659,6 +10671,31 @@
X will create two modules called ircomm and ircomm_tty. For more
X information go to http://www.pluto.dti.ne.jp/~thiguchi/irda/
X
+IrLPT Protocol
+CONFIG_IRLPT
+ Say Y here if you want to build support for the IrLPT protocol. If
+ you want to compile it as a module, say M here and read
+ Documentation/modules.txt. IrLPT makes it possible to print
+ documents to IrDA capable printers.
+
+IrLPT Client Protocol
+CONFIG_IRLPT_CLIENT
+ Say Y here if you want to build support for the IrLPT client
+ protocol. If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. The IrLPT client protocol can be used to
+ print documents to IrDA compatible printers like the HP-5MP, or
+ IrLPT printer adapters like the ACTiSYS IR-100M.
+
+IrLPT Server Protocol
+CONFIG_IRLPT_SERVER
+ Say Y here if you want to build support for the IrLPT server
+ protocol. If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. The IrLPT server protocol makes it
+ possible to use a Linux machine as an infrared printer server for
+ other laptops. So if your Linux machine has a cable connection to a
+ printer, then other laptops can use the Linux machine to print out
+ documents using infrared communication.
+
X IrTTY IrDA Device Driver
X CONFIG_IRTTY_SIR
X Say Y here if you want to build support for the IrTTY line
@@ -10686,6 +10723,13 @@
X read Documentation/modules.txt. This drivers currently only supports
X the ACTiSYS IR2000B ISA card and supports SIR, MIR and FIR (4Mbps)
X speeds.
+
+Sharp UIRCC IrDA Device Driver
+CONFIG_SHARP_FIR
+ Say Y here if you want to build support for the Sharp UIRCC IrDA
+ chipset. If you want to compile it as a module, say M here and
+ read Documentation/modules.txt. This chipset is used by the Toshiba
+ Tecra laptops.
X
X ESI JetEye PC Dongle
X CONFIG_ESI_DONGLE
diff -u --recursive --new-file v2.2.0-pre8/linux/Documentation/sgi-visws.txt linux/Documentation/sgi-visws.txt
--- v2.2.0-pre8/linux/Documentation/sgi-visws.txt Wed Dec 31 16:00:00 1969
+++ linux/Documentation/sgi-visws.txt Wed Jan 20 10:18:53 1999
@@ -0,0 +1,13 @@
+
+The SGI Visual Workstations (models 320 and 540) are based around
+the Cobalt, Lithium, and Arsenic ASICs. The Cobalt ASIC is the
+main system ASIC which interfaces the 1-4 IA32 cpus, the memory
+system, and the I/O system in the Lithium ASIC. The Cobalt ASIC
+also contains the 3D gfx rendering engine which renders to main
+system memory -- part of which is used as the frame buffer which
+is DMA'ed to a video connector using the Arsenic ASIC. A PIIX4
+chip and NS87307 are used to provide legacy device support (IDE,
+serial, floppy, and parallel).
+
+The Visual Workstation chipset largely conforms to the PC architecture
+with some notable exceptions such as interrupt handling.
diff -u --recursive --new-file v2.2.0-pre8/linux/MAINTAINERS linux/MAINTAINERS
--- v2.2.0-pre8/linux/MAINTAINERS Tue Jan 19 11:32:50 1999
+++ linux/MAINTAINERS Wed Jan 20 13:27:17 1999
@@ -641,6 +641,13 @@
X L: linux...@vger.rutgers.edu
X S: Maintained
X
+SGI VISUAL WORKSTATION 320 AND 540
+P: Bent Hagemark
+M: b...@sgi.com
+P: Ingo Molnar
+M: mi...@redhat.com
+S: Maintained
+
X SMB FILESYSTEM
X P: Volker Lendecke
X M: v...@kki.org
diff -u --recursive --new-file v2.2.0-pre8/linux/Makefile linux/Makefile
--- v2.2.0-pre8/linux/Makefile Tue Jan 19 11:32:50 1999
+++ linux/Makefile Wed Jan 20 22:27:22 1999
@@ -1,7 +1,7 @@
X VERSION = 2
X PATCHLEVEL = 2
X SUBLEVEL = 0
-EXTRAVERSION =-pre8
+EXTRAVERSION =-final
X
X ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
X
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c
--- v2.2.0-pre8/linux/arch/alpha/kernel/osf_sys.c Thu Nov 12 16:21:17 1998
+++ linux/arch/alpha/kernel/osf_sys.c Wed Jan 20 16:07:26 1999
@@ -1128,11 +1128,16 @@
X return ret;
X }
X
+#define MAX_SELECT_SECONDS \
+ ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
+
X asmlinkage int
X osf_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
X struct timeval32 *tvp)
X {
- fd_set_buffer *fds;
+ fd_set_bits fds;
+ char *bits;
+ size_t size;
X unsigned long timeout;
X int ret;
X
@@ -1145,28 +1150,46 @@
X || (ret = __get_user(usec, &tvp->tv_usec)))
X goto out_nofds;
X
- timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
- timeout += sec * HZ;
+ ret = -EINVAL;
+ if (sec < 0 || usec < 0)
+ goto out_nofds;
+
+ if ((unsigned long) sec < MAX_SELECT_SECONDS) {
+ timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
+ timeout += sec * (unsigned long) HZ;
+ }
X }
X
+ ret = -EINVAL;
+ if (n < 0 || n > KFDS_NR)
+ goto out_nofds;
+
+ /*
+ * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
+ * since we used fdset we need to allocate memory in units of
+ * long-words.
+ */
X ret = -ENOMEM;
- fds = (fd_set_buffer *) __get_free_page(GFP_KERNEL);
- if (!fds)
+ size = FDS_BYTES(n);
+ bits = kmalloc(6 * size, GFP_KERNEL);
+ if (!bits)
X goto out_nofds;
- ret = -EINVAL;
- if (n < 0)
- goto out;
- if (n > KFDS_NR)
- n = KFDS_NR;
- if ((ret = get_fd_set(n, inp->fds_bits, fds->in)) ||
- (ret = get_fd_set(n, outp->fds_bits, fds->out)) ||
- (ret = get_fd_set(n, exp->fds_bits, fds->ex)))
+ fds.in = (unsigned long *) bits;
+ fds.out = (unsigned long *) (bits + size);
+ fds.ex = (unsigned long *) (bits + 2*size);
+ fds.res_in = (unsigned long *) (bits + 3*size);
+ fds.res_out = (unsigned long *) (bits + 4*size);
+ fds.res_ex = (unsigned long *) (bits + 5*size);
+
+ if ((ret = get_fd_set(n, inp->fds_bits, fds.in)) ||
+ (ret = get_fd_set(n, outp->fds_bits, fds.out)) ||
+ (ret = get_fd_set(n, exp->fds_bits, fds.ex)))
X goto out;
- zero_fd_set(n, fds->res_in);
- zero_fd_set(n, fds->res_out);
- zero_fd_set(n, fds->res_ex);
+ zero_fd_set(n, fds.res_in);
+ zero_fd_set(n, fds.res_out);
+ zero_fd_set(n, fds.res_ex);
X
- ret = do_select(n, fds, &timeout);
+ ret = do_select(n, &fds, &timeout);
X
X /* OSF does not copy back the remaining time. */
X
@@ -1179,12 +1202,12 @@
X ret = 0;
X }
X
- set_fd_set(n, inp->fds_bits, fds->res_in);
- set_fd_set(n, outp->fds_bits, fds->res_out);
- set_fd_set(n, exp->fds_bits, fds->res_ex);
+ set_fd_set(n, inp->fds_bits, fds.res_in);
+ set_fd_set(n, outp->fds_bits, fds.res_out);
+ set_fd_set(n, exp->fds_bits, fds.res_ex);
X
X out:
- free_page((unsigned long) fds);
+ kfree(bits);
X out_nofds:
X return ret;
X }
@@ -1304,7 +1327,6 @@
X {
X struct timeval tmp;
X unsigned long ticks;
- unsigned long tmp_timeout;
X
X if (get_tv32(&tmp, sleep))
X goto fault;
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- v2.2.0-pre8/linux/arch/alpha/kernel/process.c Tue Jan 19 11:32:50 1999
+++ linux/arch/alpha/kernel/process.c Wed Jan 20 11:08:43 1999
@@ -266,12 +266,8 @@
X
X int alpha_vfork(struct switch_stack * swstack)
X {
- int child;
-
- child = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
X (struct pt_regs *) (swstack+1));
-
- return child;
X }
X
X extern void ret_from_sys_call(void);
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- v2.2.0-pre8/linux/arch/alpha/kernel/time.c Wed Jan 13 15:00:41 1999
+++ linux/arch/alpha/kernel/time.c Tue Jan 19 10:19:38 1999
@@ -10,6 +10,8 @@
X * 1995-03-26 Markus Kuhn
X * fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
X * precision CMOS clock update
+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills
X * 1997-01-09 Adrian Sun
X * use interval timer if CONFIG_RTC=y
X * 1997-10-29 John Bowman (bow...@math.ualberta.ca)
@@ -112,10 +114,10 @@
X * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
X * called as close as possible to 500 ms before the new second starts.
X */
- if (time_state != TIME_BAD
+ if ((time_status & STA_UNSYNC) == 0
X && xtime.tv_sec > state.last_rtc_update + 660
- && xtime.tv_usec >= 500000 - (tick >> 1)
- && xtime.tv_usec <= 500000 + (tick >> 1)) {
+ && xtime.tv_usec >= 500000 - ((unsigned) tick) / 2
+ && xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
X int tmp = set_rtc_mmss(xtime.tv_sec);
X state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0);
X }
@@ -353,9 +355,11 @@
X {
X cli();
X xtime = *tv;
- time_state = TIME_BAD;
- time_maxerror = 0x70000000;
- time_esterror = 0x70000000;
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR; /* p. 24, (a) */
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
X sti();
X }
X
@@ -366,6 +370,9 @@
X * nowtime is written into the registers of the CMOS clock, it will
X * jump to the next second precisely 500 ms later. Check the Motorola
X * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ * sets the minutes. Usually you won't notice until after reboot!
X */
X static int
X set_rtc_mmss(unsigned long nowtime)
@@ -407,8 +414,12 @@
X }
X CMOS_WRITE(real_seconds,RTC_SECONDS);
X CMOS_WRITE(real_minutes,RTC_MINUTES);
- } else
- retval = -1;
+ } else {
+ printk(KERN_WARNING
+ "set_rtc_mmss: can't update from %d to %d\n",
+ cmos_minutes, real_minutes);
+ retval = -1;
+ }
X
X /* The following flags have to be released exactly in this order,
X * otherwise the DS12887 (popular MC146818A clone with integrated
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/arm/kernel/time.c linux/arch/arm/kernel/time.c
--- v2.2.0-pre8/linux/arch/arm/kernel/time.c Wed Sep 9 14:51:04 1998
+++ linux/arch/arm/kernel/time.c Tue Jan 19 10:19:41 1999
@@ -9,7 +9,7 @@
X *
X * 1994-07-02 Alan Modra
X * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
- * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * 1998-12-20 Updated NTP code according to technical memorandum Jan '96
X * "A Kernel Model for Precision Timekeeping" by Dave Mills
X */
X #include <linux/errno.h>
@@ -125,9 +125,11 @@
X }
X
X xtime = *tv;
- time_state = TIME_BAD;
- time_maxerror = MAXPHASE;
- time_esterror = MAXPHASE;
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR; /* p. 24, (a) */
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
X sti ();
X }
X
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.2.0-pre8/linux/arch/i386/config.in Tue Jan 19 11:32:51 1999
+++ linux/arch/i386/config.in Wed Jan 20 10:18:53 1999
@@ -70,6 +70,17 @@
X bool ' Backward-compatible /proc/pci' CONFIG_PCI_OLD_PROC
X fi
X bool 'MCA support' CONFIG_MCA
+bool 'SGI Visual Workstation support' CONFIG_VISWS
+if [ "$CONFIG_VISWS" = "y" ]; then
+ define_bool CONFIG_X86_VISWS_APIC y
+ define_bool CONFIG_X86_LOCAL_APIC y
+else
+ if [ "$CONFIG_SMP" = "y" ]; then
+ define_bool CONFIG_X86_IO_APIC y
+ define_bool CONFIG_X86_LOCAL_APIC y
+ fi
+fi
+
X bool 'System V IPC' CONFIG_SYSVIPC
X bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
X bool 'Sysctl support' CONFIG_SYSCTL
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.2.0-pre8/linux/arch/i386/defconfig Tue Jan 19 11:32:51 1999
+++ linux/arch/i386/defconfig Wed Jan 20 11:33:56 1999
@@ -45,6 +45,9 @@
X CONFIG_PCI_QUIRKS=y
X CONFIG_PCI_OLD_PROC=y
X # CONFIG_MCA is not set
+# CONFIG_VISWS is not set
+CONFIG_X86_IO_APIC=y
+CONFIG_X86_LOCAL_APIC=y
X CONFIG_SYSVIPC=y
X # CONFIG_BSD_PROCESS_ACCT is not set
X CONFIG_SYSCTL=y
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile
--- v2.2.0-pre8/linux/arch/i386/kernel/Makefile Tue Dec 22 14:16:53 1998
+++ linux/arch/i386/kernel/Makefile Wed Jan 20 10:18:53 1999
@@ -39,7 +39,15 @@
X endif
X
X ifdef CONFIG_SMP
-O_OBJS += io_apic.o smp.o trampoline.o
+O_OBJS += smp.o trampoline.o
+endif
+
+ifdef CONFIG_X86_IO_APIC
+O_OBJS += io_apic.o
+endif
+
+ifdef CONFIG_X86_VISWS_APIC
+O_OBJS += visws_apic.o
X endif
X
X head.o: head.S $(TOPDIR)/include/linux/tasks.h
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v2.2.0-pre8/linux/arch/i386/kernel/bios32.c Fri Oct 23 22:01:19 1998
+++ linux/arch/i386/kernel/bios32.c Wed Jan 20 10:18:53 1999
@@ -352,6 +352,10 @@
X {
X u16 dfn, x;
X
+#ifdef CONFIG_VISWS
+ return 1; /* Lithium PCI Bridges are non-standard */
+#endif
+
X if (pci_probe & PCI_NO_CHECKS)
X return 1;
X for(dfn=0; dfn < 0x100; dfn++)
@@ -1051,7 +1055,7 @@
X pci_write_config_word(dev, PCI_COMMAND, cmd);
X }
X }
-#ifdef __SMP__
+#if defined(CONFIG_X86_IO_APIC)
X /*
X * Recalculate IRQ numbers if we use the I/O APIC
X */
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.2.0-pre8/linux/arch/i386/kernel/entry.S Tue Jan 19 11:32:51 1999
+++ linux/arch/i386/kernel/entry.S Wed Jan 20 11:05:59 1999
@@ -559,7 +559,7 @@
X .long SYMBOL_NAME(sys_sendfile)
X .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
X .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
- .long SYMBOL_NAME(sys_ni_syscall) /* 190 */
+ .long SYMBOL_NAME(sys_vfork) /* 190 */
X
X /*
X * NOTE!! This doesn't have to be exact - we just have
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.2.0-pre8/linux/arch/i386/kernel/i386_ksyms.c Thu Dec 31 10:28:59 1998
+++ linux/arch/i386/kernel/i386_ksyms.c Tue Jan 19 11:02:59 1999
@@ -60,6 +60,7 @@
X
X EXPORT_SYMBOL(strtok);
X EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(strstr);
X
X EXPORT_SYMBOL(strncpy_from_user);
X EXPORT_SYMBOL(__strncpy_from_user);
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.2.0-pre8/linux/arch/i386/kernel/irq.c Thu Dec 31 10:28:59 1998
+++ linux/arch/i386/kernel/irq.c Wed Jan 20 13:00:17 1999
@@ -15,6 +15,7 @@
X * Naturally it's not a 1:1 relation, but there are similarities.
X */
X
+#include <linux/config.h>
X #include <linux/ptrace.h>
X #include <linux/errno.h>
X #include <linux/kernel_stat.h>
@@ -47,46 +48,28 @@
X atomic_t nmi_counter;
X
X /*
- * About the IO-APIC, the architecture is 'merged' into our
- * current irq architecture, seemlessly. (i hope). It is only
- * visible through a few more more hardware interrupt lines, but
- * otherwise drivers are unaffected. The main code is believed
- * to be NR_IRQS-safe (nothing anymore thinks we have 16
- * irq lines only), but there might be some places left ...
+ * Linux has a controller-independent x86 interrupt architecture.
+ * every controller has a 'controller-template', that is used
+ * by the main code to do the right thing. Each driver-visible
+ * interrupt source is transparently wired to the apropriate
+ * controller. Thus drivers need not be aware of the
+ * interrupt-controller.
+ *
+ * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
+ * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
+ * (IO-APICs assumed to be messaging to Pentium local-APICs)
+ *
+ * the code is designed to be easily extended with new/different
+ * interrupt controllers, without having to do assembly magic.
X */
X
X /*
- * This contains the irq mask for both 8259A irq controllers,
+ * Micro-access to controllers is serialized over the whole
+ * system. We never hold this lock when we call the actual
+ * IRQ handler.
X */
-static unsigned int cached_irq_mask = 0xffff;
-
-#define __byte(x,y) (((unsigned char *)&(y))[x])
-#define __word(x,y) (((unsigned short *)&(y))[x])
-#define __long(x,y) (((unsigned int *)&(y))[x])
-
-#define cached_21 (__byte(0,cached_irq_mask))
-#define cached_A1 (__byte(1,cached_irq_mask))
-
X spinlock_t irq_controller_lock;
X
-/*
- * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
- * boards the timer interrupt is not connected to any IO-APIC pin, it's
- * fed to the CPU IRQ line directly.
- *
- * Any '1' bit in this mask means the IRQ is routed through the IO-APIC.
- * this 'mixed mode' IRQ handling costs us one more branch in do_IRQ,
- * but we have _much_ higher compatibility and robustness this way.
- */
-unsigned long long io_apic_irqs = 0;
-
-static void do_8259A_IRQ(unsigned int irq, struct pt_regs * regs);
-static void enable_8259A_irq(unsigned int irq);
-void disable_8259A_irq(unsigned int irq);
-
-/* startup is the same as "enable", shutdown is same as "disable" */
-#define startup_8259A_irq enable_8259A_irq
-#define shutdown_8259A_irq disable_8259A_irq
X
X /*
X * Dummy controller type for unused interrupts
@@ -108,6 +91,19 @@
X disable_none
X };
X
+/*
+ * This is the 'legacy' 8259A Programmable Interrupt Controller,
+ * present in the majority of PC/AT boxes.
+ */
+
+static void do_8259A_IRQ(unsigned int irq, struct pt_regs * regs);
+static void enable_8259A_irq(unsigned int irq);
+void disable_8259A_irq(unsigned int irq);
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define startup_8259A_irq enable_8259A_irq
+#define shutdown_8259A_irq disable_8259A_irq
+
X static struct hw_interrupt_type i8259A_irq_type = {
X "XT-PIC",
X startup_8259A_irq,
@@ -117,11 +113,38 @@
X disable_8259A_irq
X };
X
-irq_desc_t irq_desc[NR_IRQS] = {
- [0 ... 15] = { 0, &i8259A_irq_type, }, /* default to standard ISA IRQs */
- [16 ... NR_IRQS-1] = { 0, &no_irq_type, }, /* 'high' PCI IRQs filled in on demand */
-};
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = { 0, &no_irq_type, }};
+
+
+/*
+ * 8259A PIC functions to handle ISA devices:
+ */
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ */
+static unsigned int cached_irq_mask = 0xffff;
+
+#define __byte(x,y) (((unsigned char *)&(y))[x])
+#define __word(x,y) (((unsigned short *)&(y))[x])
+#define __long(x,y) (((unsigned int *)&(y))[x])
+
+#define cached_21 (__byte(0,cached_irq_mask))
+#define cached_A1 (__byte(1,cached_irq_mask))
X
+/*
+ * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
+ * boards the timer interrupt is not connected to any IO-APIC pin, it's
+ * fed to the CPU IRQ line directly.
+ *
+ * Any '1' bit in this mask means the IRQ is routed through the IO-APIC.
+ * this 'mixed mode' IRQ handling costs us one more branch in do_IRQ,
+ * but we have _much_ higher compatibility and robustness this way.
+ */
+unsigned long long io_apic_irqs = 0;
X
X /*
X * These have to be protected by the irq controller spinlock
@@ -149,6 +172,77 @@
X }
X }
X
+int i8259A_irq_pending(unsigned int irq)
+{
+ unsigned int mask = 1<<irq;
+
+ if (irq < 8)
+ return (inb(0x20) & mask);
+ return (inb(0xA0) & (mask >> 8));
+}
+
+void make_8259A_irq(unsigned int irq)
+{
+ disable_irq(irq);
+ __long(0,io_apic_irqs) &= ~(1<<irq);
+ irq_desc[irq].handler = &i8259A_irq_type;
+ enable_irq(irq);
+}
+
+/*
+ * Careful! The 8259A is a fragile beast, it pretty
+ * much _has_ to be done exactly like this (mask it
+ * first, _then_ send the EOI, and the order of EOI
+ * to the two 8259s is important!
+ */
+static inline void mask_and_ack_8259A(unsigned int irq)
+{
+ cached_irq_mask |= 1 << irq;
+ if (irq & 8) {
+ inb(0xA1); /* DUMMY */
+ outb(cached_A1,0xA1);
+ outb(0x62,0x20); /* Specific EOI to cascade */
+ outb(0x20,0xA0);
+ } else {
+ inb(0x21); /* DUMMY */
+ outb(cached_21,0x21);
+ outb(0x20,0x20);
+ }
+}
+
+static void do_8259A_IRQ(unsigned int irq, struct pt_regs * regs)
+{
+ struct irqaction * action;
+ irq_desc_t *desc = irq_desc + irq;
+
+ spin_lock(&irq_controller_lock);
+ {
+ unsigned int status;
+ mask_and_ack_8259A(irq);
+ status = desc->status & ~IRQ_REPLAY;
+ action = NULL;
+ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ action = desc->action;
+ desc->status = status | IRQ_INPROGRESS;
+ }
+ spin_unlock(&irq_controller_lock);
+
+ /* Exit early if we had no action or it was disabled */
+ if (!action)
+ return;
+
+ handle_IRQ_event(irq, regs, action);
+
+ spin_lock(&irq_controller_lock);
+ {
+ unsigned int status = desc->status & ~IRQ_INPROGRESS;
+ desc->status = status;
+ if (!(status & IRQ_DISABLED))
+ enable_8259A_irq(irq);
+ }
+ spin_unlock(&irq_controller_lock);
+}
+
X /*
X * This builds up the IRQ handler stubs using some ugly macros in irq.h
X *
@@ -168,8 +262,7 @@
X BUILD_IRQ(8) BUILD_IRQ(9) BUILD_IRQ(10) BUILD_IRQ(11)
X BUILD_IRQ(12) BUILD_IRQ(13) BUILD_IRQ(14) BUILD_IRQ(15)
X
-#ifdef __SMP__
-
+#ifdef CONFIG_X86_IO_APIC
X /*
X * The IO-APIC gives us many more interrupt sources..
X */
@@ -185,7 +278,9 @@
X BUILD_IRQ(52) BUILD_IRQ(53) BUILD_IRQ(54) BUILD_IRQ(55)
X BUILD_IRQ(56) BUILD_IRQ(57) BUILD_IRQ(58) BUILD_IRQ(59)
X BUILD_IRQ(60) BUILD_IRQ(61) BUILD_IRQ(62) BUILD_IRQ(63)
+#endif
X
+#ifdef __SMP__
X /*
X * The following vectors are part of the Linux architecture, there
X * is no hardware IRQ pin equivalent for them, they are triggered
@@ -213,7 +308,7 @@
X IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
X IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
X IRQ12_interrupt, IRQ13_interrupt, IRQ14_interrupt, IRQ15_interrupt
-#ifdef __SMP__
+#ifdef CONFIG_X86_IO_APIC
X ,IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,
X IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,
X IRQ24_interrupt, IRQ25_interrupt, IRQ26_interrupt, IRQ27_interrupt,
@@ -231,12 +326,16 @@
X #endif
X };
X
+
X /*
X * Initial irq handlers.
X */
X
-static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+void no_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+}
X
+#ifndef CONFIG_VISWS
X /*
X * Note that on a 486, we don't want to do a SIGFPE on an irq13
X * as the irq is unreliable, and exception 16 works correctly
@@ -262,7 +361,13 @@
X /*
X * IRQ2 is cascade interrupt to second interrupt controller
X */
+
X static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
+#endif
+
+/*
+ * Generic, controller-independent functions:
+ */
X
X int get_irq_list(char *buf)
X {
@@ -351,7 +456,6 @@
X }
X }
X
-
X #define MAXCOUNT 100000000
X
X static inline void wait_on_bh(void)
@@ -608,79 +712,6 @@
X return status;
X }
X
-int i8259A_irq_pending(unsigned int irq)
-{
- unsigned int mask = 1<<irq;
-
- if (irq < 8)
- return (inb(0x20) & mask);
- return (inb(0xA0) & (mask >> 8));
-}
-
-
-void make_8259A_irq(unsigned int irq)
-{
- disable_irq(irq);
- __long(0,io_apic_irqs) &= ~(1<<irq);
- irq_desc[irq].handler = &i8259A_irq_type;
- enable_irq(irq);
-}
-
-/*
- * Careful! The 8259A is a fragile beast, it pretty
- * much _has_ to be done exactly like this (mask it
- * first, _then_ send the EOI, and the order of EOI
- * to the two 8259s is important!
- */
-static inline void mask_and_ack_8259A(unsigned int irq)
-{
- cached_irq_mask |= 1 << irq;
- if (irq & 8) {
- inb(0xA1); /* DUMMY */
- outb(cached_A1,0xA1);
- outb(0x62,0x20); /* Specific EOI to cascade */
- outb(0x20,0xA0);
- } else {
- inb(0x21); /* DUMMY */
- outb(cached_21,0x21);
- outb(0x20,0x20);
- }
-}
-
-static void do_8259A_IRQ(unsigned int irq, struct pt_regs * regs)
-{
- struct irqaction * action;
- irq_desc_t *desc = irq_desc + irq;
-
- spin_lock(&irq_controller_lock);
- {
- unsigned int status;
- mask_and_ack_8259A(irq);
- status = desc->status & ~IRQ_REPLAY;
- action = NULL;
- if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- action = desc->action;
- desc->status = status | IRQ_INPROGRESS;
- }
- spin_unlock(&irq_controller_lock);
-
- /* Exit early if we had no action or it was disabled */
- if (!action)
- return;
-
- handle_IRQ_event(irq, regs, action);
-
- spin_lock(&irq_controller_lock);
- {
- unsigned int status = desc->status & ~IRQ_INPROGRESS;
- desc->status = status;
- if (!(status & IRQ_DISABLED))
- enable_8259A_irq(irq);
- }
- spin_unlock(&irq_controller_lock);
-}
-
-
X /*
X * Generic enable/disable code: this just calls
X * down into the PIC-specific version for the actual
@@ -955,21 +986,75 @@
X return irq_found;
X }
X
-__initfunc(void init_IRQ(void))
+/*
+ * Silly, horrible hack
+ */
+static char uglybuffer[10*256];
+
+__asm__("\n" __ALIGN_STR"\n"
+ "common_unexpected:\n\t"
+ SAVE_ALL
+ "pushl $ret_from_intr\n\t"
+ "jmp strange_interrupt");
+
+void strange_interrupt(int irqnum)
+{
+ printk("Unexpected interrupt %d\n", irqnum & 255);
+ for (;;);
+}
+
+extern int common_unexpected;
+__initfunc(void init_unexpected_irq(void))
X {
X int i;
+ for (i = 0; i < 256; i++) {
+ char *code = uglybuffer + 10*i;
+ unsigned long jumpto = (unsigned long) &common_unexpected;
+
+ jumpto -= (unsigned long)(code+10);
+ code[0] = 0x68; /* pushl */
+ *(int *)(code+1) = i - 512;
+ code[5] = 0xe9; /* jmp */
+ *(int *)(code+6) = jumpto;
+
+ set_intr_gate(i,code);
+ }
+}
X
- /* set the clock to 100 Hz */
- outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
- outb_p(LATCH & 0xff , 0x40); /* LSB */
- outb(LATCH >> 8 , 0x40); /* MSB */
X
- for (i=0; i<NR_IRQS; i++)
+void init_ISA_irqs (void)
+{
+ int i;
+
+ for (i = 0; i < NR_IRQS; i++) {
X irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 0;
+
+ if (i < 16) {
+ /*
+ * 16 old-style INTA-cycle interrupt gates:
+ */
+ irq_desc[i].handler = &i8259A_irq_type;
+ } else {
+ /*
+ * 'high' PCI IRQs filled in on demand
+ */
+ irq_desc[i].handler = &no_irq_type;
+ }
+ }
+}
+
+__initfunc(void init_IRQ(void))
+{
+ int i;
+
+#ifndef CONFIG_X86_VISWS_APIC
+ init_ISA_irqs();
+#else
+ init_VISWS_APIC_irqs();
+#endif
X
- /*
- * 16 old-style INTA-cycle interrupt gates:
- */
X for (i = 0; i < 16; i++)
X set_intr_gate(0x20+i,interrupt[i]);
X
@@ -1008,12 +1093,22 @@
X #endif
X request_region(0x20,0x20,"pic1");
X request_region(0xa0,0x20,"pic2");
+
+ /*
+ * Set the clock to 100 Hz, we already have a valid
+ * vector now:
+ */
+ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
+ outb_p(LATCH & 0xff , 0x40); /* LSB */
+ outb(LATCH >> 8 , 0x40); /* MSB */
+
+#ifndef CONFIG_VISWS
X setup_x86_irq(2, &irq2);
X setup_x86_irq(13, &irq13);
+#endif
X }
X
-#ifdef __SMP__
-
+#ifdef CONFIG_X86_IO_APIC
X __initfunc(void init_IRQ_SMP(void))
X {
X int i;
@@ -1021,5 +1116,5 @@
X if (IO_APIC_VECTOR(i) > 0)
X set_intr_gate(IO_APIC_VECTOR(i), interrupt[i]);
X }
-
X #endif
+
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h
--- v2.2.0-pre8/linux/arch/i386/kernel/irq.h Mon Dec 28 15:00:52 1998
+++ linux/arch/i386/kernel/irq.h Wed Jan 20 16:23:00 1999
@@ -69,6 +69,7 @@
X
X extern void init_IRQ_SMP(void);
X extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
+extern int setup_x86_irq(unsigned int, struct irqaction *);
X
X /*
X * Various low-level irq details needed by irq.c, process.c,
@@ -77,16 +78,19 @@
X * Interrupt entry/exit code at both C and assembly level
X */
X
+extern void no_action(int cpl, void *dev_id, struct pt_regs *regs);
X extern void mask_irq(unsigned int irq);
X extern void unmask_irq(unsigned int irq);
X extern void disable_8259A_irq(unsigned int irq);
X extern int i8259A_irq_pending(unsigned int irq);
X extern void ack_APIC_irq(void);
+extern void FASTCALL(send_IPI_self(int vector));
+extern void smp_send_mtrr(void);
+extern void init_VISWS_APIC_irqs(void);
X extern void setup_IO_APIC(void);
X extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
X extern void make_8259A_irq(unsigned int irq);
-extern void FASTCALL(send_IPI_self(int vector));
-extern void smp_send_mtrr(void);
+extern void send_IPI(int dest, int vector);
X extern void init_pic_mode(void);
X extern void print_IO_APIC(void);
X
@@ -103,11 +107,7 @@
X extern char ioapic_OEM_ID [16];
X extern char ioapic_Product_ID [16];
X
-extern spinlock_t irq_controller_lock; /*
- * Protects both the 8259 and the
- * IO-APIC
- */
-
+extern spinlock_t irq_controller_lock;
X
X #ifdef __SMP__
X
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.2.0-pre8/linux/arch/i386/kernel/process.c Tue Jan 19 11:32:51 1999
+++ linux/arch/i386/kernel/process.c Wed Jan 20 11:08:24 1999
@@ -785,6 +785,21 @@
X }
X
X /*
+ * This is trivial, and on the face of it looks like it
+ * could equally well be done in user mode.
+ *
+ * Not so, for quite unobvious reasons - register pressure.
+ * In user mode vfork() cannot have a stack frame, and if
+ * done by calling the "clone()" system call directly, you
+ * do not have enough call-clobbered registers to hold all
+ * the information you need.
+ */
+asmlinkage int sys_vfork(struct pt_regs regs)
+{
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs);
+}
+
+/*
X * sys_execve() executes a new program.
X */
X asmlinkage int sys_execve(struct pt_regs regs)
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.2.0-pre8/linux/arch/i386/kernel/setup.c Fri Jan 8 22:36:01 1999
+++ linux/arch/i386/kernel/setup.c Wed Jan 20 10:18:53 1999
@@ -38,6 +38,7 @@
X #include <asm/system.h>
X #include <asm/io.h>
X #include <asm/smp.h>
+#include <asm/cobalt.h>
X
X /*
X * Machine setup..
@@ -107,6 +108,132 @@
X #define RAMDISK_PROMPT_FLAG 0x8000
X #define RAMDISK_LOAD_FLAG 0x4000
X
+#ifdef CONFIG_VISWS
+char visws_board_type = -1;
+char visws_board_rev = -1;
+
+#define PIIX_PM_START 0x0F80
+
+#define SIO_GPIO_START 0x0FC0
+
+#define SIO_PM_START 0x0FC8
+
+#define PMBASE PIIX_PM_START
+#define GPIREG0 (PMBASE+0x30)
+#define GPIREG(x) (GPIREG0+((x)/8))
+#define PIIX_GPI_BD_ID1 18
+#define PIIX_GPI_BD_REG GPIREG(PIIX_GPI_BD_ID1)
+
+#define PIIX_GPI_BD_SHIFT (PIIX_GPI_BD_ID1 % 8)
+
+#define SIO_INDEX 0x2e
+#define SIO_DATA 0x2f
+
+#define SIO_DEV_SEL 0x7
+#define SIO_DEV_ENB 0x30
+#define SIO_DEV_MSB 0x60
+#define SIO_DEV_LSB 0x61
+
+#define SIO_GP_DEV 0x7
+
+#define SIO_GP_BASE SIO_GPIO_START
+#define SIO_GP_MSB (SIO_GP_BASE>>8)
+#define SIO_GP_LSB (SIO_GP_BASE&0xff)
+
+#define SIO_GP_DATA1 (SIO_GP_BASE+0)
+
+#define SIO_PM_DEV 0x8
+
+#define SIO_PM_BASE SIO_PM_START
+#define SIO_PM_MSB (SIO_PM_BASE>>8)
+#define SIO_PM_LSB (SIO_PM_BASE&0xff)
+#define SIO_PM_INDEX (SIO_PM_BASE+0)
+#define SIO_PM_DATA (SIO_PM_BASE+1)
+
+#define SIO_PM_FER2 0x1
+
+#define SIO_PM_GP_EN 0x80
+
+static void
+visws_get_board_type_and_rev(void)
+{
+ int raw;
+
+ visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG)
+ >> PIIX_GPI_BD_SHIFT;
+/*
+ * Get Board rev.
+ * First, we have to initialize the 307 part to allow us access
+ * to the GPIO registers. Let's map them at 0x0fc0 which is right
+ * after the PIIX4 PM section.
+ */
+ outb_p(SIO_DEV_SEL, SIO_INDEX);
+ outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */
+
+ outb_p(SIO_DEV_MSB, SIO_INDEX);
+ outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */
+
+ outb_p(SIO_DEV_LSB, SIO_INDEX);
+ outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */
+
+ outb_p(SIO_DEV_ENB, SIO_INDEX);
+ outb_p(1, SIO_DATA); /* Enable GPIO registers. */
+
+/*
+ * Now, we have to map the power management section to write
+ * a bit which enables access to the GPIO registers.
+ * What lunatic came up with this shit?
+ */
+ outb_p(SIO_DEV_SEL, SIO_INDEX);
+ outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */
+
+ outb_p(SIO_DEV_MSB, SIO_INDEX);
+ outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */
+
+ outb_p(SIO_DEV_LSB, SIO_INDEX);
+ outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */
+
+ outb_p(SIO_DEV_ENB, SIO_INDEX);
+ outb_p(1, SIO_DATA); /* Enable PM registers. */
+
+/*
+ * Now, write the PM register which enables the GPIO registers.
+ */
+ outb_p(SIO_PM_FER2, SIO_PM_INDEX);
+ outb_p(SIO_PM_GP_EN, SIO_PM_DATA);
+
+/*
+ * Now, initialize the GPIO registers.
+ * We want them all to be inputs which is the
+ * power on default, so let's leave them alone.
+ * So, let's just read the board rev!
+ */
+ raw = inb_p(SIO_GP_DATA1);
+ raw &= 0x7f; /* 7 bits of valid board revision ID. */
+
+ if (visws_board_type == VISWS_320) {
+ if (raw < 0x6) {
+ visws_board_rev = 4;
+ } else if (raw < 0xc) {
+ visws_board_rev = 5;
+ } else {
+ visws_board_rev = 6;
+
+ }
+ } else if (visws_board_type == VISWS_540) {
+ visws_board_rev = 2;
+ } else {
+ visws_board_rev = raw;
+ }
+
+ printk("Silicon Graphics %s (rev %d)\n",
+ visws_board_type == VISWS_320 ? "320" :
+ (visws_board_type == VISWS_540 ? "540" :
+ "unknown"),
+ visws_board_rev);
+ }
+#endif
+
X
X static char command_line[COMMAND_LINE_SIZE] = { 0, };
X char saved_command_line[COMMAND_LINE_SIZE];
@@ -122,6 +249,10 @@
X if (smptrap)
X return;
X smptrap=1;
+
+#ifdef CONFIG_VISWS
+ visws_get_board_type_and_rev();
+#endif
X
X ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
X drive_info = DRIVE_INFO;
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.2.0-pre8/linux/arch/i386/kernel/smp.c Thu Jan 7 15:11:35 1999
+++ linux/arch/i386/kernel/smp.c Wed Jan 20 10:18:53 1999
@@ -36,7 +36,6 @@
X #include <linux/kernel_stat.h>
X #include <linux/delay.h>
X #include <linux/mc146818rtc.h>
-#include <asm/i82489.h>
X #include <linux/smp_lock.h>
X #include <linux/interrupt.h>
X #include <linux/init.h>
@@ -198,6 +197,19 @@
X apic_write(APIC_EOI, 0);
X }
X
+#ifdef CONFIG_X86_VISWS_APIC
+/*
+ * hacky!
+ */
+int __init smp_scan_config(unsigned long base, unsigned long length)
+{
+ cpu_present_map |= 2; /* or in id 1 */
+ apic_version[1] |= 0x10; /* integrated APIC */
+ num_processors = 2;
+
+ return 1;
+}
+#else
X /*
X * Checksum an MP configuration block.
X */
@@ -567,6 +579,7 @@
X
X return 0;
X }
+#endif
X
X /*
X * Trampoline 80x86 program as an array.
@@ -673,7 +686,9 @@
X memory_start = PAGE_ALIGN(memory_start);
X if (smp_found_config) {
X apic_phys = mp_lapic_addr;
+#ifdef CONFIG_X86_IO_APIC
X ioapic_phys = mp_ioapic_addr;
+#endif
X } else {
X /*
X * set up a fake all zeroes page to simulate the
@@ -687,11 +702,13 @@
X memory_start += 2*PAGE_SIZE;
X }
X
+#ifdef CONFIG_X86_IO_APIC
X set_fixmap(FIX_APIC_BASE,apic_phys);
X set_fixmap(FIX_IO_APIC_BASE,ioapic_phys);
X
X printk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
X printk("mapped IOAPIC to %08lx (%08lx)\n", fix_to_virt(FIX_IO_APIC_BASE), ioapic_phys);
+#endif
X
X return memory_start;
X }
@@ -1117,6 +1134,7 @@
X
X cpu_number_map[boot_cpu_id] = 0;
X
+#ifdef CONFIG_X86_IO_APIC
X /*
X * If we don't conform to the Intel MPS standard, get out
X * of here now!
@@ -1129,6 +1147,7 @@
X cpu_online_map = cpu_present_map;
X goto smp_done;
X }
+#endif
X
X /*
X * If SMP should be disabled, then really disable it!
@@ -1282,14 +1301,15 @@
X SMP_PRINTK(("Boot done.\n"));
X
X cache_APIC_registers();
+#ifdef CONFIG_X86_IO_APIC
X /*
X * Here we can be sure that there is an IO-APIC in the system. Let's
X * go and set it up:
X */
X if (!skip_ioapic_setup)
X setup_IO_APIC();
-
X smp_done:
+#endif
X }
X
X
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- v2.2.0-pre8/linux/arch/i386/kernel/time.c Fri Jan 1 12:58:19 1999
+++ linux/arch/i386/kernel/time.c Wed Jan 20 10:18:53 1999
@@ -12,6 +12,8 @@
X * precision CMOS clock update
X * 1996-05-03 Ingo Molnar
X * fixed time warps in do_[slow|fast]_gettimeoffset()
+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills
X * 1998-09-05 (Various)
X * More robust do_fast_gettimeoffset() algorithm implemented
X * (works with APM, Cyrix 6x86MX and Centaur C6),
@@ -63,12 +65,14 @@
X #include <linux/timex.h>
X #include <linux/config.h>
X
+#include <asm/fixmap.h>
+#include <asm/cobalt.h>
+
X /*
X * for x86_do_profile()
X */
X #include "irq.h"
X
-extern int setup_x86_irq(int, struct irqaction *);
X
X unsigned long cpu_hz; /* Detected as we calibrate the TSC */
X
@@ -286,9 +290,11 @@
X }
X
X xtime = *tv;
- time_state = TIME_BAD;
- time_maxerror = MAXPHASE;
- time_esterror = MAXPHASE;
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR; /* p. 24, (a) */
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
X write_unlock_irq(&xtime_lock);
X }
X
@@ -366,6 +372,10 @@
X */
X static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
X {
+#ifdef CONFIG_VISWS
+ /* Clear the interrupt */
+ co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
+#endif
X do_timer(regs);
X /*
X * In the SMP case we use the local APIC timer interrupt to do the
@@ -385,9 +395,10 @@
X * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
X * called as close as possible to 500 ms before the new second starts.
X */
- if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
- xtime.tv_usec > 500000 - (tick >> 1) &&
- xtime.tv_usec < 500000 + (tick >> 1)) {
+ if ((time_status & STA_UNSYNC) == 0 &&
+ xtime.tv_sec > last_rtc_update + 660 &&
+ xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+ xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
X if (set_rtc_mmss(xtime.tv_sec) == 0)
X last_rtc_update = xtime.tv_sec;
X else
@@ -663,5 +674,22 @@
X printk("Detected %ld Hz processor.\n", cpu_hz);
X }
X }
+
+#ifdef CONFIG_VISWS
+ printk("Starting Cobalt Timer system clock\n");
+
+ /* Set the countdown value */
+ co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ);
+
+ /* Start the timer */
+ co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN);
+
+ /* Enable (unmask) the timer interrupt */
+ co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
+
+ /* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */
+ setup_x86_irq(CO_IRQ_TIMER, &irq0);
+#else
X setup_x86_irq(0, &irq0);
+#endif
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- v2.2.0-pre8/linux/arch/i386/kernel/traps.c Mon Dec 28 15:00:52 1998
+++ linux/arch/i386/kernel/traps.c Wed Jan 20 10:18:53 1999
@@ -34,6 +34,14 @@
X #include <asm/debugreg.h>
X #include <asm/desc.h>
X
+#include <asm/smp.h>
+
+#ifdef CONFIG_X86_VISWS_APIC
+#include <asm/fixmap.h>
+#include <asm/cobalt.h>
+#include <asm/lithium.h>
+#endif
+
X asmlinkage int system_call(void);
X asmlinkage void lcall7(void);
X
@@ -569,9 +577,100 @@
X _set_tssldt_desc(gdt_table+FIRST_LDT_ENTRY+(n<<1), (int)addr, ((size << 3) - 1), 0x82);
X }
X
+#ifdef CONFIG_X86_VISWS_APIC
+
+/*
+ * On Rev 005 motherboards legacy device interrupt lines are wired directly
+ * to Lithium from the 307. But the PROM leaves the interrupt type of each
+ * 307 logical device set appropriate for the 8259. Later we'll actually use
+ * the 8259, but for now we have to flip the interrupt types to
+ * level triggered, active lo as required by Lithium.
+ */
+
+#define REG 0x2e /* The register to read/write */
+#define DEV 0x07 /* Register: Logical device select */
+#define VAL 0x2f /* The value to read/write */
+
+static void
+superio_outb(int dev, int reg, int val)
+{
+ outb(DEV, REG);
+ outb(dev, VAL);
+ outb(reg, REG);
+ outb(val, VAL);
+}
+
+static int __attribute__ ((unused))
+superio_inb(int dev, int reg)
+{
+ outb(DEV, REG);
+ outb(dev, VAL);
+ outb(reg, REG);
+ return inb(VAL);
+}
+
+#define FLOP 3 /* floppy logical device */
+#define PPORT 4 /* parallel logical device */
+#define UART5 5 /* uart2 logical device (not wired up) */
+#define UART6 6 /* uart1 logical device (THIS is the serial port!) */
+#define IDEST 0x70 /* int. destination (which 307 IRQ line) reg. */
+#define ITYPE 0x71 /* interrupt type register */
+
+/* interrupt type bits */
+#define LEVEL 0x01 /* bit 0, 0 == edge triggered */
+#define ACTHI 0x02 /* bit 1, 0 == active lo */
+
+static void
+superio_init(void)
+{
+ if (visws_board_type == VISWS_320 && visws_board_rev == 5) {
+ superio_outb(UART6, IDEST, 0); /* 0 means no intr propagated */
+ printk("SGI 320 rev 5: disabling 307 uart1 interrupt\n");
+ }
+}
+
+static void
+lithium_init(void)
+{
+ set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS);
+ printk("Lithium PCI Bridge A, Bus Number: %d\n",
+ li_pcia_read16(LI_PCI_BUSNUM) & 0xff);
+ set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS);
+ printk("Lithium PCI Bridge B (PIIX4), Bus Number: %d\n",
+ li_pcib_read16(LI_PCI_BUSNUM) & 0xff);
+
+ /* XXX blindly enables all interrupts */
+ li_pcia_write16(LI_PCI_INTEN, 0xffff);
+ li_pcib_write16(LI_PCI_INTEN, 0xffff);
+}
+
+static void
+cobalt_init(void)
+{
+ /*
+ * On normal SMP PC this is used only with SMP, but we have to
+ * use it and set it up here to start the Cobalt clock
+ */
+ set_fixmap(FIX_APIC_BASE, APIC_PHYS_BASE);
+ printk("Local APIC ID %lx\n", apic_read(APIC_ID));
+ printk("Local APIC Version %lx\n", apic_read(APIC_VERSION));
+
+ set_fixmap(FIX_CO_CPU, CO_CPU_PHYS);
+ printk("Cobalt Revision %lx\n", co_cpu_read(CO_CPU_REV));
+
+ set_fixmap(FIX_CO_APIC, CO_APIC_PHYS);
+ printk("Cobalt APIC ID %lx\n", co_apic_read(CO_APIC_ID));
+
+ /* Enable Cobalt APIC being careful to NOT change the ID! */
+ co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID)|CO_APIC_ENABLE);
+
+ printk("Cobalt APIC enabled: ID reg %lx\n", co_apic_read(CO_APIC_ID));
+}
+#endif
X void __init trap_init(void)
X {
- int i;
+ /* Initially up all of the IDT to jump to unexpected */
+ init_unexpected_irq();
X
X if (readl(0x0FFFD9) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
X EISA_bus = 1;
@@ -594,8 +693,6 @@
X set_trap_gate(15,&spurious_interrupt_bug);
X set_trap_gate(16,&coprocessor_error);
X set_trap_gate(17,&alignment_check);
- for (i=18;i<48;i++)
- set_trap_gate(i,&reserved);
X set_system_gate(0x80,&system_call);
X
X /* set up GDT task & ldt entries */
@@ -606,4 +703,9 @@
X __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
X load_TR(0);
X load_ldt(0);
SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi
echo 'End of part 01'
echo 'File patch-2.2.0-pre9 is continued in part 02'
echo 02 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part02

#!/bin/sh
# this is part 02 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh

# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 02; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'


sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

+#ifdef CONFIG_X86_VISWS_APIC
+ superio_init();
+ lithium_init();
+ cobalt_init();
+#endif
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/i386/kernel/visws_apic.c linux/arch/i386/kernel/visws_apic.c
--- v2.2.0-pre8/linux/arch/i386/kernel/visws_apic.c Wed Dec 31 16:00:00 1969
+++ linux/arch/i386/kernel/visws_apic.c Wed Jan 20 10:18:53 1999
@@ -0,0 +1,407 @@
+/*
+ * linux/arch/i386/kernel/visws_apic.c
+ *
+ * Copyright (C) 1999 Bent Hagemark, Ingo Molnar
+ *
+ * SGI Visual Workstation interrupt controller
+ *
+ * The Cobalt system ASIC in the Visual Workstation contains a "Cobalt" APIC
+ * which serves as the main interrupt controller in the system. Non-legacy
+ * hardware in the system uses this controller directly. Legacy devices
+ * are connected to the PIIX4 which in turn has its 8259(s) connected to
+ * a of the Cobalt APIC entry.
+ */
+
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/malloc.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/tasks.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/smp.h>
+#include <asm/pgtable.h>
+#include <asm/delay.h>
+#include <asm/desc.h>
+
+#include <asm/cobalt.h>
+
+#include "irq.h"
+
+/*
+ * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt
+ * -- not the manner expected by the normal 8259 code in irq.c.
+ *
+ * there is a 'master' physical interrupt source that gets sent to
+ * the CPU. But in the chipset there are various 'virtual' interrupts
+ * waiting to be handled. We represent this to Linux through a 'master'
+ * interrupt controller type, and through a special virtual interrupt-
+ * controller. Device drivers only see the virtual interrupt sources.
+ */
+
+#define CO_IRQ_BASE 0x20 /* This is the 0x20 in init_IRQ()! */
+
+static void startup_piix4_master_irq(unsigned int irq);
+static void shutdown_piix4_master_irq(unsigned int irq);
+static void do_piix4_master_IRQ(unsigned int irq, struct pt_regs * regs);
+#define enable_piix4_master_irq startup_piix4_master_irq
+#define disable_piix4_master_irq shutdown_piix4_master_irq
+
+static struct hw_interrupt_type piix4_master_irq_type = {
+ "PIIX4-master",
+ startup_piix4_master_irq,
+ shutdown_piix4_master_irq,
+ do_piix4_master_IRQ,
+ enable_piix4_master_irq,
+ disable_piix4_master_irq
+};
+
+static void enable_piix4_virtual_irq(unsigned int irq);
+static void disable_piix4_virtual_irq(unsigned int irq);
+#define startup_piix4_virtual_irq enable_piix4_virtual_irq
+#define shutdown_piix4_virtual_irq disable_piix4_virtual_irq
+
+static struct hw_interrupt_type piix4_virtual_irq_type = {
+ "PIIX4-virtual",
+ startup_piix4_virtual_irq,
+ shutdown_piix4_virtual_irq,
+ 0, /* no handler, it's never called physically */
+ enable_piix4_virtual_irq,
+ disable_piix4_virtual_irq
+};
+
+/*
+ * This is the SGI Cobalt (IO-)APIC:
+ */
+
+static void do_cobalt_IRQ(unsigned int irq, struct pt_regs * regs);
+static void enable_cobalt_irq(unsigned int irq);
+static void disable_cobalt_irq(unsigned int irq);
+static void startup_cobalt_irq(unsigned int irq);
+#define shutdown_cobalt_irq disable_cobalt_irq
+
+static struct hw_interrupt_type cobalt_irq_type = {
+ "Cobalt-APIC",
+ startup_cobalt_irq,
+ shutdown_cobalt_irq,
+ do_cobalt_IRQ,
+ enable_cobalt_irq,
+ disable_cobalt_irq
+};
+
+
+/*
+ * Not an initfunc, needed by the reboot code
+ */
+void init_pic_mode(void)
+{
+ /* Nop on Cobalt */
+}
+
+/*
+ * Cobalt (IO)-APIC functions to handle PCI devices.
+ */
+
+static void disable_cobalt_irq(unsigned int irq)
+{
+ /* XXX undo the APIC entry here? */
+
+ /*
+ * definitely, we do not want to have IRQ storms from
+ * unused devices --mingo
+ */
+}
+
+static void enable_cobalt_irq(unsigned int irq)
+{
+}
+
+/*
+ * Set the given Cobalt APIC Redirection Table entry to point
+ * to the given IDT vector/index.
+ */
+static void co_apic_set(int entry, int idtvec)
+{
+ co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (CO_IRQ_BASE+idtvec));
+ co_apic_write(CO_APIC_HI(entry), 0);
+
+ printk("Cobalt APIC Entry %d IDT Vector %d\n", entry, idtvec);
+}
+
+/*
+ * "irq" really just serves to identify the device. Here is where we
+ * map this to the Cobalt APIC entry where it's physically wired.
+ * This is called via request_irq -> setup_x86_irq -> irq_desc->startup()
+ */
+static void startup_cobalt_irq(unsigned int irq)
+{
+ /*
+ * These "irq"'s are wired to the same Cobalt APIC entries
+ * for all (known) motherboard types/revs
+ */
+ switch (irq) {
+ case CO_IRQ_TIMER: co_apic_set(CO_APIC_CPU, CO_IRQ_TIMER);
+ return;
+
+ case CO_IRQ_ENET: co_apic_set(CO_APIC_ENET, CO_IRQ_ENET);
+ return;
+
+ case CO_IRQ_SERIAL: return; /* XXX move to piix4-8259 "virtual" */
+
+ case CO_IRQ_8259: co_apic_set(CO_APIC_8259, CO_IRQ_8259);
+ return;
+
+ case CO_IRQ_IDE:
+ switch (visws_board_type) {
+ case VISWS_320:
+ switch (visws_board_rev) {
+ case 5:
+ co_apic_set(CO_APIC_0_5_IDE0, CO_IRQ_IDE);
+ co_apic_set(CO_APIC_0_5_IDE1, CO_IRQ_IDE);
+ return;
+ case 6:
+ co_apic_set(CO_APIC_0_6_IDE0, CO_IRQ_IDE);
+ co_apic_set(CO_APIC_0_6_IDE1, CO_IRQ_IDE);
+ return;
+ }
+ case VISWS_540:
+ switch (visws_board_rev) {
+ case 2:
+ co_apic_set(CO_APIC_1_2_IDE0, CO_IRQ_IDE);
+ return;
+ }
+ }
+ break;
+ default:
+ panic("huh?");
+ }
+}
+
+/*
+ * This is the handle() op in do_IRQ()
+ */
+static void do_cobalt_IRQ(unsigned int irq, struct pt_regs * regs)


+{
+ struct irqaction * action;
+ irq_desc_t *desc = irq_desc + irq;
+
+ spin_lock(&irq_controller_lock);
+ {
+ unsigned int status;

+ /* XXX APIC EOI? */


+ status = desc->status & ~IRQ_REPLAY;
+ action = NULL;
+ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ action = desc->action;
+ desc->status = status | IRQ_INPROGRESS;
+ }
+ spin_unlock(&irq_controller_lock);
+
+ /* Exit early if we had no action or it was disabled */
+ if (!action)
+ return;
+
+ handle_IRQ_event(irq, regs, action);
+

+ (void)co_cpu_read(CO_CPU_REV); /* Sync driver ack to its h/w */
+ apic_write(APIC_EOI, APIC_EIO_ACK); /* Send EOI to Cobalt APIC */


+
+ spin_lock(&irq_controller_lock);
+ {
+ unsigned int status = desc->status & ~IRQ_INPROGRESS;
+ desc->status = status;
+ if (!(status & IRQ_DISABLED))

+ enable_cobalt_irq(irq);


+ }
+ spin_unlock(&irq_controller_lock);
+}
+

+/*
+ * PIIX4-8259 master/virtual functions to handle:
+ *
+ * floppy
+ * parallel
+ * serial
+ * audio (?)
+ *
+ * None of these get Cobalt APIC entries, neither do they have IDT
+ * entries. These interrupts are purely virtual and distributed from
+ * the 'master' interrupt source: CO_IRQ_8259.
+ *
+ * When the 8259 interrupts its handler figures out which of these
+ * devices is interrupting and dispatches to it's handler.
+ *
+ * CAREFUL: devices see the 'virtual' interrupt only. Thus disable/
+ * enable_irq gets the right irq. This 'master' irq is never directly
+ * manipulated by any driver.
+ */
+
+static void startup_piix4_master_irq(unsigned int irq)
+{
+ /* ICW1 */
+ outb(0x11, 0x20);
+ outb(0x11, 0xa0);
+
+ /* ICW2 */
+ outb(0x08, 0x21);
+ outb(0x70, 0xa1);
+
+ /* ICW3 */
+ outb(0x04, 0x21);
+ outb(0x02, 0xa1);
+
+ /* ICW4 */
+ outb(0x01, 0x21);
+ outb(0x01, 0xa1);
+
+ /* OCW1 - disable all interrupts in both 8259's */
+ outb(0xff, 0x21);
+ outb(0xff, 0xa1);
+
+ startup_cobalt_irq(irq);
+}
+
+static void shutdown_piix4_master_irq(unsigned int irq)
+{
+ /*
+ * [we skip the 8259 magic here, not strictly necessary]
+ */
+
+ shutdown_cobalt_irq(irq);
+}
+
+static void do_piix4_master_IRQ(unsigned int irq, struct pt_regs * regs)
+{
+ int realirq, mask;
+
+ /* Find out what's interrupting in the PIIX4 8259 */
+
+ spin_lock(&irq_controller_lock);
+ outb(0x0c, 0x20); /* OCW3 Poll command */
+ realirq = inb(0x20);
+
+ if (!(realirq & 0x80)) {
+ /*
+ * Bit 7 == 0 means invalid/spurious
+ */
+ goto out_unlock;
+ }
+ realirq &= 0x7f;
+
+ /*
+ * mask and ack the 8259
+ */
+ mask = inb(0x21);
+ if ((mask >> realirq) & 0x01)
+ /*
+ * This IRQ is masked... ignore
+ */
+ goto out_unlock;
+
+ outb(mask | (1<<realirq), 0x21);
+ /*
+ * OCW2 - non-specific EOI
+ */
+ outb(0x20, 0x20);


+
+ spin_unlock(&irq_controller_lock);
+
+ /*

+ * handle this 'virtual interrupt' as a Cobalt one now.
+ */
+ kstat.irqs[smp_processor_id()][irq]++;
+ do_cobalt_IRQ(realirq, regs);
+
+ spin_lock(&irq_controller_lock);
+ {
+ irq_desc_t *desc = irq_desc + realirq;
+
+ if (!(desc->status & IRQ_DISABLED))
+ enable_piix4_virtual_irq(realirq);
+ }
+ spin_unlock(&irq_controller_lock);
+ return;
+
+out_unlock:
+ spin_unlock(&irq_controller_lock);
+ return;
+}
+
+static void enable_piix4_virtual_irq(unsigned int irq)
+{
+ /*
+ * assumes this irq is one of the legacy devices
+ */
+
+ unsigned int mask = inb(0x21);
+ mask &= ~(1 << irq);
+ outb(mask, 0x21);
+ enable_cobalt_irq(irq);
+}
+
+/*
+ * assumes this irq is one of the legacy devices
+ */
+static void disable_piix4_virtual_irq(unsigned int irq)
+{
+ unsigned int mask;
+
+ disable_cobalt_irq(irq);
+
+ mask = inb(0x21);
+ mask &= ~(1 << irq);
+ outb(mask, 0x21);
+}
+
+static struct irqaction master_action =
+ { no_action, 0, 0, "PIIX4-8259", NULL, NULL };
+
+void init_VISWS_APIC_irqs(void)


+{
+ int i;
+

+ for (i = 0; i < 16; i++) {
+ irq_desc[i].status = IRQ_DISABLED;


+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 0;
+

+ /*
+ * Cobalt IRQs are mapped to standard ISA
+ * interrupt vectors:
+ */
+ switch (i) {
+ /*
+ * Only CO_IRQ_8259 will be raised
+ * externally.
+ */
+ case CO_IRQ_8259:
+ irq_desc[i].handler = &piix4_master_irq_type;
+ break;
+ case CO_IRQ_FLOPPY:
+ case CO_IRQ_PARLL:
+ irq_desc[i].handler = &piix4_virtual_irq_type;
+ break;
+ default:
+ irq_desc[i].handler = &cobalt_irq_type;
+ break;
+ }
+ }
+
+ /*
+ * The master interrupt is always present:
+ */
+ setup_x86_irq(CO_IRQ_8259, &master_action);
+}
+
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/Makefile linux/arch/m68k/Makefile
--- v2.2.0-pre8/linux/arch/m68k/Makefile Thu Jan 7 15:11:36 1999
+++ linux/arch/m68k/Makefile Tue Jan 19 10:58:26 1999
@@ -29,12 +29,19 @@
X # without -fno-strength-reduce the 53c7xx.c driver fails ;-(
X CFLAGS += -pipe -fno-strength-reduce -ffixed-a2
X
-ifdef CONFIG_OPTIMIZE_040
+# enable processor switch if compiled only for a single cpu
+ifndef CONFIG_M68020
+ifndef CONFIG_M68030
+
+ifndef CONFIG_M68060
X CFLAGS := $(CFLAGS) -m68040
X endif
X
-ifdef CONFIG_OPTIMIZE_060
+ifndef CONFIG_M68040
X CFLAGS := $(CFLAGS) -m68060
+endif
+
+endif
X endif
X
X ifdef CONFIG_KGDB
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/amiga/config.c linux/arch/m68k/amiga/config.c
--- v2.2.0-pre8/linux/arch/m68k/amiga/config.c Fri Oct 9 13:27:05 1998
+++ linux/arch/m68k/amiga/config.c Tue Jan 19 10:58:26 1999
@@ -52,7 +52,6 @@
X /* amiga specific keyboard functions */
X extern int amiga_keyb_init(void);
X extern int amiga_kbdrate (struct kbd_repeat *);
-extern void amiga_kbd_reset_setup(char*, int);
X /* amiga specific irq functions */
X extern void amiga_init_IRQ (void);
X extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *);
@@ -343,7 +342,6 @@
X mach_sched_init = amiga_sched_init;
X mach_keyb_init = amiga_keyb_init;
X mach_kbdrate = amiga_kbdrate;
- kbd_reset_setup = amiga_kbd_reset_setup;
X mach_init_IRQ = amiga_init_IRQ;
X mach_default_handler = &amiga_default_handler;
X mach_request_irq = amiga_request_irq;
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/atari/atakeyb.c linux/arch/m68k/atari/atakeyb.c
--- v2.2.0-pre8/linux/arch/m68k/atari/atakeyb.c Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/atari/atakeyb.c Tue Jan 19 10:58:26 1999
@@ -861,8 +861,3 @@
X
X return( 0 );
X }
-
-/* for "kbd-reset" cmdline param */
-__initfunc(void atari_kbd_reset_setup(char *str, int *ints))
-{
-}
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/atari/config.c linux/arch/m68k/atari/config.c
--- v2.2.0-pre8/linux/arch/m68k/atari/config.c Sat Sep 5 16:46:40 1998
+++ linux/arch/m68k/atari/config.c Tue Jan 19 10:58:26 1999
@@ -60,7 +60,6 @@
X extern int atari_keyb_init(void);
X extern int atari_kbdrate (struct kbd_repeat *);
X extern void atari_kbd_leds (unsigned int);
-extern void atari_kbd_reset_setup(char*, int);
X /* atari specific irq functions */
X extern void atari_init_IRQ (void);
X extern int atari_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
@@ -251,7 +250,6 @@
X mach_keyb_init = atari_keyb_init;
X mach_kbdrate = atari_kbdrate;
X mach_kbd_leds = atari_kbd_leds;
- kbd_reset_setup = atari_kbd_reset_setup;
X mach_init_IRQ = atari_init_IRQ;
X mach_request_irq = atari_request_irq;
X mach_free_irq = atari_free_irq;
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.2.0-pre8/linux/arch/m68k/config.in Tue Jan 19 11:32:51 1999
+++ linux/arch/m68k/config.in Tue Jan 19 10:58:26 1999
@@ -44,6 +44,7 @@
X if [ "$CONFIG_HP300" = "y" ]; then
X bool 'DIO bus support' CONFIG_DIO
X fi
+define_bool CONFIG_SUN3 n
X if [ "$CONFIG_PCI" = "y" ]; then


X bool 'Backward-compatible /proc/pci' CONFIG_PCI_OLD_PROC
X fi

@@ -129,24 +130,24 @@
X comment 'SCSI low-level drivers'
X
X if [ "$CONFIG_AMIGA" = "y" ]; then
- tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI
+ dep_tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI $CONFIG_SCSI
X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
X bool 'A4000T SCSI support' CONFIG_A4000T_SCSI
X fi
X fi
X if [ "$CONFIG_ZORRO" = "y" ]; then
- tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI
- tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
- bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI
- bool 'CyberStorm Mk II SCSI support' CONFIG_CYBERSTORMII_SCSI
- bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI
- bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI
- bool 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI
+ dep_tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI $CONFIG_SCSI
+ dep_tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI $CONFIG_SCSI
+ dep_tristate 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI $CONFIG_SCSI
+ dep_tristate 'CyberStorm Mk II SCSI support' CONFIG_CYBERSTORMII_SCSI $CONFIG_SCSI
+ dep_tristate 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI $CONFIG_SCSI
+ dep_tristate 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI $CONFIG_SCSI
+ dep_tristate 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI $CONFIG_SCSI
X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
X bool 'A4091 SCSI support' CONFIG_A4091_SCSI
X bool 'WarpEngine SCSI support' CONFIG_WARPENGINE_SCSI
X bool 'Blizzard PowerUP 603e+ SCSI' CONFIG_BLZ603EPLUS_SCSI
-# bool 'Cyberstorm Mk III SCSI support' CONFIG_CYBERSTORMIII_SCSI
+ bool 'Cyberstorm Mk III SCSI support' CONFIG_CYBERSTORMIII_SCSI
X # bool 'GVP Turbo 040/060 SCSI support' CONFIG_GVP_TURBO_SCSI
X fi
X fi
@@ -162,7 +163,7 @@
X fi
X if [ "$CONFIG_MAC" = "y" ]; then
X bool 'MAC NCR5380 SCSI' CONFIG_MAC_SCSI
- bool 'MAC NCR53c9[46] SCSI' CONFIG_SCSI_MAC_ESP
+ dep_tristate 'MAC NCR53c9[46] SCSI' CONFIG_SCSI_MAC_ESP $CONFIG_SCSI
X fi
X #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI
X
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/defconfig linux/arch/m68k/defconfig
--- v2.2.0-pre8/linux/arch/m68k/defconfig Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/defconfig Tue Jan 19 10:58:26 1999
@@ -75,21 +75,26 @@
X #
X # Networking options
X #
+CONFIG_PACKET=y
X # CONFIG_NETLINK is not set
X # CONFIG_FIREWALL is not set
X # CONFIG_NET_ALIAS is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
X CONFIG_INET=y
X # CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ACCT is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
X # CONFIG_IP_ROUTER is not set
X # CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
X
X #
X # (it is safe to leave these untouched)
X #
-# CONFIG_INET_PCTCP is not set
X # CONFIG_INET_RARP is not set
-CONFIG_PATH_MTU_DISCOVERY=y
X CONFIG_IP_NOSR=y
X # CONFIG_SKB_LARGE is not set
X # CONFIG_IPV6 is not set
@@ -99,8 +104,20 @@
X #
X # CONFIG_IPX is not set
X # CONFIG_ATALK is not set
-# CONFIG_AX25 is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
X # CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+# CONFIG_CPU_IS_SLOW is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
X
X #
X # SCSI support
@@ -113,12 +130,15 @@
X CONFIG_BLK_DEV_SD=y
X CONFIG_CHR_DEV_ST=y
X CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
X # CONFIG_CHR_DEV_SG is not set
X
X #
X # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
X #
X # CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
X
X #
X # SCSI low-level drivers
@@ -147,6 +167,7 @@
X # CONFIG_SLIP is not set
X # CONFIG_PPP is not set
X # CONFIG_ARIADNE is not set
+# CONFIG_ARIADNE2 is not set
X # CONFIG_A2065 is not set
X # CONFIG_HYDRA is not set
X # CONFIG_APNE is not set
@@ -184,7 +205,10 @@
X CONFIG_FB_AMIGA_ECS=y
X CONFIG_FB_AMIGA_AGA=y
X # CONFIG_FB_CYBER is not set
+# CONFIG_FB_VIRGE is not set
+# CONFIG_FB_CVPPC is not set
X # CONFIG_FB_RETINAZ3 is not set
+# CONFIG_FB_CLGEN is not set
X # CONFIG_FB_ATARI is not set
X # CONFIG_FB_VIRTUAL is not set
X # CONFIG_FBCON_ADVANCED is not set
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/fpsp040/skeleton.S linux/arch/m68k/fpsp040/skeleton.S
--- v2.2.0-pre8/linux/arch/m68k/fpsp040/skeleton.S Tue Aug 18 22:02:03 1998
+++ linux/arch/m68k/fpsp040/skeleton.S Tue Jan 19 10:58:26 1999
@@ -40,6 +40,7 @@
X
X #include <linux/linkage.h>
X #include <asm/entry.h>
+#include "../kernel/m68k_defs.h"
X
X |SKELETON idnt 2,1 | Motorola 040 Floating Point Software Package
X
@@ -375,12 +376,12 @@
X .global fpsp_done
X fpsp_done:
X btst #0x5,%sp@ | supervisor bit set in saved SR?
- beq Lnotkern
+ beq .Lnotkern
X rte
-Lnotkern:
+.Lnotkern:
X SAVE_ALL_INT
X GET_CURRENT(%d0)
- tstl %curptr@(LTASK_NEEDRESCHED)
+ tstl %curptr@(TASK_NEEDRESCHED)
X jne SYMBOL_NAME(ret_from_exception) | deliver signals,
X | reschedule etc..
X RESTORE_ALL
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/hp300/config.c linux/arch/m68k/hp300/config.c
--- v2.2.0-pre8/linux/arch/m68k/hp300/config.c Sat Sep 5 16:46:40 1998
+++ linux/arch/m68k/hp300/config.c Tue Jan 19 10:58:26 1999
@@ -55,11 +55,6 @@
X {
X }
X
-/* for "kbd-reset" cmdline param */
-__initfunc(void hp300_kbd_reset_setup(char *str, int i))
-{
-}
-
X static void hp300_get_model(char *model)
X {
X strcpy(model, "HP9000/300");
@@ -74,7 +69,6 @@
X mach_init_IRQ = hp300_init_IRQ;
X mach_request_irq = hp300_request_irq;
X mach_free_irq = hp300_free_irq;
- kbd_reset_setup = hp300_kbd_reset_setup;
X mach_get_model = hp300_get_model;
X mach_get_irq_list = hp300_get_irq_list;
X mach_gettimeoffset = hp300_gettimeoffset;
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/ifpsp060/iskeleton.S linux/arch/m68k/ifpsp060/iskeleton.S
--- v2.2.0-pre8/linux/arch/m68k/ifpsp060/iskeleton.S Mon Aug 3 12:45:44 1998
+++ linux/arch/m68k/ifpsp060/iskeleton.S Tue Jan 19 10:58:26 1999
@@ -36,6 +36,7 @@
X
X #include <linux/linkage.h>
X #include <asm/entry.h>
+#include "../kernel/m68k_defs.h"
X
X
X |################################
@@ -69,12 +70,12 @@
X .global _060_isp_done
X _060_isp_done:
X btst #0x5,%sp@ | supervisor bit set in saved SR?
- beq Lnotkern
+ beq .Lnotkern
X rte
-Lnotkern:
+.Lnotkern:
X SAVE_ALL_INT
X GET_CURRENT(%d0)
- tstl %curptr@(LTASK_NEEDRESCHED)
+ tstl %curptr@(TASK_NEEDRESCHED)
X jne SYMBOL_NAME(ret_from_exception) | deliver signals,
X | reschedule etc..
X RESTORE_ALL
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/kernel/entry.S linux/arch/m68k/kernel/entry.S
--- v2.2.0-pre8/linux/arch/m68k/kernel/entry.S Fri Oct 9 13:27:05 1998
+++ linux/arch/m68k/kernel/entry.S Tue Jan 19 10:58:26 1999
@@ -34,8 +34,10 @@
X #include <linux/config.h>
X #include <linux/linkage.h>
X #include <asm/entry.h>
+#include <asm/errno.h>
X #include <asm/setup.h>
X #include <asm/segment.h>
+#include <asm/traps.h>
X
X #include "m68k_defs.h"
X
@@ -43,7 +45,7 @@
X .globl SYMBOL_NAME(resume), SYMBOL_NAME(ret_from_exception)
X .globl SYMBOL_NAME(ret_from_signal)
X .globl SYMBOL_NAME(inthandler), SYMBOL_NAME(sys_call_table)
-.globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone)
+.globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone), SYMBOL_NAME(sys_vfork)
X .globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt)
X
X .text
@@ -65,24 +67,24 @@
X
X ENTRY(reschedule)
X | save top of frame
- movel %sp,%curptr@(TS_ESP0)
+ movel %sp,%curptr@(TASK_TSS+TSS_ESP0)
X
X pea SYMBOL_NAME(ret_from_exception)
X jmp SYMBOL_NAME(schedule)
X
X badsys:
- movel #-LENOSYS,LPT_OFF_D0(%sp)
+ movel #-ENOSYS,PT_D0(%sp)
X jra SYMBOL_NAME(ret_from_exception)
X
X do_trace:
- movel #-LENOSYS,LPT_OFF_D0(%sp) | needed for strace
+ movel #-ENOSYS,PT_D0(%sp) | needed for strace
X subql #4,%sp
X SAVE_SWITCH_STACK
X jbsr SYMBOL_NAME(syscall_trace)
X RESTORE_SWITCH_STACK
X addql #4,%sp
X jbsr @(SYMBOL_NAME(sys_call_table),%d2:l:4)@(0)
- movel %d0,%sp@(LPT_OFF_D0) | save the return value
+ movel %d0,%sp@(PT_D0) | save the return value
X subql #4,%sp | dummy return address
X SAVE_SWITCH_STACK
X jbsr SYMBOL_NAME(syscall_trace)
@@ -98,34 +100,34 @@
X
X GET_CURRENT(%d0)
X | save top of frame
- movel %sp,%curptr@(TS_ESP0)
+ movel %sp,%curptr@(TASK_TSS+TSS_ESP0)
X
X cmpl #NR_syscalls,%d2
X jcc badsys
- btst #LPF_TRACESYS_BIT,%curptr@(LTASK_FLAGS+LPF_TRACESYS_OFF)
+ btst #PF_TRACESYS_BIT,%curptr@(TASK_FLAGS+PF_TRACESYS_OFF)
X jne do_trace
X jbsr @(SYMBOL_NAME(sys_call_table),%d2:l:4)@(0)
- movel %d0,%sp@(LPT_OFF_D0) | save the return value
+ movel %d0,%sp@(PT_D0) | save the return value
X
X SYMBOL_NAME_LABEL(ret_from_exception)
- btst #5,%sp@(LPT_OFF_SR) | check if returning to kernel
+ btst #5,%sp@(PT_SR) | check if returning to kernel
X bnes 2f | if so, skip resched, signals
X | only allow interrupts when we are really the last one on the
X | kernel stack, otherwise stack overflow can occur during
X | heavy interupt load
X andw #ALLOWINT,%sr
- tstl %curptr@(LTASK_NEEDRESCHED)
+ tstl %curptr@(TASK_NEEDRESCHED)
X jne SYMBOL_NAME(reschedule)
X cmpl #SYMBOL_NAME(task),%curptr | task[0] cannot have signals
X jeq 2f
X | check for delayed trace
- bclr #LPF_DTRACE_BIT,%curptr@(LTASK_FLAGS+LPF_DTRACE_OFF)
+ bclr #PF_DTRACE_BIT,%curptr@(TASK_FLAGS+PF_DTRACE_OFF)
X jne do_delayed_trace
X 5:
- tstl %curptr@(LTASK_STATE) | state
+ tstl %curptr@(TASK_STATE) | state
X jne SYMBOL_NAME(reschedule)
X
- tstl %curptr@(LTASK_SIGPENDING)
+ tstl %curptr@(TASK_SIGPENDING)
X jne Lsignal_return
X 2: RESTORE_ALL
X
@@ -141,7 +143,7 @@
X RESTORE_ALL
X
X do_delayed_trace:
- bclr #7,%sp@(LPT_OFF_SR) | clear trace bit in SR
+ bclr #7,%sp@(PT_SR) | clear trace bit in SR
X pea 1 | send SIGTRAP
X movel %curptr,%sp@-
X pea LSIGTRAP
@@ -158,7 +160,7 @@
X GET_CURRENT(%d0)
X addql #1,SYMBOL_NAME(local_irq_count)
X | put exception # in d0
- bfextu %sp@(LPT_OFF_FORMATVEC){#4,#10},%d0
+ bfextu %sp@(PT_VECTOR){#4,#10},%d0
X
X movel %sp,%sp@-
X movel %d0,%sp@- | put vector # on stack
@@ -172,7 +174,7 @@
X RESTORE_ALL
X 1:
X #if 1
- bfextu %sp@(LPT_OFF_SR){#5,#3},%d0 | Check for nested interrupt.
+ bfextu %sp@(PT_SR){#5,#3},%d0 | Check for nested interrupt.
X #if MAX_NOINT_IPL > 0
X cmpiw #MAX_NOINT_IPL,%d0
X #endif
@@ -210,6 +212,14 @@
X RESTORE_SWITCH_STACK
X rts
X
+ENTRY(sys_vfork)
+ SAVE_SWITCH_STACK
+ pea %sp@(SWITCH_STACK_SIZE)
+ jbsr SYMBOL_NAME(m68k_vfork)
+ addql #4,%sp
+ RESTORE_SWITCH_STACK
+ rts
+
X ENTRY(sys_sigsuspend)
X SAVE_SWITCH_STACK
X pea %sp@(SWITCH_STACK_SIZE)
@@ -240,37 +250,31 @@
X
X SYMBOL_NAME_LABEL(resume)
X /*
- * Beware - when entering resume, offset of tss is in d1,
- * prev (the current task) is in a0, next (the new task)
- * is in a1 and d2.b is non-zero if the mm structure is
- * shared between the tasks, so don't change these
+ * Beware - when entering resume, prev (the current task) is
+ * in a0, next (the new task) is in a1,so don't change these
X * registers until their contents are no longer needed.
X */
X
- /* offset of tss struct (processor state) from beginning
- of task struct */
- addl %d1,%a0
-
X /* save sr */
- movew %sr,%a0@(LTSS_SR)
+ movew %sr,%a0@(TASK_TSS+TSS_SR)
X
X /* save fs (sfc,%dfc) (may be pointing to kernel memory) */
X movec %sfc,%d0
- movew %d0,%a0@(LTSS_FS)
+ movew %d0,%a0@(TASK_TSS+TSS_FS)
X
X /* save usp */
X /* it is better to use a movel here instead of a movew 8*) */
X movec %usp,%d0
- movel %d0,%a0@(LTSS_USP)
+ movel %d0,%a0@(TASK_TSS+TSS_USP)
X
X /* save non-scratch registers on stack */
X SAVE_SWITCH_STACK
X
X /* save current kernel stack pointer */
- movel %sp,%a0@(LTSS_KSP)
+ movel %sp,%a0@(TASK_TSS+TSS_KSP)
X
X /* save floating point context */
- fsave %a0@(LTSS_FPCTXT+27*4)
+ fsave %a0@(TASK_TSS+TSS_FPSTATE)
X
X #if defined(CONFIG_M68060)
X #if !defined(CPU_M68060_ONLY)
@@ -278,27 +282,27 @@
X beqs 1f
X #endif
X /* The 060 FPU keeps status in bits 15-8 of the first longword */
- tstb %a0@(LTSS_FPCTXT+27*4+2)
+ tstb %a0@(TASK_TSS+TSS_FPSTATE+2)
X jeq 3f
X #if !defined(CPU_M68060_ONLY)
X jra 2f
X #endif
X #endif /* CONFIG_M68060 */
X #if !defined(CPU_M68060_ONLY)
-1: tstb %a0@(LTSS_FPCTXT+27*4)
+1: tstb %a0@(TASK_TSS+TSS_FPSTATE)
X jeq 3f
X #endif
-2: fmovemx %fp0-%fp7,%a0@(LTSS_FPCTXT)
- fmoveml %fpcr/%fpsr/%fpiar,%a0@(LTSS_FPCTXT+24*4)
+2: fmovemx %fp0-%fp7,%a0@(TASK_TSS+TSS_FPREG)
+ fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_TSS+TSS_FPCNTL)
X 3:
X
- /* get pointer to tss struct (a1 contains new task) */
+ /* switch to new task (a1 contains new task) */
X movel %a1,%curptr
- addl %d1,%a1
X
X /* Skip address space switching if they are the same. */
- tstb %d2
- jne 4f
+ movel %a0@(TASK_MM),%d0
+ cmpl %a1@(TASK_MM),%d0
+ jeq 4f
X
X #if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060)
X /* 68040 or 68060 ? */
@@ -316,7 +320,7 @@
X movec %d0,%cacr
X
X /* switch the root pointer */
- pmove %a1@(LTSS_CRP),%crp
+ pmove %a1@(TASK_TSS+TSS_CRP),%crp
X #endif
X
X #if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060)
@@ -333,7 +337,7 @@
X pflushan
X
X /* switch the root pointer */
- movel %a1@(LTSS_CRP+4),%d0
+ movel %a1@(TASK_TSS+TSS_CRP+4),%d0
X movec %d0,%urp
X
X #if defined (CONFIG_M68060)
@@ -359,37 +363,37 @@
X beqs 1f
X #endif
X /* The 060 FPU keeps status in bits 15-8 of the first longword */
- tstb %a1@(LTSS_FPCTXT+27*4+2)
+ tstb %a1@(TASK_TSS+TSS_FPSTATE+2)
X jeq 3f
X #if !defined(CPU_M68060_ONLY)
X jra 2f
X #endif
X #endif /* CONFIG_M68060 */
X #if !defined(CPU_M68060_ONLY)
-1: tstb %a1@(LTSS_FPCTXT+27*4)
+1: tstb %a1@(TASK_TSS+TSS_FPSTATE)
X jeq 3f
X #endif
-2: fmovemx %a1@(LTSS_FPCTXT),%fp0-%fp7
- fmoveml %a1@(LTSS_FPCTXT+24*4),%fpcr/%fpsr/%fpiar
-3: frestore %a1@(LTSS_FPCTXT+27*4)
+2: fmovemx %a1@(TASK_TSS+TSS_FPREG),%fp0-%fp7
+ fmoveml %a1@(TASK_TSS+TSS_FPCNTL),%fpcr/%fpsr/%fpiar
+3: frestore %a1@(TASK_TSS+TSS_FPSTATE)
X
X /* restore the kernel stack pointer */
- movel %a1@(LTSS_KSP),%sp
+ movel %a1@(TASK_TSS+TSS_KSP),%sp
X
X /* restore non-scratch registers */
X RESTORE_SWITCH_STACK
X
X /* restore user stack pointer */
- movel %a1@(LTSS_USP),%a0
+ movel %a1@(TASK_TSS+TSS_USP),%a0
X movel %a0,%usp
X
X /* restore fs (sfc,%dfc) */
- movew %a1@(LTSS_FS),%a0
+ movew %a1@(TASK_TSS+TSS_FS),%a0
X movec %a0,%sfc
X movec %a0,%dfc
X
X /* restore status register */
- movew %a1@(LTSS_SR),%sr
+ movew %a1@(TASK_TSS+TSS_SR),%sr
X
X rts
X
@@ -586,6 +590,7 @@


X .long SYMBOL_NAME(sys_sendfile)
X .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
X .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */

+ .long SYMBOL_NAME(sys_vfork) /* 190 */
X

X .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
X .long SYMBOL_NAME(sys_ni_syscall)
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/kernel/head.S linux/arch/m68k/kernel/head.S
--- v2.2.0-pre8/linux/arch/m68k/kernel/head.S Tue Jun 23 10:01:21 1998
+++ linux/arch/m68k/kernel/head.S Tue Jan 19 10:58:26 1999
@@ -7,9 +7,12 @@
X **
X ** 68040 fixes by Michael Rausch
X ** 68060 fixes by Roman Hodek
+** MMU cleanup by Randy Thelen
+** Final MMU cleanup by Roman Zippel
X **
X ** Atari support by Andreas Schwab, using ideas of Robert de Vries
X ** and Bjoern Brauel
+** VME Support by Richard Hirst
X **
X ** 94/11/14 Andreas Schwab: put kernel at PAGESIZE
X ** 94/11/18 Andreas Schwab: remove identity mapping of STRAM for Atari
@@ -18,6 +21,8 @@
X ** 96/04/26 Guenther Kelleter: fixed identity mapping for Falcon with
X ** Magnum- and FX-alternate ram
X ** 98/04/25 Phil Blundell: added HP300 support
+** 1998/08/30 David Kilzer: Added support for fbcon_font_desc structures
+** for linux-2.1.115
X **
X ** This file is subject to the terms and conditions of the GNU General Public
X ** License. See the file README.legal in the main directory of this archive
@@ -34,69 +39,275 @@
X * Put us in supervisor state.
X *
X * The kernel setup code takes the following steps:
- * Raise interrupt level
- * Set up initial kernel memory mapping.
- * This sets up a mapping of the 4M of memory the kernel
- * is located in. It also does a mapping of any initial
- * machine specific areas.
- * Note that the kernel is located at virtual address 0x1000 == _start
- * Enable cache memories
- * Jump to kernel startup
- *
- * Register d6 contains the CPU flags and d4 the machine type
- * from the boot_info information for most of this file.
- * The upper word of d6 contains a bit for '040 or '060, since these two
- * are quite similar for initial mm setup. Another bit in d6 allows
- * distinction of the '060. The lower word of d6 contains the cache mode
- * that should be applied to pages containing descriptors. This mode is
- * non-cached/non-serialized for the '040 and cacheable/write-through for
- * the '060.
- *
- * General register usage:
- * a6 - start of unused memory
- * new pages can be allocated from here
- * a5 - mmu root table
- * a4 - mmu pointer table
- * a3 - mmu page tables
- * a2 - points to the page table entry for a6
- * cache status can be changed (used for '0[46]0)
- * you must increase a2 if alloc a new page
- * d7 - used for debug output and some macros
- * d6 - cpu type and cache mode
- * d5 - physical start address of kernel
- * d4 - machine type
+ * . Raise interrupt level
+ * . Set up initial kernel memory mapping.
+ * . This sets up a mapping of the 4M of memory the kernel is located in.
+ * . It also does a mapping of any initial machine specific areas.
+ * . Enable the MMU
+ * . Enable cache memories
+ * . Jump to kernel startup
+ *
+ * Much of the file restructuring was to accomplish:
+ * 1) Remove register dependency through-out the file.
+ * 2) Increase use of subroutines to perform functions
+ * 3) Increase readability of the code
+ *
+ * Of course, readability is a subjective issue, so it will never be
+ * argued that that goal was accomplished. It was merely a goal.
+ * A key way to help make code more readable is to give good
+ * documentation. So, the first thing you will find is exaustive
+ * write-ups on the structure of the file, and the features of the
+ * functional subroutines.
+ *
+ * General Structure:
+ * ------------------
+ * Without a doubt the single largest chunk of head.S is spent
+ * mapping the kernel and I/O physical space into the logical range
+ * for the kernel.
+ * There are new subroutines and data structures to make MMU
+ * support cleaner and easier to understand.
+ * First, you will find a routine call "mmu_map" which maps
+ * a logical to a physical region for some length given a cache
+ * type on behalf of the caller. This routine makes writing the
+ * actual per-machine specific code very simple.
+ * A central part of the code, but not a subroutine in itself,
+ * is the mmu_init code which is broken down into mapping the kernel
+ * (the same for all machines) and mapping machine-specific I/O
+ * regions.
+ * Also, there will be a description of engaging the MMU and
+ * caches.
+ * You will notice that there is a chunk of code which
+ * can emit the entire MMU mapping of the machine. This is present
+ * only in debug modes and can be very helpful.
+ * Further, there is a new console driver in head.S that is
+ * also only engaged in debug mode. Currently, it's only supported
+ * on the Macintosh class of machines. However, it is hoped that
+ * others will plug-in support for specific machines.
+ *
+ * ######################################################################
+ *
+ * mmu_map
+ * -------
+ * mmu_map was written for two key reasons. First, it was clear
+ * that it was very difficult to read the previous code for mapping
+ * regions of memory. Second, the Macintosh required such extensive
+ * memory allocations that it didn't make sense to propogate the
+ * existing code any further.
+ * mmu_map requires some parameters:
+ *
+ * mmu_map (logical, physical, length, cache_type)
+ *
+ * While this essentially describes the function in the abstract, you'll
+ * find more indepth description of other parameters at the implementation site.
+ *
+ * mmu_get_root_table_entry
+ * ------------------------
+ * mmu_get_ptr_table_entry
+ * -----------------------
+ * mmu_get_page_table_entry
+ * ------------------------
+ *
+ * These routines are used by other mmu routines to get a pointer into
+ * a table, if necessary a new table is allocated. These routines are working
+ * basically like pmd_alloc() and pte_alloc() in <asm/pgtable.h>. The root
+ * table needs of course only to be allocated once in mmu_get_root_table_entry,
+ * so that here also some mmu specific initialization is done. The second page
+ * at the start of the kernel (the first page is unmapped later) is used for
+ * the kernel_pg_dir. It must be at a position known at link time (as it's used
+ * to initialize the init task struct) and since it needs special cache
+ * settings, it's the easiest to use this page, the rest of the page is used
+ * for further pointer tables.
+ * mmu_get_page_table_entry allocates always a whole page for page tables, this
+ * means 1024 pages and so 4MB of memory can be mapped. It doesn't make sense
+ * to manage page tables in smaller pieces as nearly all mappings have that
+ * size.
+ *
+ * ######################################################################
+ *
+ *
+ * ######################################################################
+ *
+ * mmu_engage
+ * ----------
+ * Thanks to a small helping routine enabling the mmu got quiet simple
+ * and there is only one way left. mmu_engage makes a complete a new mapping
+ * that only includes the absolute necessary to be able to jump to the final
+ * postion and to restore the original mapping.
+ * As this code doesn't need a transparent translation register anymore this
+ * means all registers are free to be used by machines that needs them for
+ * other purposes.
+ *
+ * ######################################################################
+ *
+ * mmu_print
+ * ---------
+ * This algorithm will print out the page tables of the system as
+ * appropriate for an 030 or an 040. This is useful for debugging purposes
+ * and as such is enclosed in #ifdef MMU_PRINT/#endif clauses.
+ *
+ * ######################################################################
+ *
+ * console_init
+ * ------------
+ * The console is also able to be turned off. The console in head.S
+ * is specifically for debugging and can be very useful. It is surrounded by
+ * #ifdef CONSOLE/#endif clauses so it doesn't have to ship in known-good
+ * kernels. It's basic algorithm is to determine the size of the screen
+ * (in height/width and bit depth) and then use that information for
+ * displaying an 8x8 font or an 8x16 (widthxheight). I prefer the 8x8 for
+ * debugging so I can see more good data. But it was trivial to add support
+ * for both fonts, so I included it.
+ * Also, the algorithm for plotting pixels is abstracted so that in
+ * theory other platforms could add support for different kinds of frame
+ * buffers. This could be very useful.
+ *
+ * console_put_penguin
+ * -------------------
+ * An important part of any Linux bring up is the penguin and there's
+ * nothing like getting the Penguin on the screen! This algorithm will work
+ * on any machine for which there is a console_plot_pixel.
+ *
+ * console_scroll
+ * --------------
+ * My hope is that the scroll algorithm does the right thing on the
+ * various platforms, but it wouldn't be hard to add the test conditions
+ * and new code if it doesn't.
+ *
+ * console_putc
+ * -------------
+ *
+ * ######################################################################
+ *
+ * Register usage has greatly simplified within head.S. Every subroutine
+ * saves and restores all registers that it modifies (except it returns a
+ * value in there of course). So the only register that needs to be initialized
+ * is the stack pointer.
+ * All other init code and data is now placed in the init section, so it will
+ * be automatically freed at the end of the kernel initialization.
+ *
+ * ######################################################################
+ *
+ * options
+ * -------
+ * There are many options availble in a build of this file. I've
+ * taken the time to describe them here to save you the time of searching
+ * for them and trying to understand what they mean.
+ *
+ * CONFIG_xxx: These are the obvious machine configuration defines created
+ * during configuration. These are defined in include/linux/autoconf.h.
+ *
+ * CONSOLE: There is support for head.S console in this file. This
+ * console can talk to a Mac frame buffer, but could easily be extrapolated
+ * to extend it to support other platforms.
+ *
+ * TEST_MMU: This is a test harness for running on any given machine but
+ * getting an MMU dump for another class of machine. The classes of machines
+ * that can be tested are any of the makes (Atari, Amiga, Mac, VME, etc.)
+ * and any of the models (030, 040, 060, etc.).
+ *
+ * NOTE: TEST_MMU is NOT permanent! It is scheduled to be removed
+ * When head.S boots on Atari, Amiga, Macintosh, and VME
+ * machines. At that point the underlying logic will be
+ * believed to be solid enough to be trusted, and TEST_MMU
+ * can be dropped. Do note that that will clean up the
+ * head.S code significantly as large blocks of #if/#else
+ * clauses can be removed.
+ *
+ * MMU_NOCACHE_KERNEL: On the Macintosh platform there was an inquiry into
+ * determing why devices don't appear to work. A test case was to remove
+ * the cacheability of the kernel bits.
+ *
+ * MMU_PRINT: There is a routine built into head.S that can display the
+ * MMU data structures. It outputs its result through the serial_putc
+ * interface. So where ever that winds up driving data, that's where the
+ * mmu struct will appear. On the Macintosh that's typically the console.
+ *
+ * SERIAL_DEBUG: There are a series of putc() macro statements
+ * scattered through out the code to give progress of status to the
+ * person sitting at the console. This constant determines whether those
+ * are used.
+ *
+ * DEBUG: This is the standard DEBUG flag that can be set for building
+ * the kernel. It has the effect adding additional tests into
+ * the code.
+ *
+ * FONT_6x11:
+ * FONT_8x8:
+ * FONT_8x16:
+ * In theory these could be determined at run time or handed
+ * over by the booter. But, let's be real, it's a fine hard
+ * coded value. (But, you will notice the code is run-time
+ * flexible!) A pointer to the font's struct fbcon_font_desc
+ * is kept locally in Lconsole_font. It is used to determine
+ * font size information dynamically.
+ *
+ * Atari constants:
+ * USE_PRINTER: Use the printer port for serial debug.
+ * USE_SCC_B: Use the SCC port A (Serial2) for serial debug.
+ * USE_SCC_A: Use the SCC port B (Modem2) for serial debug.
+ * USE_MFP: Use the ST-MFP port (Modem1) for serial debug.
+ *
+ * Macintosh constants:
+ * MAC_SERIAL_DEBUG: Turns on serial debug output for the Macintosh.
+ * MAC_USE_SCC_A: Use the SCC port A (modem) for serial debug.
+ * MAC_USE_SCC_B: Use the SCC port B (printer) for serial debug (default).
X */
X
X #include <linux/config.h>
X #include <linux/linkage.h>
+#include <linux/init.h>
X #include <asm/bootinfo.h>
X #include <asm/setup.h>
X #include <asm/pgtable.h>
+#include "m68k_defs.h"
X
-.globl SYMBOL_NAME(kernel_pg_dir), SYMBOL_NAME(kpt)
-.globl SYMBOL_NAME(availmem)
-.globl SYMBOL_NAME(m68k_pgtable_cachemode)
-.globl SYMBOL_NAME(kernel_pmd_table), SYMBOL_NAME(swapper_pg_dir)
+#ifdef CONFIG_MAC
X
-#if defined(CONFIG_MVME16x)
-.globl SYMBOL_NAME(mvme_bdid_ptr)
-#endif
+#include <asm/machw.h>
X
X /*
- * Added m68k_supervisor_cachemode for 68060 boards where some drivers
- * need writethrough caching for supervisor accesses. Drivers known to
- * be effected are 53c7xx.c and apricot.c (when used on VME boards).
- * Richard Hirst.
+ * Macintosh console support
X */
X
-#ifdef CONFIG_060_WRITETHROUGH
+#define CONSOLE
+
+/*
+ * Macintosh serial debug support; outputs boot info to the printer
+ * and/or modem serial ports
+ */
+#undef MAC_SERIAL_DEBUG
+
+/*
+ * Macintosh serial debug port selection; define one or both;
+ * requires MAC_SERIAL_DEBUG to be defined
+ */
+#define MAC_USE_SCC_A /* Macintosh modem serial port */
+#define MAC_USE_SCC_B /* Macintosh printer serial port */
+
+#endif /* CONFIG_MAC */
+
+#undef MMU_PRINT
+#undef MMU_NOCACHE_KERNEL
+#define SERIAL_DEBUG
+#undef DEBUG
+
+/*
+ * For the head.S console, there are three supported fonts, 6x11, 8x16 and 8x8.
+ * The 8x8 font is harder to read but fits more on the screen.
+ */
+#define FONT_8x8 /* default */
+/* #define FONT_8x16 */ /* 2nd choice */
+/* #define FONT_6x11 */ /* 3rd choice */
+
+.globl SYMBOL_NAME(kernel_pg_dir)
+.globl SYMBOL_NAME(availmem)
+.globl SYMBOL_NAME(m68k_pgtable_cachemode)
X .globl SYMBOL_NAME(m68k_supervisor_cachemode)
-#endif
X
-D6B_0460 = 16 /* indicates 680[46]0 in d6 */
-D6B_060 = 17 /* indicates 68060 in d6 */
-D6F_040 = 1<<D6B_0460
-D6F_060 = (1<<D6B_0460)+(1<<D6B_060)
+CPUTYPE_040 = 1 /* indicates an 040 */
+CPUTYPE_060 = 2 /* indicates an 060 */
+CPUTYPE_0460 = 3 /* if either above are set, this is set */
+CPUTYPE_020 = 4 /* indicates an 020 */
X
X /* Translation control register */
X TC_ENABLE = 0x8000
@@ -144,6 +355,7 @@
X
X /* Miscellaneous definitions */
X PAGESIZE = 4096
+PAGESHIFT = 12
X
X ROOT_TABLE_SIZE = 128
X PTR_TABLE_SIZE = 128
@@ -152,32 +364,182 @@
X PTR_INDEX_SHIFT = 18
X PAGE_INDEX_SHIFT = 12
X
-TABLENR_4MB = 16 /* # of page tables needed to page 4 MB */
-TABLENR_16MB = 64 /* same for 16 MB */
+#ifdef DEBUG
+/* When debugging use readable names for labels */
+#ifdef __STDC__
+#define L(name) .head.S.##name
+#else
+#define L(name) .head.S./**/name
+#endif
+#else
+#ifdef __STDC__
+#define L(name) .L##name
+#else
+#define L(name) .L/**/name
+#endif
+#endif
+
+/* Several macros to make the writing of subroutines easier:
+ * - func_start marks the beginning of the routine which setups the frame
+ * register and saves the registers, it also defines another macro
+ * to automatically restore the registers again.
+ * - func_return marks the end of the routine and simply calls the prepared
+ * macro to restore registers and jump back to the caller.
+ * - func_define generates another macro to automatically put arguments
+ * onto the stack call the subroutine and cleanup the stack again.
+ */
+
+/* Within subroutines these macros can be used to access the arguments
+ * on the stack. With STACK some allocated memory on the stack can be
+ * accessed and ARG0 points to the return address (used by mmu_engage).
+ */
+#define STACK %a6@(stackstart)
+#define ARG0 %a6@(4)
+#define ARG1 %a6@(8)
+#define ARG2 %a6@(12)
+#define ARG3 %a6@(16)
+#define ARG4 %a6@(20)
+
+.macro func_start name,saveregs,stack=0
+L(\name):
+ linkw %a6,#-\stack
+ moveml \saveregs,%sp@-
+.set stackstart,-\stack
+
+.macro func_return_\name
+ moveml %sp@+,\saveregs
+ unlk %a6
+ rts
+.endm
+.endm
+
+.macro func_return name
+ func_return_\name
+.endm
+
+.macro func_call name
+ jbsr L(\name)
+.endm
+
+.macro move_stack nr,arg1,arg2,arg3,arg4
+.if \nr
+ move_stack "(\nr-1)",\arg2,\arg3,\arg4
+ movel \arg1,%sp@-
+.endif
+.endm
+
+.macro func_define name,nr=0
+.macro \name arg1,arg2,arg3,arg4
+ move_stack \nr,\arg1,\arg2,\arg3,\arg4
+ func_call \name
+.if \nr
+ lea %sp@(\nr*4),%sp
+.endif
+.endm
+.endm
+
+func_define mmu_map,4
+func_define mmu_map_tt,4
+func_define mmu_fixup_page_mmu_cache,1
+func_define mmu_temp_map,2
+func_define mmu_engage
+func_define mmu_get_root_table_entry,1
+func_define mmu_get_ptr_table_entry,2
+func_define mmu_get_page_table_entry,2
+func_define mmu_print
+func_define get_new_page
+#ifdef CONFIG_HP300
+func_define set_leds
+#endif
+
+.macro mmu_map_eq arg1,arg2,arg3
+ mmu_map \arg1,\arg1,\arg2,\arg3
+.endm
+
+.macro get_bi_record record
+ pea \record
+ func_call get_bi_record
+ addql #4,%sp
+.endm
+
+func_define serial_putc,1
+func_define console_putc,1
+
+.macro putc ch
+#if defined(CONSOLE) || defined(SERIAL_DEBUG)
+ pea \ch
+#endif
+#ifdef CONSOLE
+ func_call console_putc
+#endif
+#ifdef SERIAL_DEBUG
+ func_call serial_putc
+#endif
+#if defined(CONSOLE) || defined(SERIAL_DEBUG)
+ addql #4,%sp
+#endif
+.endm
+
+.macro dputc ch
+#ifdef DEBUG
+ putc \ch
+#endif
+.endm
+
+func_define putn,1
+
+.macro dputn nr
+#ifdef DEBUG
+ putn \nr
+#endif
+.endm
+
+.macro puts string
+#if defined(CONSOLE) || defined(SERIAL_DEBUG)
+ __INITDATA
+.Lstr\@:
+ .string "\string"
+ __FINIT
+ pea %pc@(.Lstr\@)
+ func_call puts
+ addql #4,%sp
+#endif
+.endm
+
+.macro dputs string
+#ifdef DEBUG
+ puts "\string"
+#endif
+.endm
+
X
-#define putc(ch) moveq &ch,%d7; jbsr Lserial_putc
-#define putr() putc(13); putc(10)
-#define putn(nr) movel nr,%d7; jbsr Lserial_putnum
-
-#define is_not_amiga(lab) moveq &MACH_AMIGA,%d7; cmpl %d4,%d7; jne lab
-#define is_not_atari(lab) moveq &MACH_ATARI,%d7; cmpl %d4,%d7; jne lab
-#define is_not_mvme16x(lab) moveq &MACH_MVME16x,%d7; cmpl %d4,%d7; jne lab
-#define is_not_bvme6000(lab) moveq &MACH_BVME6000,%d7; cmpl %d4,%d7; jne lab
-#define is_not_hp300(lab) moveq &MACH_HP300,%d7 ; cmpl %d4,%d7; jne lab
-
-#define is_040_or_060(lab) btst &D6B_0460,%d6; jne lab
-#define is_not_040_or_060(lab) btst &D6B_0460,%d6; jeq lab
-#define is_060(lab) btst &D6B_060,%d6; jne lab
-#define is_not_060(lab) btst &D6B_060,%d6; jeq lab
+#define is_not_amiga(lab) cmpl &MACH_AMIGA,%pc@(m68k_machtype); jne lab
+#define is_not_atari(lab) cmpl &MACH_ATARI,%pc@(m68k_machtype); jne lab
+#define is_not_mac(lab) cmpl &MACH_MAC,%pc@(m68k_machtype); jne lab
+#define is_not_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jne lab
+#define is_not_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jne lab
+#define is_not_hp300(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); jne lab
+
+#define is_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jne lab
+#define is_not_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jeq lab
+#define is_040(lab) btst &CPUTYPE_040,%pc@(L(cputype)+3); jne lab
+#define is_060(lab) btst &CPUTYPE_060,%pc@(L(cputype)+3); jne lab
+#define is_not_060(lab) btst &CPUTYPE_060,%pc@(L(cputype)+3); jeq lab
+#define is_020(lab) btst &CPUTYPE_020,%pc@(L(cputype)+3); jne lab
+#define is_not_020(lab) btst &CPUTYPE_020,%pc@(L(cputype)+3); jeq lab
X
X /* On the HP300 we use the on-board LEDs for debug output before
X the console is running. Writing a 1 bit turns the corresponding LED
X _off_ - on the 340 bit 7 is towards the back panel of the machine. */
+.macro leds mask
X #ifdef CONFIG_HP300
-#define leds(x) is_not_hp300(42f) ; moveb #(x),%d7 ; jbsr Lset_leds; 42:
-#else
-#define leds(x)
+ is_not_hp300(.Lled\@)
+ pea \mask
+ func_call set_leds
+ addql #4,%sp
+.Lled\@:
X #endif
+.endm
X
X .text
X ENTRY(_stext)
@@ -192,81 +554,193 @@
X .long MACH_ATARI, ATARI_BOOTI_VERSION
X .long MACH_MVME16x, MVME16x_BOOTI_VERSION
X .long MACH_BVME6000, BVME6000_BOOTI_VERSION
+ .long MACH_MAC, MAC_BOOTI_VERSION
X .long 0
-1: jra SYMBOL_NAME(_start)
+1: jra SYMBOL_NAME(__start)
X
-.equ SYMBOL_NAME(kernel_pmd_table),SYMBOL_NAME(_stext)
-.equ SYMBOL_NAME(kernel_pg_dir),SYMBOL_NAME(kernel_pmd_table)
-.equ SYMBOL_NAME(swapper_pg_dir),SYMBOL_NAME(kernel_pg_dir)+(ROOT_TABLE_SIZE<<2)
-.equ Lavail_pmd_table,SYMBOL_NAME(swapper_pg_dir)+(ROOT_TABLE_SIZE<<2)
+.equ SYMBOL_NAME(kernel_pg_dir),SYMBOL_NAME(_stext)
X
X .equ .,SYMBOL_NAME(_stext)+PAGESIZE
X
X ENTRY(_start)
+ jra SYMBOL_NAME(__start)
+__INIT
+ENTRY(__start)
X
X /*
X * Setup initial stack pointer
X */
- lea %pc@(SYMBOL_NAME(_stext):w),%sp
+ lea %pc@(SYMBOL_NAME(_stext)),%sp
X
X /*
X * Record the CPU and machine type.
X */
X
- movew #BI_MACHTYPE,%d0
- jbsr Lget_bi_record
- movel %a0@,%d4
- lea %pc@(SYMBOL_NAME(m68k_machtype)),%a0
- movel %d4,%a0@
- movew #BI_FPUTYPE,%d0
- jbsr Lget_bi_record
- movel %a0@,%d0
- lea %pc@(SYMBOL_NAME(m68k_fputype)),%a0
- movel %d0,%a0@
- movew #BI_MMUTYPE,%d0
- jbsr Lget_bi_record
- movel %a0@,%d0
- lea %pc@(SYMBOL_NAME(m68k_mmutype)),%a0
- movel %d0,%a0@
- movew #BI_CPUTYPE,%d0
- jbsr Lget_bi_record
+ get_bi_record BI_MACHTYPE
+ lea %pc@(SYMBOL_NAME(m68k_machtype)),%a1
+ movel %a0@,%a1@
+
+ get_bi_record BI_FPUTYPE
+ lea %pc@(SYMBOL_NAME(m68k_fputype)),%a1
+ movel %a0@,%a1@
+
+ get_bi_record BI_MMUTYPE
+ lea %pc@(SYMBOL_NAME(m68k_mmutype)),%a1
+ movel %a0@,%a1@
+
+ get_bi_record BI_CPUTYPE
+ lea %pc@(SYMBOL_NAME(m68k_cputype)),%a1
+ movel %a0@,%a1@
+
+#ifdef CONFIG_MAC
+/*
+ * For Macintosh, we need to determine the display parameters early (at least
+ * while debugging it).
+ */
+
+ is_not_mac(L(test_notmac))
+
+ get_bi_record BI_MAC_VADDR
+ lea %pc@(L(mac_videobase)),%a1
+ movel %a0@,%a1@
+
+ get_bi_record BI_MAC_VDEPTH
+ lea %pc@(L(mac_videodepth)),%a1
+ movel %a0@,%a1@
+
+ get_bi_record BI_MAC_VDIM
+ lea %pc@(L(mac_dimensions)),%a1
+ movel %a0@,%a1@
+
+ get_bi_record BI_MAC_VROW
+ lea %pc@(L(mac_rowbytes)),%a1
+ movel %a0@,%a1@
+
+#ifdef MAC_SERIAL_DEBUG
+ get_bi_record BI_MAC_SCCBASE
+ lea %pc@(L(mac_sccbase)),%a1
+ movel %a0@,%a1@
+#endif /* MAC_SERIAL_DEBUG */
+
+#if 0
+ /*
+ * Clear the screen
+ */
+ lea %pc@(L(mac_videobase)),%a0
+ movel %a0@,%a1
+ lea %pc@(L(mac_dimensions)),%a0
+ movel %a0@,%d1
+ swap %d1 /* #rows is high bytes */
+ andl #0xFFFF,%d1 /* rows */
+ subl #10,%d1
+ lea %pc@(L(mac_rowbytes)),%a0
+loopy2:
X movel %a0@,%d0
- lea %pc@(SYMBOL_NAME(m68k_cputype)),%a0
- movel %d0,%a0@
+ subql #1,%d0
+loopx2:
+ moveb #0x55, %a1@+
+ dbra %d0,loopx2
+ dbra %d1,loopy2
+#endif
+
+L(test_notmac):
+#endif /* CONFIG_MAC */
+
+
+/*
+ * There are ultimately two pieces of information we want for all kinds of
+ * processors CpuType and CacheBits. The CPUTYPE was passed in from booter
+ * and is converted here from a booter type definition to a separate bit
+ * number which allows for the standard is_0x0 macro tests.
+ */
+ movel %pc@(SYMBOL_NAME(m68k_cputype)),%d0
+ /*
+ * Assume it's an 030
+ */
+ clrl %d1
X
+ /*
+ * Test the BootInfo cputype for 060
+ */
X btst #CPUB_68060,%d0
X jeq 1f
- /* '060: d6 := BIT0460|BIT060, cache mode 0x60 (no-cache/non-ser) */
- movel #D6F_060+_PAGE_CACHE040W,%d6
- jra 2f
-1: btst #CPUB_68040,%d0
- jeq 1f
- /* '040: d6 := BIT0460, cache mode 0x00 (write-through) */
- movel #D6F_040+_PAGE_CACHE040W,%d6
- jra 2f
-1: /* '020 or '030: d6 := no CPU bit, cache mode unused */
- moveq #0,%d6
+ bset #CPUTYPE_060,%d1
+ bset #CPUTYPE_0460,%d1
+ jra 3f
+1:
+ /*
+ * Test the BootInfo cputype for 040
+ */
+ btst #CPUB_68040,%d0
+ jeq 2f
+ bset #CPUTYPE_040,%d1
+ bset #CPUTYPE_0460,%d1
+ jra 3f
+2:
+ /*
+ * Test the BootInfo cputype for 020
+ */
+ btst #CPUB_68020,%d0
+ jeq 3f
+ bset #CPUTYPE_020,%d1
+ jra 3f
+3:
+ /*
+ * Record the cpu type
+ */
+ lea %pc@(L(cputype)),%a0
+ movel %d1,%a0@
X
-2: lea %pc@(SYMBOL_NAME(m68k_pgtable_cachemode)),%a0
- moveq #0,%d0
- movew %d6,%d0
- movel %d0,%a0@ /* save cache mode for page tables */
+ /*
+ * NOTE:
+ *
+ * Now the macros are valid:
+ * is_040_or_060
+ * is_not_040_or_060
+ * is_040
+ * is_060
+ * is_not_060
+ */
+
+ /*
+ * Determine the cache mode for pages holding MMU tables
+ * and for supervisor mode, unused for '020 and '030
+ */
+ clrl %d0
+ clrl %d1
+
+ is_not_040_or_060(L(save_cachetype))
X
X /*
+ * '040 or '060
+ * d1 := cacheable write-through
+ * NOTE: The 68040 manual strongly recommends non-cached for MMU tables,
+ * but we have been using write-through since at least 2.0.29 so I
+ * guess it is OK.
+ */
+#ifdef CONFIG_060_WRITETHROUGH
+ /*
X * If this is a 68060 board using drivers with cache coherency
X * problems, then supervisor memory accesses need to be write-through
- * also; otherwise, we want copyback.
+ * also; otherwise, we want copyback.
X */
X
-#if defined(CONFIG_060_WRITETHROUGH)
- is_not_060(Lset_norm)
- jra 1f
-Lset_norm:
- move.w #_PAGE_CACHE040,%d0
+ is_not_060(1f)
+ movel #_PAGE_CACHE040W,%d0
+ jra L(save_cachetype)
+#endif /* CONFIG_060_WRITETHROUGH */
X 1:
- lea %pc@(SYMBOL_NAME(m68k_supervisor_cachemode)),%a0
+ movew #_PAGE_CACHE040,%d0
+
+ movel #_PAGE_CACHE040W,%d1
+
+L(save_cachetype):
+ /* Save cache mode for supervisor mode and page tables
+ */
+ lea %pc@(SYMBOL_NAME(m68k_supervisor_cachemode)),%a0
X movel %d0,%a0@
-#endif
+ lea %pc@(SYMBOL_NAME(m68k_pgtable_cachemode)),%a0
+ movel %d1,%a0@
X
X /*
X * raise interrupt level
@@ -293,288 +767,120 @@
X */
X
X #ifdef CONFIG_ATARI
- is_not_atari(Lnotypetest)
+ is_not_atari(L(notypetest))
X
X /* get special machine type (Medusa/Hades/AB40) */
X moveq #0,%d3 /* default if tag doesn't exist */
- movew #BI_ATARI_MCH_TYPE,%d0
- jbsr Lget_bi_record
+ get_bi_record BI_ATARI_MCH_TYPE
X tstl %d0
X jbmi 1f
X movel %a0@,%d3
-1:
- /* %d3 is not clobbered until Atari page tables are set up,
- * where it is used again. */
-
+ lea %pc@(SYMBOL_NAME(atari_mch_type)),%a0
+ movel %d3,%a0@
+1:
X /* On the Hades, the iobase must be set up before opening the
X * serial port. There are no I/O regs at 0x00ffxxxx at all. */
X moveq #0,%d0
X cmpl #ATARI_MACH_HADES,%d3
X jbne 1f
X movel #0xff000000,%d0 /* Hades I/O base addr: 0xff000000 */
-1: lea %pc@(Liobase),%a0
+1: lea %pc@(L(iobase)),%a0
X movel %d0,%a0@
-Lnotypetest:
+
+L(notypetest):
X #endif
X
X /*
X * Initialize serial port
X */
-
- jbsr Lserial_init
-
- putr()
- putc('A')
+ jbsr L(serial_init)
X
X /*
- * Get address at end of bootinfo and mask off at a page boundary.
+ * Initialize console
X */
- moveq #0,%d0
- jbsr Lget_bi_record
- addw #PAGESIZE-1,%a0
- movel %a0,%d0
- andl #-PAGESIZE,%d0
- movel %d0,%a6
-
- putc('B')
+#ifdef CONFIG_MAC
+ is_not_mac(L(nocon))
+#ifdef CONSOLE
+ jbsr L(console_init)
+#ifdef CONSOLE_PENGUIN
+ jbsr L(console_put_penguin)
+#endif /* CONSOLE_PENGUIN */
+ jbsr L(console_put_stats)
+#endif /* CONSOLE */
+L(nocon):
+#endif /* CONFIG_MAC */
+
+
+ putc '\n'
+ putc 'A'
+ dputn %pc@(L(cputype))
+ dputn %pc@(SYMBOL_NAME(m68k_supervisor_cachemode))
+ dputn %pc@(SYMBOL_NAME(m68k_pgtable_cachemode))
+ dputc '\n'
X
X /*
X * Save physical start address of kernel
X */
- lea %pc@(SYMBOL_NAME(_stext)-PAGESIZE:w),%a0
- movel %a0,%d5
-
-/*
- * initialize the kernel root table.
- */
- lea %pc@(SYMBOL_NAME(kernel_pg_dir):w),%a5
- movel %a5,%a0
- moveq #ROOT_TABLE_SIZE-1,%d1
-1: clrl %a0@+
- dbra %d1,1b
+ lea %pc@(L(phys_kernel_start)),%a0
+ lea %pc@(SYMBOL_NAME(_stext)),%a1
+ subl #SYMBOL_NAME(_stext),%a1
+ movel %a1,%a0@
X
- /*
- * Initialize root table descriptor pointing to the kernel pointer
- * table.
- */
- lea %pc@(Lavail_pmd_table:w),%a4
- moveq #_PAGE_TABLE,%d0
- addl %a4,%d0
- movel %d0,%a5@
+ putc 'B'
X
- putc('C')
+ leds 0x4
X
X /*
- * Initialize the pointer tables referred to above. They either point
- * to page tables in the case of the 680[46]0 or contain early
- * termination page descriptors in the case of the 68851 or 68030.
+ * mmu_init
X *
- * Each pointer table entry points to a 64 entry page table. 16 of these
- * page tables are grouped to form a single 1024 entry page table which
- * fits in a single 4096 byte page.
- *
- * Some register usages:
- * a0 -> pointer table descriptor address
- * a1 -> pointer table descriptor
- * d1 -> counter
- * d2 -> pointer table descriptor increment (varies according to CPU)
+ * This block of code does what's necessary to map in the various kinds
+ * of machines for execution of Linux.
+ * First map the first 4 MB of kernel code & data
X */
X
- /* clear the kernel pointer table */
- movel %a4,%a0
- moveq #PTR_TABLE_SIZE-1,%d1
-1: clrl %a0@+
- dbra %d1,1b
-
- movel %a4,%a0
- moveq #15,%d1
-
- /*
- * base value of pointer table descriptor is either
- * the address of the first page table (680[46]0)
- * or the base address of physical memory (68030).
- */
- is_040_or_060(1f)
-
- /* 680[23]0 */
- movel %d5,%a1 /* base address */
- addql #_PAGE_PRESENT,%a1 /* descriptor type */
- movel #PAGE_TABLE_SIZE*PAGESIZE,%d2 /* increment */
- jra 2f
-
-1: /* 680[46]0 */
- movel %a6,%a3 /* base address */
- addw #PAGESIZE,%a6 /* allocate page for 16 page tables */


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 02'
echo 'File patch-2.2.0-pre9 is continued in part 03'
echo 03 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part03

#!/bin/sh
# this is part 03 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 03; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

- lea %pc@(SYMBOL_NAME(kpt)),%a1
- movel %a3,%a1@ /* save address of page table */
- movel %a3,%a1
- addw #_PAGE_TABLE+_PAGE_ACCESSED,%a1 /* descriptor type */
- movel #PAGE_TABLE_SIZE<<2,%d2 /* increment */
-
-2: movel %a1,%a0@+
- addl %d2,%a1
- dbra %d1,2b
-
- putc('D')
-
-/*
- * If we are running on a 680[46]0, we have a kernel page table and
- * must initialize it. Make the entries point to the first
- * 4M of physical memory (the memory we are residing in).
- * Set the cache mode bits to Cacheable, Copyback. Set the Global bits
- * in the descriptors also.
- */
- is_not_040_or_060(Lnot040)
-
- putc('F')
-
- movel %a3,%a0
- movel %d5,%a1
-#if defined(CONFIG_060_WRITETHROUGH)
- addw #_PAGE_GLOBAL040+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
- addl m68k_supervisor_cachemode,%a1
-#else
- addw #_PAGE_GLOBAL040+_PAGE_CACHE040+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
-#endif
- movew #(PAGE_TABLE_SIZE*TABLENR_4MB)-1,%d1
- movel #PAGESIZE,%d2
-1: movel %a1,%a0@+
- addl %d2,%a1
- dbra %d1,1b
-
- /*
- * on the 68040, pages used to hold mmu tables should
- * be initialized as noncachable; the '060 allows write-through.
- * Do this for the root table page (which also contains
- * all pointer tables utilized thus far) and the
- * kernel page table.
- */
- movel %a5,%d0
- subl %d5,%d0
- moveq #PAGE_INDEX_SHIFT,%d2
- lsrl %d2,%d0
- lea %a3@(%d0:l:4),%a2
- movel %a2@,%d1
- andw #_CACHEMASK040,%d1
- orw %d6,%d1
- movel %d1,%a2@
+ mmu_map #0,%pc@(L(phys_kernel_start)),#4*1024*1024,\
+ %pc@(SYMBOL_NAME(m68k_supervisor_cachemode))
X
- movel %a3,%d0
- subl %d5,%d0
- lsrl %d2,%d0
- lea %a3@(%d0:l:4),%a2
- movel %a2@,%d1
- andw #_CACHEMASK040,%d1
- orw %d6,%d1
- movel %d1,%a2@+
- /*
- * %a2 points now to the page table entry for available pages at %a6,
- * hence caching modes for new pages can easily set unless increasing
- * of %a2 are forgotten.
- */
-Lnot040:
+ putc 'C'
X
- leds(0x4)
-
-/*
- * Do any machine specific page table initializations.
- */
X #ifdef CONFIG_AMIGA
- is_not_amiga(Lnotami)
X
+L(mmu_init_amiga):
+
+ is_not_amiga(L(mmu_init_not_amiga))
X /*
- * Setup a mapping of the first 16M of physical address space at virtual
- * address 0x80000000, using early termination page descriptors for the
- * 68030, and proper page tables for the 680[46]0. Set this area as
- * non-cacheable.
+ * mmu_init_amiga
X */
X
- putc('H')
-
- is_040_or_060(Lspami68040)
-
- /*
- * for the 68030, just setup a translation to map in the first
- * 32M of physical address space at virtual address 0x80000000
- * using an early termination page descriptor.
- */
-
- putc('I')
-
- movel #_PAGE_NOCACHE030+_PAGE_PRESENT+_PAGE_ACCESSED,%d0
- movel %d0,%a5@(0x40<<2)
-
- jra Lmapphys
+ putc 'D'
X
-Lspami68040:
+ is_not_040_or_060(1f)
X
X /*
- * for the 680[46]0, use another pointer table, and allocate 4 more
- * page tables. Initialize the pointer table to point to the
- * page tables. Then initialize the page tables to point to
- * the first 16M of memory, with no caching (noncachable/serialized).
+ * 040: Map the 16Meg range physical 0x0 upto logical 0x8000.0000
X */
+ mmu_map #0x80000000,#0,#0x01000000,#_PAGE_NOCACHE_S
X
- /* clear the amiga pointer table */
- lea %a4@(PTR_TABLE_SIZE<<2),%a4


- moveq #PTR_TABLE_SIZE-1,%d1
-1: clrl %a0@+
- dbra %d1,1b
-

- /* allocate 4 pages for 64 page tables */
- movel %a6,%a3
- addw #4*PAGESIZE,%a6
-
- /* initialize the pointer table */
- movel %a4,%a0
- movel %a3,%a1
- addw #_PAGE_TABLE+_PAGE_ACCESSED,%a1 /* base descriptor */
- movel #PAGE_TABLE_SIZE<<2,%d2 /* increment */
- moveq #TABLENR_16MB-1,%d1
-
-1: movel %a1,%a0@+
- addl %d2,%a1
- dbra %d1,1b
-
- /* ensure that the root table points to the pointer table */
- movel %a4,%a0
- addw #_PAGE_TABLE+_PAGE_ACCESSED,%a0
- movel %a0,%a5@(0x40<<2)
+ jbra L(mmu_init_done)
X
+1:
X /*
- * initialize the page tables
- * descriptor bits include noncachable/serialized and global bits.
+ * 030: Map the 32Meg range physical 0x0 upto logical 0x8000.0000
X */
- movel %a3,%a0
- movew #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
- movel #PAGESIZE,%d2
- movew #(PAGE_TABLE_SIZE*TABLENR_16MB)-1,%d1
-
-1: movel %a1,%a0@+
- addl %d2,%a1
- dbra %d1,1b
-
- /*
- * Finally, since we just allocated 4 page tables, make sure that
- * the virtual mapping of the 4 page tables indicates
- * noncachable/serialized.
- */
- moveq #3,%d0
-1: movel %a2@,%d1 /* a2 already points to root table offset */
- andw #_CACHEMASK040,%d1
- orw %d6,%d1
- movel %d1,%a2@+
- dbra %d0,1b
+ mmu_map #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
X
- jra Lmapphys
+ jbra L(mmu_init_done)
X
-Lnotami:
+L(mmu_init_not_amiga):
X #endif
X
X #ifdef CONFIG_ATARI
- is_not_atari(Lnotatari)
X
- move.w #PAGESIZE,%sp
+L(mmu_init_atari):
+
+ is_not_atari(L(mmu_init_not_atari))
+
+ putc 'E'
X
X /* On the Atari, we map the I/O region (phys. 0x00ffxxxx) by mapping
X the last 16 MB of virtual address space to the first 16 MB (i.e.
@@ -591,103 +897,57 @@
X
X /* I/O base addr for non-Medusa, non-Hades: 0x00000000 */
X moveq #0,%d0
+ movel %pc@(SYMBOL_NAME(atari_mch_type)),%d3
X cmpl #ATARI_MACH_MEDUSA,%d3
X jbeq 2f


X cmpl #ATARI_MACH_HADES,%d3
X jbne 1f

X 2: movel #0xff000000,%d0 /* Medusa/Hades base addr: 0xff000000 */
X 1: movel %d0,%d3
-
- /* Let the root table point to the new pointer table */
- lea %a4@(PTR_TABLE_SIZE<<2),%a4
- movel %a4,%a0
- addw #_PAGE_TABLE+_PAGE_ACCESSED,%a0
- movel %a0,%a5@(0x7f<<2) /* 0xFE000000 - 0xFFFFFFFF */
X
- /* clear lower half of the pointer table (0xfexxxxxx) */
- movel %a4,%a0
- movel #(PTR_TABLE_SIZE/2)-1,%d2
-1: clrl %a0@+
- dbra %d2,1b
-
- is_040_or_060(Lspata68040)
-
-/* Mapping of the last 16M of virtual address space to the first 16M
- for efficient addressing of hardware registers */
- movel #PAGE_TABLE_SIZE*PAGESIZE,%d1
- movel #(PTR_TABLE_SIZE/2)-1,%d2
- movel %d3,%d0
- orw #_PAGE_PRESENT+_PAGE_ACCESSED,%d0
-1: movel %d0,%a0@+
- addl %d1,%d0
- dbra %d2,1b
- moveq #_PAGE_NOCACHE030,%d0 /* make non-cachable */
- addl %d0,%a4@(0x7f<<2) /* 0xFFFC0000-0xFFFFFFFF (I/O space) */
-/* GK: 0xFFF00000-0xFFF3FFFF (IDE-bus) has to be non-cachable too */
- addl %d0,%a4@(0x7c<<2)
-
- jra Lmapphys
-
-Lspata68040:
- /* allocate 4 page tables */
- movel %a6,%a3
- addw #4*PAGESIZE,%a6
-
- /* Initialize the upper half of the pointer table (a0 is still valid) */
- movel %a3,%a1
- addw #_PAGE_TABLE+_PAGE_ACCESSED,%a1
- movel #PAGE_TABLE_SIZE<<2,%d2
- moveq #TABLENR_16MB-1,%d1
-1: movel %a1,%a0@+
- addl %d2,%a1
- dbra %d1,1b
-
- /* Initialize the page tables as noncacheable/serialized! */
- movel %a3,%a0
- movel %d3,%a1
- addw #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
- movel #PAGESIZE,%d2
- movew #(PAGE_TABLE_SIZE*TABLENR_16MB)-1,%d1
-1: movel %a1,%a0@+
- addl %d2,%a1
- dbra %d1,1b
+ is_040_or_060(L(spata68040))
X
- /*
- * Finally, since we just allocated 4 page tables, make sure that
- * the virtual mapping of the 4 page tables indicates
- * noncachable or write-through.
- */
- moveq #3,%d0
-1: movel %a2@,%d1 /* a2 already points to root table offset */
- andw #_CACHEMASK040,%d1
- orw %d6,%d1
- movel %d1,%a2@+
- dbra %d0,1b
+ /* Map everything non-cacheable, though not all parts really
+ * need to disable caches (crucial only for 0xff8000..0xffffff
+ * (standard I/O) and 0xf00000..0xf3ffff (IDE)). The remainder
+ * isn't really used, except for sometimes peeking into the
+ * ROMs (mirror at phys. 0x0), so caching isn't necessary for
+ * this. */
+ mmu_map #0xff000000,%d3,#0x01000000,#_PAGE_NOCACHE030
+
+ jbra L(mmu_init_done)
+
+L(spata68040):
X
-Lnotatari:
+ mmu_map #0xff000000,%d3,#0x01000000,#_PAGE_NOCACHE_S
+
+ jbra L(mmu_init_done)
+
+L(mmu_init_not_atari):
X #endif
X
X #ifdef CONFIG_HP300
- is_not_hp300(Lnothp300)
+ is_not_hp300(L(nothp300))
X
X /* On the HP300, we map the ROM, INTIO and DIO regions (phys. 0x00xxxxxx)
- by mapping 32MB from 0xf0xxxxxx -> 0x00xxxxxx) using an 030 early
- termination page descriptor. The ROM mapping is needed because the LEDs
+ by mapping 32MB from 0xf0xxxxxx -> 0x00xxxxxx) using an 030 early
+ termination page descriptor. The ROM mapping is needed because the LEDs
X are mapped there too. */
X
- movel #_PAGE_NOCACHE030+_PAGE_PRESENT+_PAGE_ACCESSED,%d0
- movel %d0,%a5@(0x78<<2)
+ mmu_map #0xf0000000,#0,#0x02000000,#_PAGE_NOCACHE030
+
+L(nothp300):
X
-Lnothp300:
-
X #endif
X
-#if defined(CONFIG_MVME16x)
- is_not_mvme16x(Lnot16x)
+#ifdef CONFIG_MVME16x
+
+ is_not_mvme16x(L(not16x))
X
X /* Get pointer to board ID data */
X movel %d2,%sp@-
- .long 0x4e4f0070 /* trap 0x70 - .BRD_ID */
+ trap #15
+ .word 0x70 /* trap 0x70 - .BRD_ID */
X movel %sp@+,%d2
X lea %pc@(SYMBOL_NAME(mvme_bdid_ptr)),%a0
X movel %d2,%a0@
@@ -696,415 +956,1542 @@
X * On MVME16x we have already created kernel page tables for
X * 4MB of RAM at address 0, so now need to do a transparent
X * mapping of the top of memory space. Make it 0.5GByte for now.
+ * Supervisor only access, so transparent mapping doesn't
+ * clash with User code virtual address space.
+ * this covers IO devices, PROM and SRAM. The PROM and SRAM
+ * mapping is needed to allow 167Bug to run.
+ * IO is in the range 0xfff00000 to 0xfffeffff.
+ * PROM is 0xff800000->0xffbfffff and SRAM is
+ * 0xffe00000->0xffe1ffff.
X */
X
- movel #0xe01f0000,%d2 /* logical address base */
- orw #0xa040,%d2 /* add in magic bits */
- .long 0x4e7b2005 /* movec d2,ittr1 */
- .long 0x4e7b2007 /* movec d2,dttr1 */
+ mmu_map_tt 1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
X
-Lnot16x:
-#endif
+ jbra L(mmu_init_done)
+
+L(not16x):
+#endif /* CONFIG_MVME162 | CONFIG_MVME167 */
+
+#ifdef CONFIG_BVME6000
X
-#if defined(CONFIG_BVME6000)
- is_not_bvme6000(Lnotbvm)
+ is_not_bvme6000(L(not6000))
X
X /*
X * On BVME6000 we have already created kernel page tables for
X * 4MB of RAM at address 0, so now need to do a transparent
- * mapping of the top of memory space. Make it 0.5GByte for now.
+ * mapping of the top of memory space. Make it 0.5GByte for now,
+ * so we can access on-board i/o areas.
+ * Supervisor only access, so transparent mapping doesn't
+ * clash with User code virtual address space.
X */
X
- movel #0xe01f0000,%d2 /* logical address base */
- orw #0xa040,%d2 /* add in magic bits */
- .long 0x4e7b2005 /* movec d2,ittr1 */
- .long 0x4e7b2007 /* movec d2,dttr1 */
- .long 0x4e7b2004 /* movec d2,ittr0 */
- .long 0x4e7b2006 /* movec d2,dttr0 */
+ mmu_map_tt 1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
X
-Lnotbvm:
-#endif
+ jbra L(mmu_init_done)
+
+L(not6000):
+#endif /* CONFIG_BVME6000 */
X
X /*
- * Setup a transparent mapping of the physical memory we are executing in.
+ * mmu_init_mac
+ *
+ * The Macintosh mappings are less clear.
+ *
+ * Even as of this writing, it is unclear how the
+ * Macintosh mappings will be done. However, as
+ * the first author of this code I'm proposing the
+ * following model:
+ *
+ * Map the kernel (that's already done),
+ * Map the I/O (on most machines that's the
+ * 0x5000.0000 ... 0x5200.0000 range,
+ * Map the video frame buffer using as few pages
+ * as absolutely (this requirement mostly stems from
+ * the fact that when the frame buffer is at
+ * 0x0000.0000 then we know there is valid RAM just
+ * above the screen that we don't want to waste!).
+ *
+ * By the way, if the frame buffer is at 0x0000.0000
+ * then the Macintosh is known as an RBV based Mac.
X *
- * Only do this if the physical memory is not in the first 16M Meg, or not on
- * an Amiga since the first 16M is already identity mapped on the Amiga.
+ * By the way 2, the code currently maps in a bunch of
+ * regions. But I'd like to cut that out. (And move most
+ * of the mappings up into the kernel proper ... or only
+ * map what's necessary.)
X */
-Lmapphys:
- putc('J')
- leds(0x8)
X
-#ifdef CONFIG_AMIGA
- is_not_amiga(Lmapphysnotamiga)
+#ifdef CONFIG_MAC
X
-/*
- * The virtual address of the start of the kernel is 0x1000. We transparently
- * translate the memory where we running in and can enable then the MMU. Hence
- * we have now two locations of the kernel in memory and can jump to the final
- * place. Except if the physical location is in the first 16MB, translation
- * will overlap later virtual location, but as we already mapped the first
- * 16MB to 0x80000000, we can jump there after translation and MMU is enabled
- * and then we can switch off translation and go to the final place.
- * On 020/030 we must emulate transparant translation, since 020 doesn't know
- * it, but due to early termination pointer this is easy to do.
- * When MMU is enabled, stack pointer and Lcustom will become again valid and
- * stack points to the unused first page.
- */
+L(mmu_init_mac):
X
-/*
- * Setup Supervisor Root Pointer register to point to page directory,
- * setup translation register contents and enable translation.
- */
- putc('K')
+ is_not_mac(L(mmu_init_not_mac))
X
- movew #PAGESIZE,%sp
+ putc 'F'
X
- /* fixup the Amiga custom register location before printing */
- lea %pc@(Lcustom),%a0
- movel #0x80000000,%a0@
+ lea %pc@(L(mac_videobase)),%a0
+ lea %pc@(L(console_video_virtual)),%a1
+ movel %a0@,%a1@
X
- is_040_or_060(Lamimmu68040)
+ is_not_040_or_060(1f)
X
- moveq #ROOT_INDEX_SHIFT,%d2
- movel %d5,%d0
- lsrl %d2,%d0
- movel %d0,%d1
- lsll %d2,%d1
- orw #_PAGE_PRESENT+_PAGE_ACCESSED,%d1
- lsll #2,%d0
- movel %a5@(%d0:w),%d2
- movel %d1,%a5@(%d0:w)
- lea %pc@(Lmmu),%a3
- /* no limit, 4byte descriptors */
- movel #0x80000002,%a3@
- movel %a5,%a3@(4)
- pmove %a3@,%srp
- pmove %a3@,%crp
- pflusha
+ moveq #_PAGE_NOCACHE_S,%d3
+ jbra 2f
+1:
+ moveq #_PAGE_NOCACHE030,%d3
+2:
X /*
- * enable,super root enable,4096 byte pages,7 bit root index,
- * 7 bit pointer index, 6 bit page table index.
+ * Mac Note: screen address of logical 0xF000.0000 -> <screen physical>
+ * we simply map the 4MB that contains the videomem
X */
- movel #0x82c07760,%a3@
- pmove %a3@,%tc /* enable the MMU */
- tstl %d0
- jne 1f
- jmp %pc@(2f+0x80000000)
-1: jmp 2f:w
-2: movel %d2,%a5@(%d0:w)
- pflusha
- jmp LdoneMMUenable:w
X
-Lamimmu68040:
+ movel #VIDEOMEMMASK,%d0
+ andl L(mac_videobase),%d0
X
- .chip 68040
- lea 2f:w,%a0
- movel %d5,%d0
- andl #0xff000000,%d0
- jne 1f
- lea %pc@(2f+0x80000000),%a0
-1: orw #TTR_ENABLE+TTR_KERNELMODE+_PAGE_NOCACHE_S,%d0
- movec %d0,%itt0
- movec %a5,%urp
- movec %a5,%srp
- pflusha
- movel #TC_ENABLE+TC_PAGE4K,%d0
- /*
- * this value is also ok for the 68060, we don`t use the cache
- * mode/protection defaults
- */
- movec %d0,%tc /* enable the MMU */
- jmp %a0@
-2: moveq #0,%d0
- movec %d0,%itt0
- jmp LdoneMMUenable:w
- .chip 68k
+ mmu_map #VIDEOMEMBASE,%d0,#VIDEOMEMSIZE,%d3
+ mmu_map_eq #0x40800000,#0x02000000,%d3 /* rom ? */
+ mmu_map_eq #0x50000000,#0x02000000,%d3
+ mmu_map_eq #0x60000000,#0x00400000,%d3
+ mmu_map_eq #0x9c000000,#0x00400000,%d3
+ mmu_map_tt 1,#0xf8000000,#0x08000000,%d3
X
-Lmapphysnotamiga:
+ jbra L(mmu_init_done)
+
+L(mmu_init_not_mac):
X #endif
X
-#ifdef CONFIG_ATARI
- is_not_atari(Lmapphysnotatari)
+L(mmu_init_done):
+
+ putc 'G'
+ leds 0x8
X
X /*
- * If the kernel physical address is different from its virtual address, we
- * will temporarily set up an identity mapping of the 16MB chunk with
- * transparent translation where the kernel is executing.
+ * mmu_fixup
+ *
+ * On the 040 class machines, all pages that are used for the
+ * mmu have to be fixed up. According to Motorola, pages holding mmu
+ * tables should be non-cacheable on a '040 and write-through on a
+ * '060. But analysis of the reasons for this, and practical
+ * experience, showed that write-through also works on a '040.
+ *
+ * Allocated memory so far goes from kernel_end to memory_start that
+ * is used for all kind of tables, for that the cache attributes
+ * are now fixed.
X */
- putc('L')
+L(mmu_fixup):
X
- /* fixup the Atari iobase register location before printing */
- lea %pc@(Liobase),%a0
- movel #0xff000000,%a0@
+ is_not_040_or_060(L(mmu_fixup_done))
X
- is_040_or_060(Latarimmu68040)
+#ifdef MMU_NOCACHE_KERNEL
+ jbra L(mmu_fixup_done)
+#endif
X
- .chip 68030
- lea %pc@(Lmmu),%a3
- movel %d5,%d0
- jne 1f
- lea LdoneMMUenable:w,%a0
- jra 3f
-1: lea 4f:w,%a0
- andl #0xff000000,%d0 /* logical address base */
- jeq 2f
- orw #TTR_ENABLE+TTR_CI+TTR_RWM+TTR_FCB2+TTR_FCM1+TTR_FCM0,%d0
- movel %d0,%a3@
- pmove %a3@,%tt0
- jra 3f
- /* tt0 doesn't work if physical and virtual address of kernel is in
- * the same 16M area (Falcon with Magnum/FX, kernel in alternate ram)
- * Transparent translation through kernel pointer table
- * Requires that this code until after MMU enabling lies in
- * the 256K page around %d5
- */
-2: movel %a5@,%d1
- andw #0xfff0,%d1
- movel %d1,%a1
- movel %d5,%d1
- moveq #PTR_INDEX_SHIFT,%d0
- lsrl %d0,%d1
- lea %a1@(%d1:l:4),%a1
- movel %d5,%d1
- orw #_PAGE_PRESENT+_PAGE_ACCESSED,%d1
- movel %a1@,%d2
- movel %d1,%a1@
- lea 5f:w,%a0
- /* no limit, 4byte descriptors */
-3: movel #0x80000002,%a3@
- movel %a5,%a3@(4)
- pmove %a3@,%srp
- pmove %a3@,%crp
- pflusha
- /*
- * enable,super root enable,4096 byte pages,7 bit root index,
- * 7 bit pointer index, 6 bit page table index.
- */
- movel #0x82c07760,%a3@
- pmove %a3@,%tc /* enable the MMU */
- jmp %a0@
-4: clrl %a3@
- pmove %a3@,%tt0
- jra LdoneMMUenable
-5: movel %d2,%a1@
- jra LdoneMMUenable
- .chip 68k
-
-Latarimmu68040:
- .chip 68040
- movel %d5,%d0
- jne 1f
- lea LdoneMMUenable:w,%a0
- jra 2f
-1: lea 3f:w,%a0
- andl #0xff000000,%d0 /* logical address base */
- orw #TTR_ENABLE+TTR_KERNELMODE+_PAGE_NOCACHE_S,%d0
- movec %d0,%itt0
-2: nop
- pflusha
- movec %a5,%srp
- movec %a5,%urp
- movel #TC_ENABLE+TC_PAGE4K,%d0
- /*
- * this value is also ok for the 68060, we don`t use the cache
- * mode/protection defaults
+ /* first fix the page at the start of the kernel, that
+ * contains also kernel_pg_dir.
X */
- movec %d0,%tc /* enable the MMU */
- jmp %a0@
-3: moveq #0,%d0
- movec %d0,%itt0
- jra LdoneMMUenable
- .chip 68k
-
-Lmapphysnotatari:
-#endif
+ movel %pc@(L(phys_kernel_start)),%d0
+ lea %pc@(SYMBOL_NAME(_stext)),%a0
+ subl %d0,%a0
+ mmu_fixup_page_mmu_cache %a0
X
-#if defined(CONFIG_MVME16x)
- is_not_mvme16x(Lmapphysnot16x)
- /*
- * save physaddr of phys mem in register a3
- */
- moveq #'L',%d7
- jbsr Lserial_putc
-
- .word 0xf4d8 /* CINVA I/D */
- .word 0xf518 /* pflusha */
- .long 0x4e7bd807 /* movec a5,srp */
- .long 0x4e7bd806 /* movec a5,urp */
- movel #(TC_ENABLE+TC_PAGE4K),%d0
- .long 0x4e7b0003 /* movec d0,tc (enable the MMU) */
- jra LdoneMMUenable /* branch to continuation of startup */
+ movel %pc@(L(kernel_end)),%a0
+ subl %d0,%a0
+ movel %pc@(L(memory_start)),%a1
+ subl %d0,%a1
+ bra 2f
+1:
+ mmu_fixup_page_mmu_cache %a0
+ addw #PAGESIZE,%a0
+2:
+ cmpl %a0,%a1
+ jgt 1b
X
-Lmapphysnot16x:
+L(mmu_fixup_done):
X
+#ifdef MMU_PRINT
+ mmu_print
X #endif
X
-#if defined(CONFIG_HP300)
- is_not_hp300(Lmapphysnothp300)
-
X /*
- * Physical RAM is at 0xff000000. We want to map the kernel at 0x00000000.
- * In order to avoid disaster when we enable the MMU we need to make a
- * transparent mapping of the RAM we're executing out of as well.


+ * mmu_engage
+ *

+ * This chunk of code performs the gruesome task of engaging the MMU.
+ * The reason its gruesome is because when the MMU becomes engaged it
+ * maps logical addresses to physical addresses. The Program Counter
+ * register is then passed through the MMU before the next instruction
+ * is fetched (the instruction following the engage MMU instruction).
+ * This may mean one of two things:
+ * 1. The Program Counter falls within the logical address space of
+ * the kernel of which there are two sub-possibilities:
+ * A. The PC maps to the correct instruction (logical PC == physical
+ * code location), or
+ * B. The PC does not map through and the processor will read some
+ * data (or instruction) which is not the logically next instr.
+ * As you can imagine, A is good and B is bad.
+ * Alternatively,
+ * 2. The Program Counter does not map through the MMU. The processor
+ * will take a Bus Error.
+ * Clearly, 2 is bad.
+ * It doesn't take a wiz kid to figure you want 1.A.
+ * This code creates that possibility.
+ * There are two possible 1.A. states (we now ignore the other above states):
+ * A. The kernel is located at physical memory addressed the same as
+ * the logical memory for the kernel, i.e., 0x01000.
+ * B. The kernel is located some where else. e.g., 0x0400.0000
+ *
+ * Under some conditions the Macintosh can look like A or B.
+ * [A friend and I once noted that Apple hardware engineers should be
+ * wacked twice each day: once when they show up at work (as in, Whack!,
+ * "This is for the screwy hardware we know you're going to design today."),
+ * and also at the end of the day (as in, Whack! "I don't know what
+ * you designed today, but I'm sure it wasn't good."). -- rst]
+ *
+ * This code works on the following premise:
+ * If the kernel start (%d5) is within the first 16 Meg of RAM,
+ * then create a mapping for the kernel at logical 0x8000.0000 to
+ * the physical location of the pc. And, create a transparent
+ * translation register for the first 16 Meg. Then, after the MMU
+ * is engaged, the PC can be moved up into the 0x8000.0000 range
+ * and then the transparent translation can be turned off and then
+ * the PC can jump to the correct logical location and it will be
+ * home (finally). This is essentially the code that the Amiga used
+ * to use. Now, it's generalized for all processors. Which means
+ * that a fresh (but temporary) mapping has to be created. The mapping
+ * is made in page 0 (an as of yet unused location -- except for the
+ * stack!). This temporary mapping will only require 1 pointer table
+ * and a single page table (it can map 256K).
+ *
+ * OK, alternatively, imagine that the Program Counter is not within
+ * the first 16 Meg. Then, just use Transparent Translation registers
+ * to do the right thing.
+ *
+ * Last, if _start is already at 0x01000, then there's nothing special
+ * to do (in other words, in a degenerate case of the first case above,
+ * do nothing).
+ *
+ * Let's do it.
+ *
+ *
X */
- /*
- * save physaddr of phys mem in register a3
- */
X
- .chip 68030
- lea %pc@(Lmmu),%a3
- movel %d5,%d0
- andl #0xff000000,%d0 /* logical address base */
- orw #TTR_ENABLE+TTR_CI+TTR_RWM+TTR_FCB2+TTR_FCM1+TTR_FCM0,%d0
- movel %d0,%a3@
- pmove %a3@,%tt0
- /* no limit, 4byte descriptors */
- movel #0x80000002,%a3@
- movel %a5,%a3@(4)
- pmove %a3@,%srp
- pmove %a3@,%crp
- pflusha
- /*
- * enable,super root enable,4096 byte pages,7 bit root index,
- * 7 bit pointer index, 6 bit page table index.
- */
- movel #0x82c07760,%a3@
- pmove %a3@,%tc /* enable the MMU */
- jmp 1f
-1:
- .chip 68k
+ putc 'H'
X
- /*
- * Fix up the custom register to point to the new location of the LEDs.
- */
- lea %pc@(Lcustom),%a1
- movel #0xf0000000,%a1@
+ mmu_engage
X
- /*
- * Energise the FPU and caches.
- */
- orl #0x64, 0xf05f400c
-
-Lmapphysnothp300:
+#ifdef CONFIG_AMIGA
+ is_not_amiga(1f)
+ /* fixup the Amiga custom register location before printing */
+ clrl L(custom)
+1:
+#endif
X
+#ifdef CONFIG_ATARI
+ is_not_atari(1f)
+ /* fixup the Atari iobase register location before printing */
+ movel #0xff000000,L(iobase)
+1:
+#endif
+
+#ifdef CONFIG_MAC
+ is_not_mac(1f)
+ movel #~VIDEOMEMMASK,%d0
+ andl L(mac_videobase),%d0
+ addl #VIDEOMEMBASE,%d0
+ movel %d0,L(mac_videobase)
+1:
X #endif
X
-#if defined(CONFIG_BVME6000)
- is_not_bvme6000(Lmapphysnotbvm)
+#ifdef CONFIG_HP300
+ is_not_hp300(1f)
X /*
- * save physaddr of phys mem in register a3
+ * Fix up the custom register to point to the new location of the LEDs.
X */
- moveq #'L',%d7
- jbsr Lserial_putc
+ movel #0xf0000000,L(custom)
X
- .word 0xf4d8 /* CINVA I/D */
- .word 0xf518 /* pflusha */
- .long 0x4e7bd807 /* movec a5,srp */
- .long 0x4e7bd806 /* movec a5,urp */
- movel #(TC_ENABLE+TC_PAGE4K),%d0
X /*
- * this value is also ok for the 68060, we don`t use the cache
- * mode/protection defaults
+ * Energise the FPU and caches.
X */
- .long 0x4e7b0003 /* movec d0,tc (enable the MMU) */
- jra LdoneMMUenable /* branch to continuation of startup */
-
-Lmapphysnotbvm:
-
+ movel #0x60,0xf05f400c
+1:
X #endif
X
-LdoneMMUenable:
-
X /*
X * Fixup the addresses for the kernel pointer table and availmem.
X * Convert them from physical addresses to virtual addresses.
X */
X
- putc('M')
- leds(0x10)
+ putc 'I'
+ leds 0x10
X
- /*
- * d5 contains physaddr of kernel start
- */
- subl %d5,SYMBOL_NAME(kpt)
-
- /*
- * do the same conversion on the first available memory
+ /* do the same conversion on the first available memory
X * address (in a6).
X */
- subl %d5,%a6
- movel %a6,SYMBOL_NAME(availmem) /* first available memory address */
-
- putc('N')
+ movel L(memory_start),%d0
+ movel %d0,SYMBOL_NAME(availmem)
X
X /*
X * Enable caches
X */
- is_040_or_060(Lcache680460)
X
- movel #CC3_ENABLE_DB+CC3_CLR_D+CC3_ENABLE_D+CC3_ENABLE_IB+CC3_CLR_I+CC3_ENABLE_I,%d0
- movec %d0,%cacr
- jra 1f
+ is_not_040_or_060(L(cache_not_680460))
X
-Lcache680460:
+L(cache680460):
X .chip 68040
+ nop
X cpusha %bc
- .chip 68k
+ nop
X
- is_060(Lcache68060)
+ is_060(L(cache68060))
X
X movel #CC6_ENABLE_D+CC6_ENABLE_I,%d0
X /* MMU stuff works in copyback mode now, so enable the cache */
X movec %d0,%cacr
- jra 1f
+ jra L(cache_done)
X
-Lcache68060:
- .chip 68060
+L(cache68060):
X movel #CC6_ENABLE_D+CC6_ENABLE_I+CC6_ENABLE_SB+CC6_PUSH_DPI+CC6_ENABLE_B+CC6_CLRA_B,%d0
X /* MMU stuff works in copyback mode now, so enable the cache */
X movec %d0,%cacr
X /* enable superscalar dispatch in PCR */
X moveq #1,%d0
+ .chip 68060
X movec %d0,%pcr
+
+ jbra L(cache_done)
+L(cache_not_680460):
+L(cache68030):
+ .chip 68030
+ movel #CC3_ENABLE_DB+CC3_CLR_D+CC3_ENABLE_D+CC3_ENABLE_IB+CC3_CLR_I+CC3_ENABLE_I,%d0
+ movec %d0,%cacr
+
+ jra L(cache_done)
X .chip 68k
-1:
+L(cache_done):
+
+ putc 'J'


X
X /*
X * Setup initial stack pointer

- * We need to get current loaded up with our first task...
X */
X lea SYMBOL_NAME(init_task_union),%a2
- lea 8192(%a2),%sp
+ lea 0x2000(%a2),%sp
X
X /* jump to the kernel start */
- putr()
- leds(0x55)
+ putc '\n'
+ leds 0x55
X
- subl %a6,%a6 /* clear a6 for gdb */
+ subl %a6,%a6 /* clear a6 for gdb */
X jbsr SYMBOL_NAME(start_kernel)
X
-/*
- * Find a tag record in the bootinfo structure
- * The bootinfo structure is located right after the kernel bss
- * Returns: d0: size (-1 if not found)
- * a0: data pointer (end-of-records if not found)
- */
-Lget_bi_record:
- lea %pc@(SYMBOL_NAME(_end)),%a0
-1: tstw %a0@(BIR_tag)
- jeq 3f
- cmpw %a0@(BIR_tag),%d0
- jeq 2f
- addw %a0@(BIR_size),%a0
- jra 1b
-2: moveq #0,%d0
- movew %a0@(BIR_size),%d0
- lea %a0@(BIR_data),%a0
- rts
-3: moveq #-1,%d0
- lea %a0@(BIR_size),%a0
- rts
+/*
+ * Find a tag record in the bootinfo structure
+ * The bootinfo structure is located right after the kernel bss
+ * Returns: d0: size (-1 if not found)
+ * a0: data pointer (end-of-records if not found)
+ */
+func_start get_bi_record,%d1
+
+ movel ARG1,%d0
+ lea %pc@(SYMBOL_NAME(_end)),%a0
+1: tstw %a0@(BIR_TAG)
+ jeq 3f
+ cmpw %a0@(BIR_TAG),%d0
+ jeq 2f
+ addw %a0@(BIR_SIZE),%a0
+ jra 1b
+2: moveq #0,%d0
+ movew %a0@(BIR_SIZE),%d0
+ lea %a0@(BIR_DATA),%a0
+ jra 4f
+3: moveq #-1,%d0
+ lea %a0@(BIR_SIZE),%a0
+4:
+func_return get_bi_record
+
+
+/*
+ * MMU Initialization Begins Here
+ *
+ * The structure of the MMU tables on the 68k machines
+ * is thus:
+ * Root Table
+ * Logical addresses are translated through
+ * a hierarchical translation mechanism where the high-order
+ * seven bits of the logical address (LA) are used as an
+ * index into the "root table." Each entry in the root
+ * table has a bit which specifies if it's a valid pointer to a
+ * pointer table. Each entry defines a 32KMeg range of memory.
+ * If an entry is invalid then that logical range of 32M is
+ * invalid and references to that range of memory (when the MMU
+ * is enabled) will fault. If the entry is valid, then it does
+ * one of two things. On 040/060 class machines, it points to
+ * a pointer table which then describes more finely the memory
+ * within that 32M range. On 020/030 class machines, a technique
+ * called "early terminating descriptors" are used. This technique
+ * allows an entire 32Meg to be described by a single entry in the
+ * root table. Thus, this entry in the root table, contains the
+ * physical address of the memory or I/O at the logical address
+ * which the entry represents and it also contains the necessary
+ * cache bits for this region.
+ *
+ * Pointer Tables
+ * Per the Root Table, there will be one or more
+ * pointer tables. Each pointer table defines a 32M range.
+ * Not all of the 32M range need be defined. Again, the next
+ * seven bits of the logical address are used an index into
+ * the pointer table to point to page tables (if the pointer
+ * is valid). There will undoubtedly be more than one
+ * pointer table for the kernel because each pointer table
+ * defines a range of only 32M. Valid pointer table entries
+ * point to page tables, or are early terminating entries
+ * themselves.
+ *
+ * Page Tables
+ * Per the Pointer Tables, each page table entry points
+ * to the physical page in memory that supports the logical
+ * address that translates to the particular index.
+ *
+ * In short, the Logical Address gets translated as follows:
+ * bits 31..26 - index into the Root Table
+ * bits 25..18 - index into the Pointer Table
+ * bits 17..12 - index into the Page Table
+ * bits 11..0 - offset into a particular 4K page
+ *
+ * The algorithms which follows do one thing: they abstract
+ * the MMU hardware. For example, there are three kinds of
+ * cache settings that are relevant. Either, memory is
+ * being mapped in which case it is either Kernel Code (or
+ * the RamDisk) or it is MMU data. On the 030, the MMU data
+ * option also describes the kernel. Or, I/O is being mapped
+ * in which case it has its own kind of cache bits. There
+ * are constants which abstract these notions from the code that
+ * actually makes the call to map some range of memory.


+ *
+ *
+ *

+ */
+
+#ifdef MMU_PRINT
+/*


+ * mmu_print
+ *

+ * This algorithm will print out the current MMU mappings.
+ *
+ * Input:
+ * %a5 points to the root table. Everything else is calculated
+ * from this.
+ */
+
+#define mmu_next_valid 0
+#define mmu_start_logical 4
+#define mmu_next_logical 8
+#define mmu_start_physical 12
+#define mmu_next_physical 16
+
+#define MMU_PRINT_INVALID -1
+#define MMU_PRINT_VALID 1
+#define MMU_PRINT_UNINITED 0
+
+#define putZc(z,n) jbne 1f; putc z; jbra 2f; 1: putc n; 2:
+
+func_start mmu_print,%a0-%a6/%d0-%d7
+
+ movel %pc@(L(kernel_pgdir_ptr)),%a5
+ lea %pc@(L(mmu_print_data)),%a0
+ movel #MMU_PRINT_UNINITED,%a0@(mmu_next_valid)
+
+ is_not_040_or_060(mmu_030_print)
+
+mmu_040_print:
+ puts "\nMMU040\n"
+ puts "rp:"
+ putn %a5
+ putc '\n'
+#if 0
+ /*
+ * The following #if/#endif block is a tight algorithm for dumping the 040
+ * MMU Map in gory detail. It really isn't that practical unless the
+ * MMU Map algorithm appears to go awry and you need to debug it at the
+ * entry per entry level.
+ */
+ movel #ROOT_TABLE_SIZE,%d5
+#if 0
+ movel %a5@+,%d7 | Burn an entry to skip the kernel mappings,
+ subql #1,%d5 | they (might) work
+#endif
+1: tstl %d5
+ jbeq mmu_print_done
+ subq #1,%d5
+ movel %a5@+,%d7
+ btst #1,%d7
+ jbeq 1b
+
+2: putn %d7
+ andil #0xFFFFFE00,%d7
+ movel %d7,%a4
+ movel #PTR_TABLE_SIZE,%d4
+ putc ' '
+3: tstl %d4
+ jbeq 11f
+ subq #1,%d4
+ movel %a4@+,%d7
+ btst #1,%d7
+ jbeq 3b
+
+4: putn %d7
+ andil #0xFFFFFF00,%d7
+ movel %d7,%a3
+ movel #PAGE_TABLE_SIZE,%d3
+5: movel #8,%d2
+6: tstl %d3
+ jbeq 31f
+ subq #1,%d3
+ movel %a3@+,%d6
+ btst #0,%d6
+ jbeq 6b
+7: tstl %d2
+ jbeq 8f
+ subq #1,%d2
+ putc ' '
+ jbra 91f
+8: putc '\n'
+ movel #8+1+8+1+1,%d2
+9: putc ' '
+ dbra %d2,9b
+ movel #7,%d2
+91: putn %d6
+ jbra 6b
+
+31: putc '\n'
+ movel #8+1,%d2
+32: putc ' '
+ dbra %d2,32b
+ jbra 3b
+
+11: putc '\n'
+ jbra 1b
+#endif /* MMU 040 Dumping code that's gory and detailed */
+
+ lea %pc@(SYMBOL_NAME(kernel_pg_dir)),%a5
+ movel %a5,%a0 /* a0 has the address of the root table ptr */
+ movel #0x00000000,%a4 /* logical address */
+ moveql #0,%d0
+40:
+ /* Increment the logical address and preserve in d5 */
+ movel %a4,%d5
+ addil #PAGESIZE<<13,%d5
+ movel %a0@+,%d6
+ btst #1,%d6
+ jbne 41f
+ jbsr mmu_print_tuple_invalidate
+ jbra 48f
+41:
+ movel #0,%d1
+ andil #0xfffffe00,%d6
+ movel %d6,%a1
+42:
+ movel %a4,%d5
+ addil #PAGESIZE<<6,%d5
+ movel %a1@+,%d6
+ btst #1,%d6
+ jbne 43f
+ jbsr mmu_print_tuple_invalidate
+ jbra 47f
+43:
+ movel #0,%d2
+ andil #0xffffff00,%d6
+ movel %d6,%a2
+44:
+ movel %a4,%d5
+ addil #PAGESIZE,%d5
+ movel %a2@+,%d6
+ btst #0,%d6
+ jbne 45f
+ jbsr mmu_print_tuple_invalidate
+ jbra 46f
+45:
+ moveml %d0-%d1,%sp@-
+ movel %a4,%d0
+ movel %d6,%d1
+ andil #0xfffff4e0,%d1
+ lea %pc@(mmu_040_print_flags),%a6
+ jbsr mmu_print_tuple
+ moveml %sp@+,%d0-%d1
+46:
+ movel %d5,%a4
+ addq #1,%d2
+ cmpib #64,%d2
+ jbne 44b
+47:
+ movel %d5,%a4
+ addq #1,%d1
+ cmpib #128,%d1
+ jbne 42b
+48:
+ movel %d5,%a4 /* move to the next logical address */
+ addq #1,%d0
+ cmpib #128,%d0
+ jbne 40b
+
+ .chip 68040
+ movec %dtt1,%d0
+ movel %d0,%d1
+ andiw #0x8000,%d1 /* is it valid ? */
+ jbeq 1f /* No, bail out */
+
+ movel %d0,%d1
+ andil #0xff000000,%d1 /* Get the address */
+ putn %d1
+ puts "=="
+ putn %d1
+
+ movel %d0,%d6
+ jbsr mmu_040_print_flags_tt
+1:
+ movec %dtt0,%d0
+ movel %d0,%d1
+ andiw #0x8000,%d1 /* is it valid ? */
+ jbeq 1f /* No, bail out */
+
+ movel %d0,%d1
+ andil #0xff000000,%d1 /* Get the address */
+ putn %d1
+ puts "=="
+ putn %d1
+
+ movel %d0,%d6
+ jbsr mmu_040_print_flags_tt
+1:
+ .chip 68k
+
+ jbra mmu_print_done
+
+mmu_040_print_flags:
+ btstl #10,%d6
+ putZc(' ','G') /* global bit */
+ btstl #7,%d6
+ putZc(' ','S') /* supervisor bit */
+mmu_040_print_flags_tt:
+ btstl #6,%d6
+ jbne 3f
+ putc 'C'
+ btstl #5,%d6
+ putZc('w','c') /* write through or copy-back */
+ jbra 4f
+3:
+ putc 'N'
+ btstl #5,%d6
+ putZc('s',' ') /* serialized non-cacheable, or non-cacheable */
+4:
+ rts
+
+mmu_030_print_flags:
+ btstl #6,%d6
+ putZc('C','I') /* write through or copy-back */
+ rts
+
+mmu_030_print:
+ puts "\nMMU030\n"
+ puts "\nrp:"
+ putn %a5
+ putc '\n'
+ movel %a5,%d0
+ andil #0xfffffff0,%d0
+ movel %d0,%a0
+ movel #0x00000000,%a4 /* logical address */
+ movel #0,%d0
+30:
+ movel %a4,%d5
+ addil #PAGESIZE<<13,%d5
+ movel %a0@+,%d6
+ btst #1,%d6 /* is it a ptr? */
+ jbne 31f /* yes */
+ btst #0,%d6 /* is it early terminating? */
+ jbeq 1f /* no */
+ jbsr mmu_030_print_helper
+ jbra 38f
+1:
+ jbsr mmu_print_tuple_invalidate
+ jbra 38f
+31:
+ movel #0,%d1
+ andil #0xfffffff0,%d6
+ movel %d6,%a1
+32:
+ movel %a4,%d5
+ addil #PAGESIZE<<6,%d5
+ movel %a1@+,%d6
+ btst #1,%d6
+ jbne 33f
+ btst #0,%d6
+ jbeq 1f /* no */
+ jbsr mmu_030_print_helper
+ jbra 37f
+1:
+ jbsr mmu_print_tuple_invalidate
+ jbra 37f
+33:
+ movel #0,%d2
+ andil #0xfffffff0,%d6
+ movel %d6,%a2
+34:
+ movel %a4,%d5
+ addil #PAGESIZE,%d5
+ movel %a2@+,%d6
+ btst #0,%d6
+ jbne 35f
+ jbsr mmu_print_tuple_invalidate
+ jbra 36f
+35:
+ jbsr mmu_030_print_helper
+36:
+ movel %d5,%a4
+ addq #1,%d2
+ cmpib #64,%d2
+ jbne 34b
+37:
+ movel %d5,%a4
+ addq #1,%d1
+ cmpib #128,%d1
+ jbne 32b
+38:
+ movel %d5,%a4 /* move to the next logical address */
+ addq #1,%d0
+ cmpib #128,%d0
+ jbne 30b
+
+mmu_print_done:
+ puts "\n\n"
+
+func_return mmu_print
+
+
+mmu_030_print_helper:
+ moveml %d0-%d1,%sp@-
+ movel %a4,%d0
+ movel %d6,%d1
+ lea %pc@(mmu_030_print_flags),%a6
+ jbsr mmu_print_tuple
+ moveml %sp@+,%d0-%d1
+ rts
+
+mmu_print_tuple_invalidate:
+ moveml %a0/%d7,%sp@-
+
+ lea %pc@(L(mmu_print_data)),%a0
+ tstl %a0@(mmu_next_valid)
+ jbmi mmu_print_tuple_invalidate_exit
+
+ movel #MMU_PRINT_INVALID,%a0@(mmu_next_valid)
+
+ putn %a4
+
+ puts "##\n"
+
+mmu_print_tuple_invalidate_exit:
+ moveml %sp@+,%a0/%d7
+ rts
+
+
+mmu_print_tuple:
+ moveml %d0-%d7/%a0,%sp@-
+
+ lea %pc@(L(mmu_print_data)),%a0
+
+ tstl %a0@(mmu_next_valid)
+ jble mmu_print_tuple_print
+
+ cmpl %a0@(mmu_next_physical),%d1
+ jbeq mmu_print_tuple_increment
+
+mmu_print_tuple_print:
+ putn %d0
+ puts "->"
+ putn %d1
+
+ movel %d1,%d6
+ jbsr %a6@
+
+mmu_print_tuple_record:
+ movel #MMU_PRINT_VALID,%a0@(mmu_next_valid)
+
+ movel %d1,%a0@(mmu_next_physical)
+
+mmu_print_tuple_increment:
+ movel %d5,%d7
+ subl %a4,%d7
+ addl %d7,%a0@(mmu_next_physical)
+
+mmu_print_tuple_exit:
+ moveml %sp@+,%d0-%d7/%a0
+ rts
+
+mmu_print_machine_cpu_types:
+ puts "machine: "
+
+ is_not_amiga(1f)
+ puts "amiga"
+ jbra 9f
+1:
+ is_not_atari(2f)
+ puts "atari"
+ jbra 9f
+2:
+ is_not_mac(3f)
+ puts "macintosh"
+ jbra 9f
+3: puts "unknown"
+9: putc '\n'
+
+ puts "cputype: 0"
+ is_not_060(1f)
+ putc '6'
+ jbra 9f
+1:
+ is_not_040_or_060(2f)
+ putc '4'
+ jbra 9f
+2: putc '3'
+9: putc '0'
+ putc '\n'
+
+ rts
+#endif /* MMU_PRINT */
+
+/*
+ * mmu_map_tt
+ *
+ * This is a specific function which works on all 680x0 machines.
+ * On 030, 040 & 060 it will attempt to use Transparent Translation
+ * registers (tt1).
+ * On 020 it will call the standard mmu_map which will use early
+ * terminating descriptors.
+ */
+func_start mmu_map_tt,%d0/%d1/%a0,4
+
+ dputs "mmu_map_tt:"
+ dputn ARG1
+ dputn ARG2
+ dputn ARG3
+ dputn ARG4
+ dputc '\n'
+
+ is_020(L(do_map))
+
+ /* Extract the highest bit set
+ */
+ bfffo ARG3{#0,#32},%d1
+ cmpw #8,%d0
+ jcc L(do_map)
+
+ /* And get the mask
+ */
+ moveq #-1,%d0
+ lsrl %d1,%d0
+ lsrl #1,%d0
+
+ /* Mask the address
+ */
+ movel %d0,%d1
+ notl %d1
+ andl ARG2,%d1
+
+ /* Generate the upper 16bit of the tt register
+ */
+ lsrl #8,%d0
+ orl %d0,%d1
+ clrw %d1
+
+ is_040_or_060(L(mmu_map_tt_040))
+
+ /* set 030 specific bits (read/write access for supervisor mode
+ * (highest function code set, lower two bits masked))
+ */
+ orw #TTR_ENABLE+TTR_RWM+TTR_FCB2+TTR_FCM1+TTR_FCM0,%d1
+ movel ARG4,%d0
+ btst #6,%d0
+ jeq 1f
+ orw #TTR_CI,%d1
+
+1: lea STACK,%a0
+ dputn %d1
+ movel %d1,%a0@
+ .chip 68030
+ tstl ARG1
+ jne 1f
+ pmove %a0@,%tt0
+ jra 2f
+1: pmove %a0@,%tt1
+2: .chip 68k
+ jra L(mmu_map_tt_done)
+
+ /* set 040 specific bits
+ */
+L(mmu_map_tt_040):
+ orw #TTR_ENABLE+TTR_KERNELMODE,%d1
+ orl ARG4,%d1
+ dputn %d1
+
+ .chip 68040
+ tstl ARG1
+ jne 1f
+ movec %d1,%itt0
+ movec %d1,%dtt0
+ jra 2f
+1: movec %d1,%itt1
+ movec %d1,%dtt1
+2: .chip 68k
+
+ jra L(mmu_map_tt_done)
+
+L(do_map):
+ mmu_map_eq ARG2,ARG3,ARG4
+
+L(mmu_map_tt_done):
+
+func_return mmu_map_tt
+
+/*


+ * mmu_map
+ *

+ * This routine will map a range of memory using a pointer
+ * table and allocating the pages on the fly from the kernel.
+ * The pointer table does not have to be already linked into
+ * the root table, this routine will do that if necessary.


+ *
+ * NOTE

+ * This routine will assert failure and use the serial_putc
+ * routines in the case of a run-time error. For example,
+ * if the address is already mapped.
+ *
+ * NOTE-2
+ * This routine will use early terminating descriptors
+ * where possible for the 68020+68851 and 68030 type
+ * processors.
+ */
+func_start mmu_map,%d0-%d4/%a0-%a4
+
+ dputs "\nmmu_map:"
+ dputn ARG1
+ dputn ARG2
+ dputn ARG3
+ dputn ARG4
+ dputc '\n'
+
+ /* Get logical address and round it down to 256KB
+ */
+ movel ARG1,%d0
+ andl #-(PAGESIZE*PAGE_TABLE_SIZE),%d0
+ movel %d0,%a3
+
+ /* Get the end address
+ */
+ movel ARG1,%a4
+ addl ARG3,%a4
+ subql #1,%a4
+
+ /* Get physical address and round it down to 256KB
+ */
+ movel ARG2,%d0
+ andl #-(PAGESIZE*PAGE_TABLE_SIZE),%d0
+ movel %d0,%a2
+
+ /* Add page attributes to the physical address
+ */
+ movel ARG4,%d0
+ orw #_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
+ addw %d0,%a2
+
+ dputn %a2
+ dputn %a3
+ dputn %a4
+
+ is_not_040_or_060(L(mmu_map_030))
+
+ addw #_PAGE_GLOBAL040,%a2
+/*
+ * MMU 040 & 060 Support
+ *
+ * The MMU usage for the 040 and 060 is different enough from
+ * the 030 and 68851 that there is separate code. This comment
+ * block describes the data structures and algorithms built by
+ * this code.
+ *
+ * The 040 does not support early terminating descriptors, as
+ * the 030 does. Therefore, a third level of table is needed
+ * for the 040, and that would be the page table. In Linux,
+ * page tables are allocated directly from the memory above the
+ * kernel.
+ *
+ */
+
+L(mmu_map_040):
+ /* Calculate the offset into the root table
+ */
+ movel %a3,%d0
+ moveq #ROOT_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ mmu_get_root_table_entry %d0
+
+ /* Calculate the offset into the pointer table
+ */
+ movel %a3,%d0
+ moveq #PTR_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ andl #PTR_TABLE_SIZE-1,%d0
+ mmu_get_ptr_table_entry %a0,%d0
+
+ /* Calculate the offset into the page table
+ */
+ movel %a3,%d0
+ moveq #PAGE_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ andl #PAGE_TABLE_SIZE-1,%d0
+ mmu_get_page_table_entry %a0,%d0
+
+ /* The page table entry must not no be busy
+ */
+ tstl %a0@
+ jne L(mmu_map_error)
+
+ /* Do the mapping and advance the pointers
+ */
+ movel %a2,%a0@
+2:
+ addw #PAGESIZE,%a2
+ addw #PAGESIZE,%a3
+
+ /* Ready with mapping?
+ */
+ lea %a3@(-1),%a0
+ cmpl %a0,%a4
+ jhi L(mmu_map_040)
+ jra L(mmu_map_done)
+
+L(mmu_map_030):
+ /* Calculate the offset into the root table
+ */
+ movel %a3,%d0
+ moveq #ROOT_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ mmu_get_root_table_entry %d0
+
+ /* Check if logical address 32MB aligned,
+ * so we can try to map it once
+ */
+ movel %a3,%d0
+ andl #(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE-1)&(-ROOT_TABLE_SIZE),%d0
+ jne 1f
+
+ /* Is there enough to map for 32MB at once
+ */
+ lea %a3@(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE-1),%a1
+ cmpl %a1,%a4
+ jcs 1f
+
+ addql #1,%a1
+
+ /* The root table entry must not no be busy
+ */
+ tstl %a0@
+ jne L(mmu_map_error)
+
+ /* Do the mapping and advance the pointers
+ */
+ dputs "early term1"
+ dputn %a2
+ dputn %a3
+ dputn %a1
+ dputc '\n'
+ movel %a2,%a0@
+
+ movel %a1,%a3
+ lea %a2@(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE),%a2
+ jra L(mmu_mapnext_030)
+1:
+ /* Calculate the offset into the pointer table
+ */
+ movel %a3,%d0
+ moveq #PTR_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ andl #PTR_TABLE_SIZE-1,%d0
+ mmu_get_ptr_table_entry %a0,%d0
+
+ /* The pointer table entry must not no be busy
+ */
+ tstl %a0@
+ jne L(mmu_map_error)
+
+ /* Do the mapping and advance the pointers
+ */
+ dputs "early term2"
+ dputn %a2
+ dputn %a3
+ dputc '\n'
+ movel %a2,%a0@
+
+ addl #PAGE_TABLE_SIZE*PAGESIZE,%a2
+ addl #PAGE_TABLE_SIZE*PAGESIZE,%a3
+
+L(mmu_mapnext_030):
+ /* Ready with mapping?
+ */
+ lea %a3@(-1),%a0
+ cmpl %a0,%a4
+ jhi L(mmu_map_030)
+ jra L(mmu_map_done)
+
+L(mmu_map_error):
+
+ dputs "mmu_map error:"
+ dputn %a2
+ dputn %a3
+ dputc '\n'
+
+L(mmu_map_done):
+
+func_return mmu_map
+
+/*
+ * mmu_fixup
+ *
+ * On the 040 class machines, all pages that are used for the
+ * mmu have to be fixed up.
+ */
+
+func_start mmu_fixup_page_mmu_cache,%d0/%a0
+
+ dputs "mmu_fixup_page_mmu_cache"
+ dputn ARG1
+
+ /* Calculate the offset into the root table
+ */
+ movel ARG1,%d0
+ moveq #ROOT_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ mmu_get_root_table_entry %d0
+
+ /* Calculate the offset into the pointer table
+ */
+ movel ARG1,%d0
+ moveq #PTR_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ andl #PTR_TABLE_SIZE-1,%d0
+ mmu_get_ptr_table_entry %a0,%d0
+
+ /* Calculate the offset into the page table
+ */
+ movel ARG1,%d0
+ moveq #PAGE_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ andl #PAGE_TABLE_SIZE-1,%d0
+ mmu_get_page_table_entry %a0,%d0
+
+ movel %a0@,%d0
+ andil #_CACHEMASK040,%d0
+ orl %pc@(SYMBOL_NAME(m68k_pgtable_cachemode)),%d0
+ movel %d0,%a0@
+
+ dputc '\n'
+
+func_return mmu_fixup_page_mmu_cache
+
+/*
+ * mmu_temp_map
+ *
+ * create a temporary mapping to enable the mmu,
+ * this we don't need any transparation translation tricks.
+ */
+
+func_start mmu_temp_map,%d0/%d1/%a0/%a1
+
+ dputs "mmu_temp_map"
+ dputn ARG1
+ dputn ARG2
+ dputc '\n'
+
+ lea %pc@(L(temp_mmap_mem)),%a1
+
+ /* Calculate the offset in the root table
+ */
+ movel ARG2,%d0
+ moveq #ROOT_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ mmu_get_root_table_entry %d0
+
+ /* Check if the table is temporary allocated, so we have to reuse it
+ */
+ movel %a0@,%d0
+ cmpl %pc@(L(memory_start)),%d0
+ jcc 1f
+
+ /* Temporary allocate a ptr table and insert it into the root table
+ */
+ movel %a1@,%d0
+ addl #PTR_TABLE_SIZE*4,%a1@
+ orw #_PAGE_TABLE+_PAGE_ACCESSED,%d0
+ movel %d0,%a0@
+ dputs " (new)"
+1:
+ dputn %d0
+ /* Mask the root table entry for the ptr table
+ */
+ andw #-ROOT_TABLE_SIZE,%d0
+ movel %d0,%a0
+
+ /* Calculate the offset into the pointer table
+ */
+ movel ARG2,%d0
+ moveq #PTR_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ andl #PTR_TABLE_SIZE-1,%d0
+ lea %a0@(%d0*4),%a0
+ dputn %a0
+
+ /* Check if a temporary page table is already allocated
+ */
+ movel %a0@,%d0
+ jne 1f
+
+ /* Temporary allocate a page table and insert it into the ptr table
+ */
+ movel %a1@,%d0
+ addl #PTR_TABLE_SIZE*4,%a1@
+ orw #_PAGE_TABLE+_PAGE_ACCESSED,%d0
+ movel %d0,%a0@
+ dputs " (new)"
+1:
+ dputn %d0
+ /* Mask the ptr table entry for the page table
+ */
+ andw #-PTR_TABLE_SIZE,%d0
+ movel %d0,%a0
+
+ /* Calculate the offset into the page table
+ */
+ movel ARG2,%d0
+ moveq #PAGE_INDEX_SHIFT,%d1
+ lsrl %d1,%d0
+ andl #PAGE_TABLE_SIZE-1,%d0
+ lea %a0@(%d0*4),%a0
+ dputn %a0
+
+ /* Insert the address into the page table
+ */
+ movel ARG1,%d0
+ andw #-PAGESIZE,%d0
+ orw #_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
+ movel %d0,%a0@
+ dputn %d0
+
+ dputc '\n'
+
+func_return mmu_temp_map
+
+func_start mmu_engage,%d0-%d2/%a0-%a3
+
+ moveq #ROOT_TABLE_SIZE-1,%d0
+ /* Temporarily use a different root table. */
+ lea %pc@(L(kernel_pgdir_ptr)),%a0
+ movel %a0@,%a2
+ movel %pc@(L(memory_start)),%a1
+ movel %a1,%a0@
+ movel %a2,%a0
+1:
+ movel %a0@+,%a1@+
+ dbra %d0,1b
+
+ lea %pc@(L(temp_mmap_mem)),%a0
+ movel %a1,%a0@
+
+ movew #PAGESIZE-1,%d0
+1:
+ clrl %a1@+
+ dbra %d0,1b
+
+ lea %pc@(1b),%a0
+ movel #1b,%a1
+ /* Skip temp mappings if phys == virt */
+ cmpl %a0,%a1
+ jeq 1f
+
+ mmu_temp_map %a0,%a0
+ mmu_temp_map %a0,%a1
+
+ addw #PAGESIZE,%a0
+ addw #PAGESIZE,%a1
+ mmu_temp_map %a0,%a0
+ mmu_temp_map %a0,%a1
+1:
+ movel %pc@(L(memory_start)),%a3
+ movel %pc@(L(phys_kernel_start)),%d2
+
+ is_not_040_or_060(L(mmu_engage_030))
+
+L(mmu_engage_040):
+ .chip 68040
+ nop
+ cinva %bc
+ nop
+ pflusha
+ nop
+ movec %a3,%srp
+ movel #TC_ENABLE+TC_PAGE4K,%d0
+ movec %d0,%tc /* enable the MMU */
+ jmp 1f:l
+1: nop
+ movec %a2,%srp
+ nop
+ cinva %bc
+ nop
+ pflusha
+ .chip 68k
+ jra L(mmu_engage_cleanup)
+
+L(mmu_engage_030_temp):
+ .space 12
+L(mmu_engage_030):
+ .chip 68030
+ lea %pc@(L(mmu_engage_030_temp)),%a0
+ movel #0x80000002,%a0@
+ movel %a3,%a0@(4)
+ movel #0x0808,%d0
+ movec %d0,%cacr
+ pmove %a0@,%srp
+ pflusha
+ /*
+ * enable,super root enable,4096 byte pages,7 bit root index,
+ * 7 bit pointer index, 6 bit page table index.
+ */
+ movel #0x82c07760,%a0@(8)
+ pmove %a0@(8),%tc /* enable the MMU */
+ jmp 1f:l
+1: movel %a2,%a0@(4)
+ movel #0x0808,%d0
+ movec %d0,%cacr
+ pmove %a0@,%srp
+ pflusha
+ .chip 68k
+
+L(mmu_engage_cleanup):
+ subl %d2,%a2
+ movel %a2,L(kernel_pgdir_ptr)
+ subl %d2,%fp
+ subl %d2,%sp
+ subl %d2,ARG0
+ subl %d2,L(memory_start)
+
+func_return mmu_engage
+
+func_start mmu_get_root_table_entry,%d0/%a1
+
+#if 0
+ dputs "mmu_get_root_table_entry:"
+ dputn ARG1
+ dputs " ="
+#endif
+
+ movel %pc@(L(kernel_pgdir_ptr)),%a0
+ tstl %a0
+ jne 2f
+
+ dputs "\nmmu_init:"
+
+ /* Find the start of free memory, get_bi_record does this for us,
+ * as the bootinfo structure is located directly behind the kernel
+ * and and we simply search for the last entry.
+ */
+ get_bi_record BI_LAST
+ addw #PAGESIZE-1,%a0
+ movel %a0,%d0
+ andw #-PAGESIZE,%d0
+
+ dputn %d0
+
+ lea %pc@(L(memory_start)),%a0
+ movel %d0,%a0@
+ lea %pc@(L(kernel_end)),%a0
+ movel %d0,%a0@
+
+ /* we have to return the first page at _stext since the init code
+ * in mm/init.c simply expects kernel_pg_dir there, the rest of
+ * page is used for further ptr tables in get_ptr_table.
+ */
+ lea %pc@(SYMBOL_NAME(_stext)),%a0
+ lea %pc@(L(mmu_cached_pointer_tables)),%a1
+ movel %a0,%a1@
+ addl #ROOT_TABLE_SIZE*4,%a1@
+
+ lea %pc@(L(mmu_num_pointer_tables)),%a1
+ addql #1,%a1@
+
+ /* clear the page
+ */
+ movel %a0,%a1
+ movew #PAGESIZE/4-1,%d0
+1:
+ clrl %a1@+
+ dbra %d0,1b
+
+ lea %pc@(L(kernel_pgdir_ptr)),%a1
+ movel %a0,%a1@
+
+ dputn %a0
+ dputc '\n'
+2:
+ movel ARG1,%d0
+ lea %a0@(%d0*4),%a0
+
+#if 0
+ dputn %a0
+ dputc '\n'
+#endif
+
+func_return mmu_get_root_table_entry
+
+
+
+func_start mmu_get_ptr_table_entry,%d0/%a1
+
+#if 0
+ dputs "mmu_get_ptr_table_entry:"
+ dputn ARG1
+ dputn ARG2
+ dputs " ="
+#endif
+
+ movel ARG1,%a0
+ movel %a0@,%d0
+ jne 2f
+
+ /* Keep track of the number of pointer tables we use
+ */
+ dputs "\nmmu_get_new_ptr_table:"
+ lea %pc@(L(mmu_num_pointer_tables)),%a0
+ movel %a0@,%d0
+ addql #1,%a0@
+
+ /* See if there is a free pointer table in our cache of pointer tables
+ */
+ lea %pc@(L(mmu_cached_pointer_tables)),%a1
+ andw #7,%d0
+ jne 1f
+
+ /* Get a new pointer table page from above the kernel memory
+ */
+ get_new_page
+ movel %a0,%a1@
+1:
+ /* There is an unused pointer table in our cache... use it
+ */
+ movel %a1@,%d0
+ addl #PTR_TABLE_SIZE*4,%a1@
+
+ dputn %d0
+ dputc '\n'
+
+ /* Insert the new pointer table into the root table
+ */
+ movel ARG1,%a0
+ orw #_PAGE_TABLE+_PAGE_ACCESSED,%d0
+ movel %d0,%a0@
+2:
+ /* Extract the pointer table entry
+ */
+ andw #-PTR_TABLE_SIZE,%d0
+ movel %d0,%a0
+ movel ARG2,%d0
+ lea %a0@(%d0*4),%a0
+
+#if 0
+ dputn %a0
+ dputc '\n'
+#endif
+
+func_return mmu_get_ptr_table_entry
+
+
+func_start mmu_get_page_table_entry,%d0/%a1
+
+#if 0
+ dputs "mmu_get_page_table_entry:"
+ dputn ARG1
+ dputn ARG2
+ dputs " ="
+#endif
+
+ movel ARG1,%a0
+ movel %a0@,%d0
+ jne 2f
+
+ /* If the page table entry doesn't exist, we allocate a complete new
+ * page and use it as one continues big page table which can cover
+ * 4MB of memory, nearly almost all mappings have that alignment.
+ */
+ get_new_page
+ addw #_PAGE_TABLE+_PAGE_ACCESSED,%a0
+
+ /* align pointer table entry for a page of page tables
+ */
+ movel ARG1,%d0
+ andw #-(PAGESIZE/PAGE_TABLE_SIZE),%d0
+ movel %d0,%a1
+
+ /* Insert the page tables into the pointer entries
+ */
+ moveq #PAGESIZE/PAGE_TABLE_SIZE/4-1,%d0
+1:
+ movel %a0,%a1@+
+ lea %a0@(PAGE_TABLE_SIZE*4),%a0
+ dbra %d0,1b
+
+ /* Now we can get the initialized pointer table entry
+ */
+ movel ARG1,%a0
+ movel %a0@,%d0
+2:
+ /* Extract the page table entry
+ */
+ andw #-PAGE_TABLE_SIZE,%d0
+ movel %d0,%a0
+ movel ARG2,%d0
+ lea %a0@(%d0*4),%a0
+
+#if 0
+ dputn %a0
+ dputc '\n'
+#endif
+
+func_return mmu_get_page_table_entry
+
+/*
+ * get_new_page
+ *
+ * Return a new page from the memory start and clear it.
+ */
+func_start get_new_page,%d0/%a1
+
+ dputs "\nget_new_page:"
+
+ /* allocate the page and adjust memory_start
+ */
+ lea %pc@(L(memory_start)),%a0
+ movel %a0@,%a1
+ addl #PAGESIZE,%a0@
+
+ /* clear the new page
+ */
+ movel %a1,%a0
+ movew #PAGESIZE/4-1,%d0
+1:
+ clrl %a1@+
+ dbra %d0,1b
+
+ dputn %a0
+ dputc '\n'
+
+func_return get_new_page
+
+
X
X /*
X * Debug output support
@@ -1112,11 +2499,49 @@
X * from the MFP or a serial port of the SCC
X */
X
+#ifdef CONFIG_MAC
+
+L(scc_initable_mac):
+ .byte 9,12 /* Reset */
+ .byte 4,0x44 /* x16, 1 stopbit, no parity */
+ .byte 3,0xc0 /* receiver: 8 bpc */
+ .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */
+ .byte 9,0 /* no interrupts */
+ .byte 10,0 /* NRZ */
+ .byte 11,0x50 /* use baud rate generator */
+ .byte 12,10,13,0 /* 9600 baud */
+ .byte 14,1 /* Baud rate generator enable */
+ .byte 3,0xc1 /* enable receiver */
+ .byte 5,0xea /* enable transmitter */
+ .byte -1
+ .even
+#endif
+
X #ifdef CONFIG_ATARI
X /* #define USE_PRINTER */
-/* #define USE_SCC */
+/* #define USE_SCC_B */
+/* #define USE_SCC_A */
X #define USE_MFP
X
+#if defined(USE_SCC_A) || defined(USE_SCC_B)
+#define USE_SCC
+/* Initialisation table for SCC */
+L(scc_initable):
+ .byte 9,12 /* Reset */
+ .byte 4,0x44 /* x16, 1 stopbit, no parity */
+ .byte 3,0xc0 /* receiver: 8 bpc */
+ .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */
+ .byte 9,0 /* no interrupts */
+ .byte 10,0 /* NRZ */
+ .byte 11,0x50 /* use baud rate generator */
+ .byte 12,24,13,0 /* 9600 baud */
+ .byte 14,2,14,3 /* use master clock for BRG, enable */
+ .byte 3,0xc1 /* enable receiver */
+ .byte 5,0xea /* enable transmitter */
+ .byte -1
+ .even
+#endif
+
X #ifdef USE_PRINTER
X
X LPSG_SELECT = 0xff8800
@@ -1129,13 +2554,18 @@
X LSTMFP_DDR = 0xfffa05
X LSTMFP_IERB = 0xfffa09
X
-#elif defined(USE_SCC)
-
-LSCC_CTRL_B = 0xff8c85
-LSCC_DATA_B = 0xff8c87
+#elif defined(USE_SCC_B)
+
+LSCC_CTRL = 0xff8c85
+LSCC_DATA = 0xff8c87
+
+#elif defined(USE_SCC_A)
+
+LSCC_CTRL = 0xff8c81
+LSCC_DATA = 0xff8c83
X
X /* Initialisation table for SCC */
-scc_initable:
+L(scc_initable):
X .byte 9,12 /* Reset */
X .byte 4,0x44 /* x16, 1 stopbit, no parity */
X .byte 3,0xc0 /* receiver: 8 bpc */
@@ -1159,45 +2589,48 @@
X LMFP_UDR = 0xfffa2f
X
X #endif
-#endif
-
-#if defined (CONFIG_BVME6000)
-BVME_SCC_CTRL_A = 0xffb0000b
-BVME_SCC_DATA_A = 0xffb0000f
-#endif
+#endif /* CONFIG_ATARI */
X
X /*
X * Serial port output support.
X */
-LSERPER = 0xdff032
-LSERDAT = 0xdff030
-LSERDATR = 0xdff018
-LSERIAL_CNTRL = 0xbfd000
-LSERIAL_DTR = 7
X
X /*
X * Initialize serial port hardware for 9600/8/1
- * a0 thrashed
- * Amiga d0 trashed
- * Atari d0 trashed (a1 in case of SCC)
X */
- .even
-Lserial_init:
+func_start serial_init,%d0/%d1/%a0/%a1
+ /*
+ * Some of the register usage that follows
+ * CONFIG_AMIGA
+ * a0 = pointer to boot info record
+ * d0 = boot info offset
+ * CONFIG_ATARI
+ * a0 = address of SCC
+ * a1 = Liobase address/address of scc_initable
+ * d0 = init data for serial port
+ * CONFIG_MAC
+ * a0 = address of SCC
+ * a1 = address of scc_initable_mac
+ * d0 = init data for serial port
+ */
+
X #ifdef CONFIG_AMIGA
- cmpil #MACH_AMIGA,%d4
- jne 1f
- bclr #LSERIAL_DTR,LSERIAL_CNTRL
- movew #BI_AMIGA_SERPER,%d0
- jbsr Lget_bi_record
- movew %a0@,LSERPER
- jra 9f
+#define SERIAL_DTR 7
+#define SERIAL_CNTRL CIABBASE+C_PRA
+
+ is_not_amiga(1f)
+ lea %pc@(L(custom)),%a0
+ movel #-ZTWOBASE,%a0@
+ bclr #SERIAL_DTR,SERIAL_CNTRL-ZTWOBASE
+ get_bi_record BI_AMIGA_SERPER
+ movew %a0@,CUSTOMBASE+C_SERPER-ZTWOBASE
+| movew #61,CUSTOMBASE+C_SERPER-ZTWOBASE
X 1:
X #endif
X #ifdef CONFIG_ATARI
- cmpil #MACH_ATARI,%d4
- jne 4f
- movel %pc@(Liobase),%a1
-#ifdef USE_PRINTER
+ is_not_atari(4f)
+ movel %pc@(L(iobase)),%a1
+#if defined(USE_PRINTER)
X bclr #0,%a1@(LSTMFP_IERB)
X bclr #0,%a1@(LSTMFP_DDR)
X moveb #LPSG_CONTROL,%a1@(LPSG_SELECT)
@@ -1209,8 +2642,8 @@
X bset #5,%d0
X moveb %d0,%a1@(LPSG_WRITE)
X #elif defined(USE_SCC)
- lea %a1@(LSCC_CTRL_B),%a0
- lea %pc@(scc_initable:w),%a1
+ lea %a1@(LSCC_CTRL),%a0
+ lea %pc@(L(scc_initable)),%a1
X 2: moveb %a1@+,%d0
X jmi 3f
X moveb %d0,%a0@
@@ -1225,174 +2658,854 @@
X orb #1,%a1@(LMFP_TDCDR)
X bset #1,%a1@(LMFP_TSR)
X #endif
+ jra L(serial_init_done)
X 4:
X #endif
-9:
- rts
+#ifdef CONFIG_MAC
+ is_not_mac(L(serial_init_not_mac))
+#ifdef MAC_SERIAL_DEBUG
+#if !defined(MAC_USE_SCC_A) && !defined(MAC_USE_SCC_B)
+#define MAC_USE_SCC_B
+#endif
+#define mac_scc_cha_b_ctrl_offset 0x0
+#define mac_scc_cha_a_ctrl_offset 0x2
+#define mac_scc_cha_b_data_offset 0x4
+#define mac_scc_cha_a_data_offset 0x6
+
+#ifdef MAC_USE_SCC_A
+ /* Initialize channel A */
+ movel %pc@(L(mac_sccbase)),%a0
+ lea %pc@(L(scc_initable_mac)),%a1
+5: moveb %a1@+,%d0
+ jmi 6f
+ moveb %d0,%a0@(mac_scc_cha_a_ctrl_offset)
+ moveb %a1@+,%a0@(mac_scc_cha_a_ctrl_offset)
+ jra 5b
+6:
+#endif /* MAC_USE_SCC_A */
+
+#ifdef MAC_USE_SCC_B
+ /* Initialize channel B */
+#ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */
+ movel %pc@(L(mac_sccbase)),%a0
+#endif /* MAC_USE_SCC_A */
+ lea %pc@(L(scc_initable_mac)),%a1
+7: moveb %a1@+,%d0
+ jmi 8f
+ moveb %d0,%a0@(mac_scc_cha_b_ctrl_offset)
+ moveb %a1@+,%a0@(mac_scc_cha_b_ctrl_offset)
+ jra 7b
+8:
+#endif /* MAC_USE_SCC_B */


+#endif /* MAC_SERIAL_DEBUG */
+

+ jra L(serial_init_done)
+L(serial_init_not_mac):


+#endif /* CONFIG_MAC */
+

+L(serial_init_done):
+func_return serial_init
X
-#ifdef CONFIG_HP300
-/* Set LEDs to %d7 */
- .even
-Lset_leds:
- moveml %a0/%a1,%sp@-
- movel %pc@(Lcustom),%a1
- moveb %d7,%a1@(0x1ffff)
- moveml %sp@+,%a0/%a1
- rts
-#endif
-
X /*
- * Output character in d7 on serial port.
- * d7 thrashed.
+ * Output character on serial port.
X */
-Lserial_putc:
- moveml %a0/%a1,%sp@-
-#if defined(CONFIG_MVME16x)
- cmpil #MACH_MVME16x,%d4
- jne 2f
- moveb %d7,%sp@-
- .long 0x4e4f0020
- jra 9f
-2:
-#endif
-#ifdef CONFIG_BVME6000
- cmpil #MACH_BVME6000,%d4
- jne 2f
-1: btst #2,BVME_SCC_CTRL_A
- jeq 1b
- moveb %d7,BVME_SCC_DATA_A
- jra 9f
-2:
-#endif
+func_start serial_putc,%d0/%d1/%a0/%a1
+
+ movel ARG1,%d0
+ cmpib #'\n',%d0
+ jbne 1f
+
+ /* A little safe recursion is good for the soul */
+ serial_putc #'\r'
+1:
+
X #ifdef CONFIG_AMIGA
- cmpil #MACH_AMIGA,%d4
- jne 2f
- andw #0x00ff,%d7
- oriw #0x0100,%d7
- movel %pc@(Lcustom),%a1
- movew %d7,%a1@(LSERDAT)
-1: movew %a1@(LSERDATR),%d7
- andw #0x2000,%d7
+ is_not_amiga(2f)
+ andw #0x00ff,%d0
+ oriw #0x0100,%d0
+ movel %pc@(L(custom)),%a0
+ movew %d0,%a0@(CUSTOMBASE+C_SERDAT)
+1: movew %a0@(CUSTOMBASE+C_SERDATR),%d0
+ andw #0x2000,%d0
X jeq 1b
- jra 9f
+ jra L(serial_putc_done)
X 2:
X #endif
+
+#ifdef CONFIG_MAC
+ is_not_mac(5f)
+
+#ifdef CONSOLE
+ console_putc %d0
+#endif /* CONSOLE */
+
+#ifdef MAC_SERIAL_DEBUG
+
+#ifdef MAC_USE_SCC_A
+ movel %pc@(L(mac_sccbase)),%a1
+3: btst #2,%a1@(mac_scc_cha_a_ctrl_offset)
+ jeq 3b
+ moveb %d0,%a1@(mac_scc_cha_a_data_offset)
+#endif /* MAC_USE_SCC_A */


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 03'
echo 'File patch-2.2.0-pre9 is continued in part 04'
echo 04 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part04

#!/bin/sh
# this is part 04 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 04; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

+
+#ifdef MAC_USE_SCC_B


+#ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */

+ movel %pc@(L(mac_sccbase)),%a1
+#endif /* MAC_USE_SCC_A */
+4: btst #2,%a1@(mac_scc_cha_b_ctrl_offset)
+ jeq 4b
+ moveb %d0,%a1@(mac_scc_cha_b_data_offset)
+#endif /* MAC_USE_SCC_B */
+


+#endif /* MAC_SERIAL_DEBUG */
+

+ jra L(serial_putc_done)
+5:


+#endif /* CONFIG_MAC */
+

X #ifdef CONFIG_ATARI
- cmpil #MACH_ATARI,%d4
- jne 4f
- movel %pc@(Liobase),%a1
-#ifdef USE_PRINTER
+ is_not_atari(4f)
+ movel %pc@(L(iobase)),%a1
+#if defined(USE_PRINTER)

X 3: btst #0,%a1@(LSTMFP_GPIP)
X jne 3b
X moveb #LPSG_IO_B,%a1@(LPSG_SELECT)
- moveb %d7,%a1@(LPSG_WRITE)
+ moveb %d0,%a1@(LPSG_WRITE)
X moveb #LPSG_IO_A,%a1@(LPSG_SELECT)
- moveb %a1@(LPSG_READ),%d7
- bclr #5,%d7
- moveb %d7,%a1@(LPSG_WRITE)
+ moveb %a1@(LPSG_READ),%d0
+ bclr #5,%d0
+ moveb %d0,%a1@(LPSG_WRITE)
X nop
X nop
- bset #5,%d7
- moveb %d7,%a1@(LPSG_WRITE)
+ bset #5,%d0
+ moveb %d0,%a1@(LPSG_WRITE)
X #elif defined(USE_SCC)
-3: btst #2,%a1@(LSCC_CTRL_B)
+3: btst #2,%a1@(LSCC_CTRL)
X jeq 3b
- moveb %d7,%a1@(LSCC_DATA_B)
+ moveb %d0,%a1@(LSCC_DATA)
X #elif defined(USE_MFP)
X 3: btst #7,%a1@(LMFP_TSR)
X jeq 3b
- moveb %d7,%a1@(LMFP_UDR)
+ moveb %d0,%a1@(LMFP_UDR)
X #endif
+ jra L(serial_putc_done)
X 4:
+#endif /* CONFIG_ATARI */
+
+#ifdef CONFIG_MVME16x
+ is_not_mvme16x(2f)
+ /*
+ * The VME 16x class has PROM support for serial output
+ * of some kind; the TRAP table is still valid.
+ */
+ moveml %d0-%d7/%a2-%a6,%sp@-
+ moveb %d0,%sp@-
+ trap #15
+ .word 0x0020 /* TRAP 0x020 */
+ moveml %sp@+,%d0-%d7/%a2-%a6
+ jbra L(serial_putc_done)
+2:
+#endif CONFIG_MVME162 | CONFIG_MVME167
+
+#ifdef CONFIG_BVME6000
+ is_not_bvme6000(2f)
+ /*
+ * The BVME6000 machine has a serial port ...
+ */
+1: btst #2,BVME_SCC_CTRL_A
+ jeq 1b
+ moveb %d0,BVME_SCC_DATA_A
+ jbra L(serial_putc_done)
+2:
X #endif
-9:


- moveml %sp@+,%a0/%a1
- rts

+
+L(serial_putc_done):
+func_return serial_putc
X
X /*
- * Output string pointed to by a0 to serial port.
- * a0 trashed.
+ * Output a string.
X */
-Lserial_puts:
- movel %d7,%sp@-
-1: moveb %a0@+,%d7
- jeq 2f
- jbsr Lserial_putc
- jra 1b
-2: movel %sp@+,%d7
- rts
+func_start puts,%d0/%a0
+
+ movel ARG1,%a0
+ jra 2f
+1:


+#ifdef CONSOLE
+ console_putc %d0
+#endif

+#ifdef SERIAL_DEBUG
+ serial_putc %d0
+#endif
+2: moveb %a0@+,%d0
+ jne 1b
+
+func_return puts
X
X /*
- * Output number in d7 in hex notation on serial port.
+ * Output number in hex notation.
X */
X
-Lserial_putnum:
- moveml %d0-%d2/%d7,%sp@-
- movel %d7,%d1
- moveq #4,%d0
- moveq #7,%d2
-L1: roll %d0,%d1
- moveb %d1,%d7
- andb #0x0f,%d7
- cmpb #0x0a,%d7
- jcc 1f
- addb #'0',%d7
+func_start putn,%d0-%d2
+
+ putc ' '
+
+ movel ARG1,%d0
+ moveq #7,%d1
+1: roll #4,%d0
+ move %d0,%d2
+ andb #0x0f,%d2
+ addb #'0',%d2
+ cmpb #'9',%d2
+ jls 2f
+ addb #'A'-('9'+1),%d2
+2:
+#ifdef CONSOLE
+ console_putc %d2
+#endif
+#ifdef SERIAL_DEBUG
+ serial_putc %d2
+#endif
+ dbra %d1,1b
+
+func_return putn
+
+#ifdef CONFIG_MAC
+/*
+ * mac_serial_print
+ *
+ * This routine takes its parameters on the stack. It then
+ * turns around and calls the internal routine. This routine
+ * is used until the Linux console driver initializes itself.
+ *
+ * The calling parameters are:
+ * void mac_serial_print(const char *str);
+ *
+ * This routine does NOT understand variable arguments only
+ * simple strings!
+ */
+ENTRY(mac_serial_print)
+ moveml %d0/%a0,%sp@-
+#if 1
+ move %sr,%sp@-
+ ori #0x0700,%sr
+#endif
+ movel %sp@(10),%a0 /* fetch parameter */
X jra 2f
-1: addb #'A'-10,%d7
-2: jbsr Lserial_putc
- dbra %d2,L1
- moveq #32,%d7
- jbsr Lserial_putc
- moveml %sp@+,%d0-%d2/%d7
+1: serial_putc %d0
+2: moveb %a0@+,%d0
+ jne 1b
+#if 1
+ move %sp@+,%sr
+#endif
+ moveml %sp@+,%d0/%a0
+ rts


+#endif /* CONFIG_MAC */
+

+#ifdef CONFIG_HP300
+func_start set_leds,%d0/%a0
+ movel ARG1,%d0
+ movel %pc@(Lcustom),%a0
+ moveb %d0,%a0@(0x1ffff)
+func_return set_leds
+#endif
+
+#ifdef CONSOLE
+/*
+ * For continuity, see the data alignment
+ * to which this structure is tied.
+ */
+#define Lconsole_struct_cur_column 0
+#define Lconsole_struct_cur_row 4
+#define Lconsole_struct_num_columns 8
+#define Lconsole_struct_num_rows 12
+#define Lconsole_struct_left_edge 16
+#define Lconsole_struct_penguin_putc 20
+
+L(console_init):


+ /*
+ * Some of the register usage that follows

+ * a0 = pointer to boot_info
+ * a1 = pointer to screen
+ * a2 = pointer to Lconsole_globals
+ * d3 = pixel width of screen
+ * d4 = pixel height of screen
+ * (d3,d4) ~= (x,y) of a point just below
+ * and to the right of the screen
+ * NOT on the screen!
+ * d5 = number of bytes per scan line
+ * d6 = number of bytes on the entire screen
+ */
+ moveml %a0-%a4/%d0-%d7,%sp@-
+
+ lea %pc@(L(console_globals)),%a2


+ lea %pc@(L(mac_videobase)),%a0
+ movel %a0@,%a1

+ lea %pc@(L(mac_rowbytes)),%a0
+ movel %a0@,%d5
+ lea %pc@(L(mac_dimensions)),%a0
+ movel %a0@,%d3 /* -> low byte */
+ movel %d3,%d4
+ swap %d4 /* -> high byte */
+ andl #0xffff,%d3 /* d3 = screen width in pixels */
+ andl #0xffff,%d4 /* d4 = screen height in pixels */
+
+ movel %d5,%d6
+ subl #20,%d6
+ mulul %d4,%d6 /* scan line bytes x num scan lines */
+ divul #8,%d6 /* we'll clear 8 bytes at a time */
+ subq #1,%d6
+
+console_clear_loop:
+ movel #0xffffffff,%a1@+ /* Mac_black */
+ movel #0xffffffff,%a1@+ /* Mac_black */
+ dbra %d6,console_clear_loop
+
+ /* Calculate font size */
+
+#if defined(FONT_8x8)
+ lea %pc@(SYMBOL_NAME(font_vga_8x8)), %a0
+#elif defined(FONT_8x16)
+ lea %pc@(SYMBOL_NAME(font_vga_8x16)),%a0
+#elif defined(FONT_6x11)
+ lea %pc@(SYMBOL_NAME(font_vga_6x11)),%a0
+#else /* (FONT_8x8) default */
+ lea %pc@(SYMBOL_NAME(font_vga_8x8)), %a0
+#endif
+
+ /*
+ * At this point we make a shift in register usage
+ * a1 = address of Lconsole_font pointer
+ */
+ lea %pc@(L(console_font)),%a1
+ movel %a0,%a1@ /* store pointer to struct fbcon_font_desc in Lconsole_font */
+
+ /*
+ * Calculate global maxs
+ * Note - we can use either an
+ * 8 x 16 or 8 x 8 character font
+ * 6 x 11 also supported
+ */
+ /* ASSERT: a0 = contents of Lconsole_font */
+ movel %d3,%d0 /* screen width in pixels */
+ divul %a0@(FBCON_FONT_DESC_WIDTH),%d0 /* d0 = max num chars per row */
+
+ movel %d4,%d1 /* screen height in pixels */
+ divul %a0@(FBCON_FONT_DESC_HEIGHT),%d1 /* d1 = max num rows */
+
+ movel %d0,%a2@(Lconsole_struct_num_columns)
+ movel %d1,%a2@(Lconsole_struct_num_rows)
+
+ /*
+ * Clear the current row and column
+ */
+ clrl %a2@(Lconsole_struct_cur_column)
+ clrl %a2@(Lconsole_struct_cur_row)
+ clrl %a2@(Lconsole_struct_left_edge)
+
+ /*
+ * Initialization is complete
+ */
+ moveml %sp@+,%a0-%a4/%d0-%d7
+ rts
+
+L(console_put_stats):


+ /*
+ * Some of the register usage that follows

+ * a0 = pointer to boot_info
+ * d7 = value of boot_info fields
+ */
+ moveml %a0/%d7,%sp@-
+
+ puts "\nMacLinux\n\n"
+
+#ifdef SERIAL_DEBUG
+ puts " vidaddr:"
+ putn %pc@(L(mac_videobase)) /* video addr. */
+
+ puts "\n _stext:"
+ lea %pc@(SYMBOL_NAME(_stext)),%a0
+ putn %a0
+
+ puts "\nbootinfo:"
+ lea %pc@(SYMBOL_NAME(_end)),%a0
+ putn %a0
+
+ puts "\ncpuid:"
+ putn %pc@(L(cputype))
+ putc '\n'
+
+# if defined(MMU_PRINT)
+ jbsr mmu_print_machine_cpu_types
+# endif /* MMU_PRINT */
+#endif /* SERIAL_DEBUG */
+


+ moveml %sp@+,%a0/%d7
+ rts
+

+#ifdef CONSOLE_PENGUIN
+L(console_put_penguin):
+ /*
+ * Get 'that_penguin' onto the screen in the upper right corner
+ * penguin is 64 x 74 pixels, align against right edge of screen
+ */
+ moveml %a0-%a1/%d0-%d7,%sp@-
+
+ lea %pc@(L(mac_dimensions)),%a0
+ movel %a0@,%d0
+ andil #0xffff,%d0
+ subil #64,%d0 /* snug up against the right edge */
+ clrl %d1 /* start at the top */
+ movel #73,%d7
+ lea %pc@(SYMBOL_NAME(that_penguin)),%a1
+console_penguin_row:
+ movel #31,%d6
+console_penguin_pixel_pair:
+ moveb %a1@,%d2
+ lsrb #4,%d2
+ jbsr console_plot_pixel
+ addq #1,%d0
+ moveb %a1@+,%d2
+ jbsr console_plot_pixel
+ addq #1,%d0
+ dbra %d6,console_penguin_pixel_pair
+
+ subil #64,%d0
+ addq #1,%d1
+ dbra %d7,console_penguin_row
+
+ moveml %sp@+,%a0-%a1/%d0-%d7
+ rts
+#endif
+
+console_scroll:
+ moveml %a0-%a4/%d0-%d7,%sp@-
+
+ /*
+ * Calculate source and destination addresses
+ * output a1 = dest
+ * a2 = source


+ */
+ lea %pc@(L(mac_videobase)),%a0
+ movel %a0@,%a1

+ movel %a1,%a2
+ lea %pc@(L(mac_rowbytes)),%a0
+ movel %a0@,%d5
+ movel %pc@(L(console_font)),%a0
+ mulul %a0@(FBCON_FONT_DESC_HEIGHT),%d5 /* account for # scan lines per character */
+ addal %d5,%a2
+
+ /*
+ * Get dimensions
+ */
+ lea %pc@(L(mac_dimensions)),%a0
+ movel %a0@,%d3
+ movel %d3,%d4
+ swap %d4
+ andl #0xffff,%d3 /* d3 = screen width in pixels */
+ andl #0xffff,%d4 /* d4 = screen height in pixels */
+
+ /*
+ * Calculate number of bytes to move
+ */
+ lea %pc@(L(mac_rowbytes)),%a0
+ movel %a0@,%d6
+ movel %pc@(L(console_font)),%a0
+ subl %a0@(FBCON_FONT_DESC_HEIGHT),%d4 /* we're not scrolling the top row! */
+ mulul %d4,%d6 /* scan line bytes x num scan lines */
+ divul #32,%d6 /* we'll move 8 longs at a time */
+ subq #1,%d6
+
+console_scroll_loop:
+ movel %a2@+,%a1@+
+ movel %a2@+,%a1@+
+ movel %a2@+,%a1@+
+ movel %a2@+,%a1@+
+ movel %a2@+,%a1@+
+ movel %a2@+,%a1@+
+ movel %a2@+,%a1@+
+ movel %a2@+,%a1@+
+ dbra %d6,console_scroll_loop
+
+ lea %pc@(L(mac_rowbytes)),%a0
+ movel %a0@,%d6
+ movel %pc@(L(console_font)),%a0
+ mulul %a0@(FBCON_FONT_DESC_HEIGHT),%d6 /* scan line bytes x font height */
+ divul #32,%d6 /* we'll move 8 words at a time */
+ subq #1,%d6
+
+ moveq #-1,%d0
+console_scroll_clear_loop:
+ movel %d0,%a1@+
+ movel %d0,%a1@+
+ movel %d0,%a1@+
+ movel %d0,%a1@+
+ movel %d0,%a1@+
+ movel %d0,%a1@+
+ movel %d0,%a1@+
+ movel %d0,%a1@+
+ dbra %d6,console_scroll_clear_loop
+
+ moveml %sp@+,%a0-%a4/%d0-%d7
+ rts
+
+
+func_start console_putc,%a0/%a1/%d0-%d7
+
+ is_not_mac(console_exit)
+
+ /* Output character in d7 on console.
+ */
+ movel ARG1,%d7
+ cmpib #'\n',%d7


+ jbne 1f
+
+ /* A little safe recursion is good for the soul */

+ console_putc #'\r'
+1:
+ lea %pc@(L(console_globals)),%a0
+
+ cmpib #10,%d7
+ jne console_not_lf
+ movel %a0@(Lconsole_struct_cur_row),%d0
+ addil #1,%d0
+ movel %d0,%a0@(Lconsole_struct_cur_row)
+ movel %a0@(Lconsole_struct_num_rows),%d1
+ cmpl %d1,%d0
+ jcs 1f
+ subil #1,%d0
+ movel %d0,%a0@(Lconsole_struct_cur_row)
+ jbsr console_scroll
+1:
+ jra console_exit
+
+console_not_lf:
+ cmpib #13,%d7
+ jne console_not_cr
+ clrl %a0@(Lconsole_struct_cur_column)
+ jra console_exit
+
+console_not_cr:
+ cmpib #1,%d7
+ jne console_not_home
+ clrl %a0@(Lconsole_struct_cur_row)
+ clrl %a0@(Lconsole_struct_cur_column)
+ jra console_exit
+
+/*
+ * At this point we know that the %d7 character is going to be
+ * rendered on the screen. Register usage is -
+ * a0 = pointer to console globals
+ * a1 = font data
+ * d0 = cursor column
+ * d1 = cursor row to draw the character
+ * d7 = character number
+ */
+console_not_home:
+ movel %a0@(Lconsole_struct_cur_column),%d0
+ addil #1,%a0@(Lconsole_struct_cur_column)
+ movel %a0@(Lconsole_struct_num_columns),%d1
+ cmpl %d1,%d0
+ jcs 1f
+ putc '\n' /* recursion is OK! */
+1:
+ movel %a0@(Lconsole_struct_cur_row),%d1
+
+ /*
+ * At this point we make a shift in register usage
+ * a0 = address of pointer to font data (fbcon_font_desc)
+ */
+ movel %pc@(L(console_font)),%a0
+ movel %a0@(FBCON_FONT_DESC_DATA),%a1 /* Load fbcon_font_desc.data into a1 */
+ andl #0x000000ff,%d7
+ /* ASSERT: a0 = contents of Lconsole_font */
+ mulul %a0@(FBCON_FONT_DESC_HEIGHT),%d7 /* d7 = index into font data */
+ addl %d7,%a1 /* a1 = points to char image */
+
+ /*
+ * At this point we make a shift in register usage
+ * d0 = pixel coordinate, x
+ * d1 = pixel coordinate, y
+ * d2 = (bit 0) 1/0 for white/black (!) pixel on screen
+ * d3 = font scan line data (8 pixels)
+ * d6 = count down for the font's pixel width (8)
+ * d7 = count down for the font's pixel count in height
+ */
+ /* ASSERT: a0 = contents of Lconsole_font */
+ mulul %a0@(FBCON_FONT_DESC_WIDTH),%d0
+ mulul %a0@(FBCON_FONT_DESC_HEIGHT),%d1
+ movel %a0@(FBCON_FONT_DESC_HEIGHT),%d7 /* Load fbcon_font_desc.height into d7 */
+ subq #1,%d7
+console_read_char_scanline:
+ moveb %a1@+,%d3
+
+ /* ASSERT: a0 = contents of Lconsole_font */
+ movel %a0@(FBCON_FONT_DESC_WIDTH),%d6 /* Load fbcon_font_desc.width into d6 */
+ subql #1,%d6
+
+console_do_font_scanline:
+ lslb #1,%d3
+ scsb %d2 /* convert 1 bit into a byte */
+ jbsr console_plot_pixel
+ addq #1,%d0
+ dbra %d6,console_do_font_scanline
+
+ /* ASSERT: a0 = contents of Lconsole_font */
+ subl %a0@(FBCON_FONT_DESC_WIDTH),%d0
+ addq #1,%d1
+ dbra %d7,console_read_char_scanline
+
+console_exit:
+
+func_return console_putc
+
+console_plot_pixel:
+ /*
+ * Input:
+ * d0 = x coordinate
+ * d1 = y coordinate
+ * d2 = (bit 0) 1/0 for white/black (!)
+ * All registers are preserved
+ */
+ moveml %a0-%a1/%d0-%d4,%sp@-
+


+ lea %pc@(L(mac_videobase)),%a0
+ movel %a0@,%a1

+ lea %pc@(L(mac_videodepth)),%a0
+ movel %a0@,%d3
+ lea %pc@(L(mac_rowbytes)),%a0
+ mulul %a0@,%d1
+
+ /*
+ * Register usage:
+ * d0 = x coord becomes byte offset into frame buffer
+ * d1 = y coord
+ * d2 = black or white (0/1)
+ * d3 = video depth
+ * d4 = temp of x (d0) for many bit depths
+ * d5 = unused
+ * d6 = unused
+ * d7 = unused
+ */
+test_1bit:
+ cmpb #1,%d3
+ jbne test_2bit
+ movel %d0,%d4 /* we need the low order 3 bits! */
+ divul #8,%d0
+ addal %d0,%a1
+ addal %d1,%a1
+ andb #7,%d4
+ eorb #7,%d4 /* reverse the x-coordinate w/ screen-bit # */
+ andb #1,%d2
+ jbne white_1
+ bsetb %d4,%a1@
+ jbra console_plot_pixel_exit
+white_1:
+ bclrb %d4,%a1@
+ jbra console_plot_pixel_exit
+
+test_2bit:
+ cmpb #2,%d3
+ jbne test_4bit
+ movel %d0,%d4 /* we need the low order 2 bits! */
+ divul #4,%d0
+ addal %d0,%a1
+ addal %d1,%a1
+ andb #3,%d4
+ eorb #3,%d4 /* reverse the x-coordinate w/ screen-bit # */
+ lsll #1,%d4 /* ! */
+ andb #1,%d2
+ jbne white_2
+ bsetb %d4,%a1@
+ addq #1,%d4
+ bsetb %d4,%a1@
+ jbra console_plot_pixel_exit
+white_2:
+ bclrb %d4,%a1@
+ addq #1,%d4
+ bclrb %d4,%a1@
+ jbra console_plot_pixel_exit
+
+test_4bit:
+ cmpb #4,%d3
+ jbne test_8bit
+ movel %d0,%d4 /* we need the low order bit! */
+ divul #2,%d0
+ addal %d0,%a1
+ addal %d1,%a1
+ andb #1,%d4
+ eorb #1,%d4
+ lsll #2,%d4 /* ! */
+ andb #1,%d2
+ jbne white_4
+ bsetb %d4,%a1@
+ addq #1,%d4
+ bsetb %d4,%a1@
+ addq #1,%d4
+ bsetb %d4,%a1@
+ addq #1,%d4
+ bsetb %d4,%a1@
+ jbra console_plot_pixel_exit
+white_4:
+ bclrb %d4,%a1@
+ addq #1,%d4
+ bclrb %d4,%a1@
+ addq #1,%d4
+ bclrb %d4,%a1@
+ addq #1,%d4
+ bclrb %d4,%a1@
+ jbra console_plot_pixel_exit
+
+test_8bit:
+ cmpb #8,%d3
+ jbne test_16bit
+ addal %d0,%a1
+ addal %d1,%a1
+ andb #1,%d2
+ jbne white_8
+ moveb #0xff,%a1@
+ jbra console_plot_pixel_exit
+white_8:
+ clrb %a1@
+ jbra console_plot_pixel_exit
+
+test_16bit:
+ cmpb #16,%d3
+ jbne console_plot_pixel_exit
+ addal %d0,%a1
+ addal %d0,%a1
+ addal %d1,%a1
+ andb #1,%d2
+ jbne white_16
+ clrw %a1@
+ jbra console_plot_pixel_exit
+white_16:
+ movew #0x0fff,%a1@
+ jbra console_plot_pixel_exit
+
+console_plot_pixel_exit:
+ moveml %sp@+,%a0-%a1/%d0-%d4
X rts
+#endif /* CONSOLE */
X
X #if 0
-Lshowtest:
+/*
+ * This is some old code lying around. I don't believe
+ * it's used or important anymore. My guess is it contributed
+ * to getting to this point, but it's done for now.
+ * It was still in the 2.1.77 head.S, so it's still here.
+ * (And still not used!)
+ */
+L(showtest):
X moveml %a0/%d7,%sp@-
- putc('A')
- putc('=')
- putn(%a1)
-
- ptestr #5,%a1@,#7,%a0


-
- putc('D')

- putc('A')
- putc('=')
- putn(%a0)


-
- putc('D')

- putc('=')
- putn(%a0@)
-
- putc('S')
- putc('=')
- lea %pc@(Lmmu),%a0
- pmove %psr,%a0@
+ puts "A="
+ putn %a1
+
+ .long 0xf0119f15 | ptestr #5,%a1@,#7,%a0
+
+ puts "DA="
+ putn %a0
+
+ puts "D="
+ putn %a0@
+
+ puts "S="
+ lea %pc@(L(mmu)),%a0
+ .long 0xf0106200 | pmove %psr,%a0@
X clrl %d7
X movew %a0@,%d7
- jbsr Lserial_putnum
+ putn %d7
X
- putr()
+ putc '\n'
X moveml %sp@+,%a0/%d7
X rts
+#endif /* 0 */
+
+__INITDATA
+ .align 4
+
+#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || defined(CONFIG_HP300)
+L(custom):
+L(iobase):
+ .long 0
+#endif
+
+#ifdef CONFIG_MAC
+L(console_video_virtual):
+ .long 0


+#endif /* CONFIG_MAC */
+

+#if defined(CONSOLE)
+L(console_globals):
+ .long 0 /* cursor column */
+ .long 0 /* cursor row */
+ .long 0 /* max num columns */
+ .long 0 /* max num rows */
+ .long 0 /* left edge */
+ .long 0 /* mac putc */
+L(console_font):
+ .long 0 /* pointer to console font (struct fbcon_font_desc) */


+#endif /* CONSOLE */
+

+#if defined(MMU_PRINT)
+L(mmu_print_data):
+ .long 0 /* valid flag */
+ .long 0 /* start logical */
+ .long 0 /* next logical */
+ .long 0 /* start physical */
+ .long 0 /* next physical */


+#endif /* MMU_PRINT */
+

+L(cputype):
+ .long 0
+L(mmu_cached_pointer_tables):
+ .long 0
+L(mmu_num_pointer_tables):
+ .long 0
+L(phys_kernel_start):
+ .long 0
+L(kernel_end):
+ .long 0
+L(memory_start):
+ .long 0
+L(kernel_pgdir_ptr):
+ .long 0
+L(temp_mmap_mem):
+ .long 0
+
+
+#if defined (CONFIG_BVME6000)
+BVME_SCC_CTRL_A = 0xffb0000b
+BVME_SCC_DATA_A = 0xffb0000f
+#endif
+
+#if defined(CONFIG_MAC)
+L(mac_booter_data):
+ .long 0
+L(mac_videobase):
+ .long 0
+L(mac_videodepth):
+ .long 0
+L(mac_dimensions):
+ .long 0
+L(mac_rowbytes):
+ .long 0
+#ifdef MAC_SERIAL_DEBUG
+L(mac_sccbase):
+ .long 0
+#endif /* MAC_SERIAL_DEBUG */
X #endif
+
+__FINIT
X .data
- .even
-Lcustom:
-Liobase:
- .long 0
-Lmmu: .quad 0
-SYMBOL_NAME_LABEL(kpt)
- .long 0
+ .align 4
+
X SYMBOL_NAME_LABEL(availmem)
- .long 0
+ .long 0
X SYMBOL_NAME_LABEL(m68k_pgtable_cachemode)
- .long 0
-#ifdef CONFIG_060_WRITETHROUGH
+ .long 0
X SYMBOL_NAME_LABEL(m68k_supervisor_cachemode)
- .long 0
-#endif
+ .long 0
X #if defined(CONFIG_MVME16x)
X SYMBOL_NAME_LABEL(mvme_bdid_ptr)
- .long 0
+ .long 0
X #endif
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/kernel/m68k_defs.c linux/arch/m68k/kernel/m68k_defs.c
--- v2.2.0-pre8/linux/arch/m68k/kernel/m68k_defs.c Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/kernel/m68k_defs.c Tue Jan 19 10:58:26 1999
@@ -10,14 +10,78 @@
X
X #include <linux/stddef.h>
X #include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/amigahw.h>
+#include <video/font.h>
X
X #define DEFINE(sym, val) \
X asm volatile("\n#define " #sym " %c0" : : "i" (val))
X
X int main(void)
X {
- DEFINE(TS_TSS, offsetof(struct task_struct, tss));
- DEFINE(TS_ESP0, offsetof(struct task_struct, tss.esp0));
- DEFINE(TS_FPU, offsetof(struct task_struct, tss.fp));
+ /* offsets into the task struct */
+ DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+ DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+ DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, sigpending));
+ DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, need_resched));
+ DEFINE(TASK_TSS, offsetof(struct task_struct, tss));
+ DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+
+ /* offsets into the thread struct */
+ DEFINE(TSS_KSP, offsetof(struct thread_struct, ksp));
+ DEFINE(TSS_USP, offsetof(struct thread_struct, usp));
+ DEFINE(TSS_SR, offsetof(struct thread_struct, sr));
+ DEFINE(TSS_FS, offsetof(struct thread_struct, fs));
+ DEFINE(TSS_CRP, offsetof(struct thread_struct, crp));
+ DEFINE(TSS_ESP0, offsetof(struct thread_struct, esp0));
+ DEFINE(TSS_FPREG, offsetof(struct thread_struct, fp));
+ DEFINE(TSS_FPCNTL, offsetof(struct thread_struct, fpcntl));
+ DEFINE(TSS_FPSTATE, offsetof(struct thread_struct, fpstate));
+
+ /* offsets into the pt_regs */
+ DEFINE(PT_D0, offsetof(struct pt_regs, d0));
+ DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
+ DEFINE(PT_SR, offsetof(struct pt_regs, sr));
+
+ /* bitfields are a bit difficult */
+ DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4);
+
+ /* offsets into the irq_handler struct */
+ DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler));
+ DEFINE(IRQ_DEVID, offsetof(struct irq_node, dev_id));
+ DEFINE(IRQ_NEXT, offsetof(struct irq_node, next));
+
+ /* offsets into the kernel_stat struct */
+ DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
+
+ /* offsets into the bi_record struct */
+ DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
+ DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
+ DEFINE(BIR_DATA, offsetof(struct bi_record, data));
+
+ /* offsets into fbcon_font_desc (video/font.h) */
+ DEFINE(FBCON_FONT_DESC_IDX, offsetof(struct fbcon_font_desc, idx));
+ DEFINE(FBCON_FONT_DESC_NAME, offsetof(struct fbcon_font_desc, name));
+ DEFINE(FBCON_FONT_DESC_WIDTH, offsetof(struct fbcon_font_desc, width));
+ DEFINE(FBCON_FONT_DESC_HEIGHT, offsetof(struct fbcon_font_desc, height));
+ DEFINE(FBCON_FONT_DESC_DATA, offsetof(struct fbcon_font_desc, data));
+ DEFINE(FBCON_FONT_DESC_PREF, offsetof(struct fbcon_font_desc, pref));
+
+ /* offsets into the custom struct */
+ DEFINE(CUSTOMBASE, &custom);
+ DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
+ DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
+ DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
+ DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));
+ DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));
+ DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));
+ DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));
+ DEFINE(CIAABASE, &ciaa);
+ DEFINE(CIABBASE, &ciab);
+ DEFINE(C_PRA, offsetof(struct CIA, pra));
+ DEFINE(ZTWOBASE, zTwoBase);
+
X return 0;
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/kernel/m68k_ksyms.c linux/arch/m68k/kernel/m68k_ksyms.c
--- v2.2.0-pre8/linux/arch/m68k/kernel/m68k_ksyms.c Thu Jan 7 15:11:36 1999
+++ linux/arch/m68k/kernel/m68k_ksyms.c Tue Jan 19 10:58:34 1999
@@ -13,6 +13,7 @@
X #include <asm/machdep.h>
X #include <asm/pgtable.h>
X #include <asm/irq.h>
+#include <asm/io.h>
X #include <asm/semaphore.h>
X #include <asm/checksum.h>
X #include <asm/hardirq.h>
@@ -37,21 +38,22 @@
X EXPORT_SYMBOL(mm_end_of_chunk);
X #endif
X EXPORT_SYMBOL(mm_vtop_fallback);
+EXPORT_SYMBOL(m68k_realnum_memory);
X EXPORT_SYMBOL(m68k_memory);
-EXPORT_SYMBOL(kernel_map);
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
X EXPORT_SYMBOL(m68k_debug_device);
X EXPORT_SYMBOL(dump_fpu);
X EXPORT_SYMBOL(dump_thread);
X EXPORT_SYMBOL(strnlen);
X EXPORT_SYMBOL(strrchr);
X EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(strtok);
-EXPORT_SYMBOL(strpbrk);
X EXPORT_SYMBOL(local_irq_count);
X EXPORT_SYMBOL(local_bh_count);
X EXPORT_SYMBOL(enable_irq);
X EXPORT_SYMBOL(disable_irq);
X EXPORT_SYMBOL(kernel_set_cachemode);
+EXPORT_SYMBOL(kernel_thread);
X
X /* Networking helper routines. */
X EXPORT_SYMBOL(csum_partial_copy);
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
--- v2.2.0-pre8/linux/arch/m68k/kernel/process.c Thu Jan 7 15:11:36 1999
+++ linux/arch/m68k/kernel/process.c Tue Jan 19 10:58:34 1999
@@ -56,16 +56,13 @@
X */
X asmlinkage int sys_idle(void)
X {
- int ret = -EPERM;
-
- lock_kernel();
X if (current->pid != 0)
- goto out;
+ return -EPERM;
X
X /* endless idle loop with no priority at all */
- current->priority = -100;
+ current->priority = 0;
X current->counter = -100;
- for (;;){
+ for (;;) {
X if (!current->need_resched)
X #if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC)
X /* block out HSYNC on the atari (falcon) */
@@ -73,14 +70,9 @@
X #else /* portable version */
X __asm__("stop #0x2000" : : : "cc");
X #endif /* machine compilation types */
- check_pgt_cache();
- run_task_queue(&tq_scheduler);
X schedule();
+ check_pgt_cache();
X }
- ret = 0;
-out:
- unlock_kernel();
- return ret;
X }
X
X void machine_restart(char * __unused)
@@ -115,6 +107,44 @@
X printk("USP: %08lx\n", rdusp());
X }
X
+/*
+ * Create a kernel thread
+ */
+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+ int pid;
+ mm_segment_t fs;
+
+ fs = get_fs();
+ set_fs (KERNEL_DS);
+
+ {
+ register long retval __asm__ ("d0");
+ register long clone_arg __asm__ ("d1") = flags | CLONE_VM;
+
+ __asm__ __volatile__
+ ("clrl %%d2\n\t"
+ "trap #0\n\t" /* Linux/m68k system call */
+ "tstl %0\n\t" /* child or parent */
+ "jne 1f\n\t" /* parent - jump */
+ "lea %%sp@(-8192),%6\n\t" /* reload current */
+ "movel %3,%%sp@-\n\t" /* push argument */
+ "jsr %4@\n\t" /* call fn */
+ "movel %0,%%d1\n\t" /* pass exit value */
+ "movel %2,%0\n\t" /* exit */
+ "trap #0\n"
+ "1:"
+ : "=d" (retval)
+ : "0" (__NR_clone), "i" (__NR_exit),
+ "r" (arg), "a" (fn), "d" (clone_arg), "r" (current)
+ : "d0", "d2");
+ pid = retval;
+ }
+
+ set_fs (fs);
+ return pid;
+}
+
X void flush_thread(void)
X {
X unsigned long zero = 0;
@@ -137,6 +167,19 @@
X return do_fork(SIGCHLD, rdusp(), regs);
X }
X
+asmlinkage int m68k_vfork(struct pt_regs *regs)
+{
+ int child;
+ struct semaphore sem = MUTEX_LOCKED;
+
+ child = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs);
+
+ if (child > 0)
+ down(&sem);
+
+ return child;
+}
+
X asmlinkage int m68k_clone(struct pt_regs *regs)
X {
X unsigned long clone_flags;
@@ -147,7 +190,7 @@
X newsp = regs->d2;
X if (!newsp)
X newsp = rdusp();
- return do_fork(clone_flags, newsp, regs);
+ return do_fork(clone_flags & ~CLONE_VFORK, newsp, regs);
X }
X
X int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
--- v2.2.0-pre8/linux/arch/m68k/kernel/ptrace.c Thu Jan 7 15:11:36 1999
+++ linux/arch/m68k/kernel/ptrace.c Tue Jan 19 10:58:34 1999
@@ -325,12 +325,15 @@
X ret = 0;
X goto out;
X }
- if (pid == 1) /* you may not mess with init */
- goto out;
X ret = -ESRCH;
- if (!(child = find_task_by_pid(pid)))
+ read_lock(&tasklist_lock);
+ child = find_task_by_pid(pid);
+ read_unlock(&tasklist_lock); /* FIXME!!! */
+ if (!child)
X goto out;
X ret = -EPERM;
+ if (pid == 1) /* you may not mess with init */
+ goto out;
X if (request == PTRACE_ATTACH) {
X if (child == current)
X goto out;
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/kernel/setup.c linux/arch/m68k/kernel/setup.c
--- v2.2.0-pre8/linux/arch/m68k/kernel/setup.c Sat Sep 5 16:46:40 1998
+++ linux/arch/m68k/kernel/setup.c Tue Jan 19 10:58:34 1999
@@ -48,6 +48,7 @@
X extern unsigned long availmem;
X
X int m68k_num_memory = 0;
+int m68k_realnum_memory = 0;
X struct mem_info m68k_memory[NUM_MEMINFO];
X
X static struct mem_info m68k_ramdisk = { 0, 0 };
@@ -62,8 +63,6 @@
X int (*mach_keyb_init) (void) __initdata;
X int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
X void (*mach_kbd_leds) (unsigned int) = NULL;
-/* machine dependent "kbd-reset" setup function */
-void (*kbd_reset_setup) (char *, int) __initdata = NULL;
X /* machine dependent irq functions */
X void (*mach_init_IRQ) (void) __initdata;
X void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
@@ -159,6 +158,7 @@
X record = (struct bi_record *)((u_long)record+record->size);
X }
X
+ m68k_realnum_memory = m68k_num_memory;
X #ifdef CONFIG_SINGLE_MEMORY_CHUNK
X if (m68k_num_memory > 1) {
X printk("Ignoring last %i chunks of physical memory\n",
@@ -398,9 +398,9 @@
X }
X #endif
X
-__initfunc(unsigned long arch_kbd_init(void))
+/* for "kbd-reset" cmdline param */
+void __init kbd_reset_setup(char *str, int *ints)
X {
- return mach_keyb_init();
X }
X
X void arch_gettod(int *year, int *mon, int *day, int *hour,
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/kernel/sys_m68k.c linux/arch/m68k/kernel/sys_m68k.c
--- v2.2.0-pre8/linux/arch/m68k/kernel/sys_m68k.c Tue Aug 18 22:02:03 1998
+++ linux/arch/m68k/kernel/sys_m68k.c Tue Jan 19 10:58:34 1999
@@ -112,7 +112,8 @@
X *
X * This is really horribly ugly.
X */
-asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
+asmlinkage int sys_ipc (uint call, int first, int second,
+ int third, void *ptr, long fifth)
X {
X int version, ret;
X
@@ -122,88 +123,76 @@
X if (call <= SEMCTL)
X switch (call) {
X case SEMOP:
- ret = sys_semop (first, (struct sembuf *)ptr, second);
- goto out;
+ return sys_semop (first, (struct sembuf *)ptr, second);
X case SEMGET:
- ret = sys_semget (first, second, third);
- goto out;
+ return sys_semget (first, second, third);
X case SEMCTL: {
X union semun fourth;
- ret = -EINVAL;
X if (!ptr)
- goto out;
- if ((ret = get_user(fourth.__pad, (void **) ptr)))
- goto out;
- ret = sys_semctl (first, second, third, fourth);
- goto out;
+ return -EINVAL;
+ if (get_user(fourth.__pad, (void **) ptr))
+ return -EFAULT;
+ return sys_semctl (first, second, third, fourth);
X }
X default:
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
X }
X if (call <= MSGCTL)
X switch (call) {
X case MSGSND:
- ret = sys_msgsnd (first, (struct msgbuf *) ptr,
+ return sys_msgsnd (first, (struct msgbuf *) ptr,
X second, third);
- goto out;
X case MSGRCV:
X switch (version) {
X case 0: {
X struct ipc_kludge tmp;
- ret = -EINVAL;
X if (!ptr)
- goto out;
- ret = -EFAULT;
- if (copy_from_user (&tmp, ptr, sizeof (tmp)))
- goto out;
- ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
- goto out;
+ return -EINVAL;
+ if (copy_from_user (&tmp,
+ (struct ipc_kludge *)ptr,
+ sizeof (tmp)))
+ return -EFAULT;
+ return sys_msgrcv (first, tmp.msgp, second,
+ tmp.msgtyp, third);
X }
- case 1: default:
- ret = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
- goto out;
+ default:
+ return sys_msgrcv (first,
+ (struct msgbuf *) ptr,
+ second, fifth, third);
X }
X case MSGGET:
- ret = sys_msgget ((key_t) first, second);
- goto out;
+ return sys_msgget ((key_t) first, second);
X case MSGCTL:
- ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
- goto out;
+ return sys_msgctl (first, second,
+ (struct msqid_ds *) ptr);
X default:
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
X }
X if (call <= SHMCTL)
X switch (call) {
X case SHMAT:
X switch (version) {
- case 0: default: {
+ default: {
X ulong raddr;
- ret = sys_shmat (first, (char *) ptr, second, &raddr);
+ ret = sys_shmat (first, (char *) ptr,
+ second, &raddr);
X if (ret)
- goto out;
- ret = put_user (raddr, (ulong *) third);
- goto out;
+ return ret;
+ return put_user (raddr, (ulong *) third);
X }
X }
X case SHMDT:
- ret = sys_shmdt ((char *)ptr);
- goto out;
+ return sys_shmdt ((char *)ptr);
X case SHMGET:
- ret = sys_shmget (first, second, third);
- goto out;
+ return sys_shmget (first, second, third);
X case SHMCTL:
- ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
- goto out;
+ return sys_shmctl (first, second,
+ (struct shmid_ds *) ptr);
X default:
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
X }
- ret = -EINVAL;
-out:
- unlock_kernel();
- return ret;
+
+ return -EINVAL;
X }
X
X asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/kernel/time.c linux/arch/m68k/kernel/time.c
--- v2.2.0-pre8/linux/arch/m68k/kernel/time.c Sun Jun 7 11:16:27 1998
+++ linux/arch/m68k/kernel/time.c Tue Jan 19 10:58:34 1999
@@ -5,6 +5,9 @@
X *
X * This file contains the m68k-specific time handling details.
X * Most of the stuff is located in the machine specific files.
+ *


+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills

X */
X
X #include <linux/config.h> /* CONFIG_HEARTBEAT */
@@ -65,9 +68,10 @@


X * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
X * called as close as possible to 500 ms before the new second starts.
X */
- if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
- xtime.tv_usec > 500000 - (tick >> 1) &&
- xtime.tv_usec < 500000 + (tick >> 1)) {
+ if ((time_status & STA_UNSYNC) == 0 &&
+ xtime.tv_sec > last_rtc_update + 660 &&
+ xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+ xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
X if (set_rtc_mmss(xtime.tv_sec) == 0)
X last_rtc_update = xtime.tv_sec;
X else

@@ -146,27 +150,38 @@
X mach_sched_init(timer_interrupt);
X }
X
+extern rwlock_t xtime_lock;
+
X /*
X * This version of gettimeofday has near microsecond resolution.
X */
X void do_gettimeofday(struct timeval *tv)
X {
+ extern volatile unsigned long lost_ticks;
X unsigned long flags;
+ unsigned long usec, sec, lost;
X
- save_flags(flags);
- cli();
- *tv = xtime;
- tv->tv_usec += mach_gettimeoffset();
- if (tv->tv_usec >= 1000000) {
- tv->tv_usec -= 1000000;
- tv->tv_sec++;
+ read_lock_irqsave(&xtime_lock, flags);
+ usec = mach_gettimeoffset();
+ lost = lost_ticks;
+ if (lost)
+ usec += lost * (1000000/HZ);
+ sec = xtime.tv_sec;
+ usec += xtime.tv_usec;
+ read_unlock_irqrestore(&xtime_lock, flags);
+
+ while (usec >= 1000000) {
+ usec -= 1000000;
+ sec++;
X }
- restore_flags(flags);
+
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
X }
X
X void do_settimeofday(struct timeval *tv)
X {
- cli();
+ write_lock_irq(&xtime_lock);
X /* This is revolting. We need to set the xtime.tv_usec
X * correctly. However, the value in this location is
X * is value at the last tick.
@@ -175,14 +190,16 @@
X */
X tv->tv_usec -= mach_gettimeoffset();
X
- if (tv->tv_usec < 0) {
+ while (tv->tv_usec < 0) {
X tv->tv_usec += 1000000;
X tv->tv_sec--;


X }
X
X xtime = *tv;
- time_state = TIME_BAD;
- time_maxerror = MAXPHASE;
- time_esterror = MAXPHASE;
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR; /* p. 24, (a) */
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
X sti();

X }
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/mac/config.c linux/arch/m68k/mac/config.c
--- v2.2.0-pre8/linux/arch/m68k/mac/config.c Thu Jan 7 15:11:36 1999
+++ linux/arch/m68k/mac/config.c Tue Jan 19 10:58:34 1999
@@ -55,9 +55,6 @@
X
X void *mac_env; /* Loaded by the boot asm */
X
-/* The logical video addr. determined by head.S - testing */
-extern unsigned long mac_videobase;
-
X /* The phys. video addr. - might be bogus on some machines */
X unsigned long mac_orig_videoaddr;
X
@@ -65,7 +62,6 @@
X extern int mac_keyb_init(void);
X extern int mac_kbdrate(struct kbd_repeat *k);
X extern void mac_kbd_leds(unsigned int leds);
-extern void mac_kbd_reset_setup(char*, int);
X
X /* Mac specific irq functions */
X extern void mac_init_IRQ (void);
@@ -241,9 +237,7 @@
X mac_bi_data.id = *data;
X break;
X case BI_MAC_VADDR:
- /* save booter supplied videobase; use the one mapped in head.S! */
- mac_orig_videoaddr = *data;
- mac_bi_data.videoaddr = mac_videobase;
+ mac_bi_data.videoaddr = VIDEOMEMBASE + (*data & ~VIDEOMEMMASK);
X break;
X case BI_MAC_VDEPTH:
X mac_bi_data.videodepth = *data;
@@ -307,7 +301,6 @@
X mach_keyb_init = mac_keyb_init;
X mach_kbdrate = mac_kbdrate;
X mach_kbd_leds = mac_kbd_leds;
- kbd_reset_setup = mac_kbd_reset_setup;
X mach_init_IRQ = mac_init_IRQ;
X mach_request_irq = mac_request_irq;
X mach_free_irq = mac_free_irq;
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/mac/debug.c linux/arch/m68k/mac/debug.c
--- v2.2.0-pre8/linux/arch/m68k/mac/debug.c Thu Jan 7 15:11:36 1999
+++ linux/arch/m68k/mac/debug.c Tue Jan 19 10:58:34 1999
@@ -39,7 +39,7 @@
X extern void mac_serial_print(char *);
X
X #define DEBUG_HEADS
-#define DEBUG_SCREEN
+#undef DEBUG_SCREEN
X #define DEBUG_SERIAL
X
X /*
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/mac/mackeyb.c linux/arch/m68k/mac/mackeyb.c
--- v2.2.0-pre8/linux/arch/m68k/mac/mackeyb.c Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/mac/mackeyb.c Tue Jan 19 10:58:34 1999
@@ -760,8 +760,3 @@
X
X return 0;


X }
-
-/* for "kbd-reset" cmdline param */

-__initfunc(void mac_kbd_reset_setup(char *str, int *ints))
-{
-}
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/mm/init.c linux/arch/m68k/mm/init.c
--- v2.2.0-pre8/linux/arch/m68k/mm/init.c Sat Sep 5 16:46:40 1998
+++ linux/arch/m68k/mm/init.c Tue Jan 19 10:58:34 1999
@@ -28,8 +28,9 @@
X #include <asm/atari_stram.h>
X #endif
X
+#undef DEBUG
+
X extern void die_if_kernel(char *,struct pt_regs *,long);
-extern void init_kpointer_table(void);
X extern void show_net_buffers(void);
X
X int do_check_pgt_cache(int low, int high)
@@ -122,17 +123,14 @@
X unsigned long mm_cachebits = 0;
X #endif
X
-pte_t *kernel_page_table (unsigned long *memavailp)
+static pte_t *__init kernel_page_table(unsigned long *memavailp)
X {
X pte_t *ptablep;
X
- if (memavailp) {
- ptablep = (pte_t *)*memavailp;
- *memavailp += PAGE_SIZE;
- }
- else
- ptablep = (pte_t *)__get_free_page(GFP_KERNEL);
+ ptablep = (pte_t *)*memavailp;
+ *memavailp += PAGE_SIZE;
X
+ clear_page((unsigned long)ptablep);
X flush_page_to_ram((unsigned long) ptablep);
X flush_tlb_kernel_page((unsigned long) ptablep);
X nocache_page ((unsigned long)ptablep);
@@ -140,199 +138,164 @@
X return ptablep;
X }
X
-__initfunc(static unsigned long
-map_chunk (unsigned long addr, unsigned long size, unsigned long *memavailp))
-{
-#define ONEMEG (1024*1024)
-#define L3TREESIZE (256*1024)
+static pmd_t *last_pgtable __initdata = NULL;
X
- static unsigned long mem_mapped = 0;
- static unsigned long virtaddr = 0;
- static pte_t *ktablep = NULL;
- unsigned long *kpointerp;
- unsigned long physaddr;
- extern pte_t *kpt;
- int pindex; /* index into pointer table */
- pgd_t *page_dir = pgd_offset_k (virtaddr);
-
- if (!pgd_present (*page_dir)) {
- /* we need a new pointer table */
- kpointerp = (unsigned long *) get_kpointer_table ();
- pgd_set (page_dir, (pmd_t *) kpointerp);
- memset (kpointerp, 0, PTRS_PER_PMD * sizeof (pmd_t));
- }
- else
- kpointerp = (unsigned long *) pgd_page (*page_dir);
+static pmd_t *__init kernel_ptr_table(unsigned long *memavailp)
+{
+ if (!last_pgtable) {
+ unsigned long pmd, last;
+ int i;
X
- /*
- * pindex is the offset into the pointer table for the
- * descriptors for the current virtual address being mapped.
- */
- pindex = (virtaddr >> 18) & 0x7f;
+ last = (unsigned long)kernel_pg_dir;
+ for (i = 0; i < PTRS_PER_PGD; i++) {
+ if (!pgd_val(kernel_pg_dir[i]))
+ continue;
+ pmd = pgd_page(kernel_pg_dir[i]);
+ if (pmd > last)
+ last = pmd;
+ }
X
+ last_pgtable = (pmd_t *)last;
X #ifdef DEBUG
- printk ("mm=%ld, kernel_pg_dir=%p, kpointerp=%p, pindex=%d\n",
- mem_mapped, kernel_pg_dir, kpointerp, pindex);
+ printk("kernel_ptr_init: %p\n", last_pgtable);
X #endif
+ }
X
- /*
- * if this is running on an '040, we already allocated a page
- * table for the first 4M. The address is stored in kpt by
- * arch/head.S
- *
- */
- if (CPU_IS_040_OR_060 && mem_mapped == 0)
- ktablep = kpt;
-
- for (physaddr = addr;
- physaddr < addr + size;
- mem_mapped += L3TREESIZE, virtaddr += L3TREESIZE) {
+ if (((unsigned long)(last_pgtable + PTRS_PER_PMD) & ~PAGE_MASK) == 0) {
+ last_pgtable = (pmd_t *)*memavailp;
+ *memavailp += PAGE_SIZE;
X
-#ifdef DEBUG
- printk ("pa=%#lx va=%#lx ", physaddr, virtaddr);
-#endif
+ clear_page((unsigned long)last_pgtable);
+ flush_page_to_ram((unsigned long)last_pgtable);
+ flush_tlb_kernel_page((unsigned long)last_pgtable);
+ nocache_page((unsigned long)last_pgtable);
+ } else
+ last_pgtable += PTRS_PER_PMD;
X
- if (pindex > 127 && mem_mapped >= 32*ONEMEG) {
- /* we need a new pointer table every 32M */
-#ifdef DEBUG
- printk ("[new pointer]");
-#endif
+ return last_pgtable;
+}
X
- kpointerp = (unsigned long *)get_kpointer_table ();
- pgd_set(pgd_offset_k(virtaddr), (pmd_t *)kpointerp);
- pindex = 0;
- }
+static unsigned long __init
+map_chunk (unsigned long addr, long size, unsigned long *memavailp)
+{
+#define PTRTREESIZE (256*1024)
+#define ROOTTREESIZE (32*1024*1024)
+ static unsigned long virtaddr = 0;
+ unsigned long physaddr;
+ pgd_t *pgd_dir;
+ pmd_t *pmd_dir;
+ pte_t *pte_dir;
X
- if (CPU_IS_040_OR_060) {
- int i;
- unsigned long ktable;
-
- /* Don't map the first 4 MB again. The pagetables
- * for this range have already been initialized
- * in boot/head.S. Otherwise the pages used for
- * tables would be reinitialized to copyback mode.
- */
+ physaddr = (addr | m68k_supervisor_cachemode |
+ _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
+ if (CPU_IS_040_OR_060)
+ physaddr |= _PAGE_GLOBAL040;
X
- if (mem_mapped < 4 * ONEMEG)
- {
+ while (size > 0) {
X #ifdef DEBUG
- printk ("Already initialized\n");
+ if (!(virtaddr & (PTRTREESIZE-1)))
+ printk ("\npa=%#lx va=%#lx ", physaddr & PAGE_MASK,
+ virtaddr);
X #endif
- physaddr += L3TREESIZE;
- pindex++;
+ pgd_dir = pgd_offset_k(virtaddr);
+ if (virtaddr && CPU_IS_020_OR_030) {
+ if (!(virtaddr & (ROOTTREESIZE-1)) &&
+ size >= ROOTTREESIZE) {
+#ifdef DEBUG
+ printk ("[very early term]");
+#endif
+ pgd_val(*pgd_dir) = physaddr;
+ size -= ROOTTREESIZE;
+ virtaddr += ROOTTREESIZE;
+ physaddr += ROOTTREESIZE;
X continue;
X }
+ }
+ if (!pgd_present(*pgd_dir)) {
+ pmd_dir = kernel_ptr_table(memavailp);
X #ifdef DEBUG
- printk ("[setup table]");
+ printk ("[new pointer %p]", pmd_dir);
X #endif
+ pgd_set(pgd_dir, pmd_dir);
+ } else
+ pmd_dir = pmd_offset(pgd_dir, virtaddr);
X
- /*
- * 68040, use page tables pointed to by the
- * kernel pointer table.
- */
-
- if ((pindex & 15) == 0) {
- /* Need new page table every 4M on the '040 */
+ if (CPU_IS_020_OR_030) {
+ if (virtaddr) {
X #ifdef DEBUG
- printk ("[new table]");
+ printk ("[early term]");
X #endif
- ktablep = kernel_page_table (memavailp);
- }
-
- ktable = virt_to_phys(ktablep);
-
- /*
- * initialize section of the page table mapping
- * this 256K portion.
- */
- for (i = 0; i < 64; i++) {
- pte_val(ktablep[i]) = physaddr | _PAGE_PRESENT
- | m68k_supervisor_cachemode | _PAGE_GLOBAL040
- | _PAGE_ACCESSED;
+ pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;
+ physaddr += PTRTREESIZE;
+ } else {
+ int i;
+#ifdef DEBUG
+ printk ("[zero map]");
+#endif
+ pte_dir = (pte_t *)kernel_ptr_table(memavailp);
+ pmd_dir->pmd[0] = virt_to_phys(pte_dir) |
+ _PAGE_TABLE | _PAGE_ACCESSED;
+ pte_val(*pte_dir++) = 0;
X physaddr += PAGE_SIZE;
+ for (i = 1; i < 64; physaddr += PAGE_SIZE, i++)
+ pte_val(*pte_dir++) = physaddr;
X }
- ktablep += 64;
-
- /*
- * make the kernel pointer table point to the
- * kernel page table. Each entries point to a
- * 64 entry section of the page table.
- */
-
- kpointerp[pindex++] = ktable | _PAGE_TABLE | _PAGE_ACCESSED;
+ size -= PTRTREESIZE;
+ virtaddr += PTRTREESIZE;
X } else {
- /*
- * 68030, use early termination page descriptors.
- * Each one points to 64 pages (256K).
- */
-#ifdef DEBUG
- printk ("[early term] ");
-#endif
- if (virtaddr == 0UL) {
- /* map the first 256K using a 64 entry
- * 3rd level page table.
- * UNMAP the first entry to trap
- * zero page (NULL pointer) references
- */
- int i;
- unsigned long *tbl;
-
- tbl = (unsigned long *)get_kpointer_table();
-
- kpointerp[pindex++] = virt_to_phys(tbl) | _PAGE_TABLE |_PAGE_ACCESSED;
-
- for (i = 0; i < 64; i++, physaddr += PAGE_SIZE)
- tbl[i] = physaddr | _PAGE_PRESENT | _PAGE_ACCESSED;
-
- /* unmap the zero page */
- tbl[0] = 0;
- } else {
- /* not the first 256K */
- kpointerp[pindex++] = physaddr | _PAGE_PRESENT | _PAGE_ACCESSED;
+ if (!pmd_present(*pmd_dir)) {
X #ifdef DEBUG
- printk ("%lx=%lx ", virt_to_phys(&kpointerp[pindex-1]),
- kpointerp[pindex-1]);
+ printk ("[new table]");
X #endif
- physaddr += 64 * PAGE_SIZE;
+ pte_dir = kernel_page_table(memavailp);
+ pmd_set(pmd_dir, pte_dir);
X }
+ pte_dir = pte_offset(pmd_dir, virtaddr);
+
+ if (virtaddr) {
+ if (!pte_present(*pte_dir))
+ pte_val(*pte_dir) = physaddr;
+ } else
+ pte_val(*pte_dir) = 0;
+ size -= PAGE_SIZE;
+ virtaddr += PAGE_SIZE;
+ physaddr += PAGE_SIZE;
X }
+
+ }
X #ifdef DEBUG
- printk ("\n");
+ printk("\n");
X #endif
- }
X
- return mem_mapped;
+ return virtaddr;
X }
X
X extern unsigned long free_area_init(unsigned long, unsigned long);
+extern void init_pointer_table(unsigned long ptable);
X
X /* References to section boundaries */
X
X extern char _text, _etext, _edata, __bss_start, _end;
X extern char __init_begin, __init_end;
X
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
X /*
X * paging_init() continues the virtual memory environment setup which
X * was begun by the code in arch/head.S.
X */
-__initfunc(unsigned long paging_init(unsigned long start_mem,
- unsigned long end_mem))
+unsigned long __init paging_init(unsigned long start_mem,
+ unsigned long end_mem)
X {
X int chunk;
X unsigned long mem_avail = 0;
X
X #ifdef DEBUG
X {
- extern pte_t *kpt;
- printk ("start of paging_init (%p, %p, %lx, %lx, %lx)\n",
- kernel_pg_dir, kpt, availmem, start_mem, end_mem);
+ extern unsigned long availmem;
+ printk ("start of paging_init (%p, %lx, %lx, %lx)\n",
+ kernel_pg_dir, availmem, start_mem, end_mem);
X }
X #endif
X
- init_kpointer_table();
-
X /* Fix the cache mode in the page descriptors for the 680[46]0. */
X if (CPU_IS_040_OR_060) {
X int i;
@@ -366,6 +329,7 @@
X m68k_memory[chunk].size, &start_mem);
X
X }
+
X flush_tlb_all();
X #ifdef DEBUG
X printk ("memory available is %ldKB\n", mem_avail >> 10);
@@ -385,21 +349,16 @@
X start_mem += PAGE_SIZE;
X memset((void *)empty_zero_page, 0, PAGE_SIZE);
X
-#if 0
X /*
X * allocate the "swapper" page directory and
X * record in task 0 (swapper) tss
X */
- swapper_pg_dir = (pgd_t *)get_kpointer_table();
-
- init_mm.pgd = swapper_pg_dir;
-#endif
-
- memset (swapper_pg_dir, 0, sizeof(pgd_t)*PTRS_PER_PGD);
+ init_mm.pgd = (pgd_t *)kernel_ptr_table(&start_mem);
+ memset (init_mm.pgd, 0, sizeof(pgd_t)*PTRS_PER_PGD);
X
X /* setup CPU root pointer for swapper task */
X task[0]->tss.crp[0] = 0x80000000 | _PAGE_TABLE;
- task[0]->tss.crp[1] = virt_to_phys (swapper_pg_dir);
+ task[0]->tss.crp[1] = virt_to_phys(init_mm.pgd);
X
X #ifdef DEBUG
X printk ("task 0 pagedir at %p virt, %#lx phys\n",
@@ -430,16 +389,16 @@
X #ifdef DEBUG
X printk ("before free_area_init\n");
X #endif
-
- return PAGE_ALIGN(free_area_init (start_mem, end_mem));
+ return PAGE_ALIGN(free_area_init(start_mem, end_mem));
X }
X
-__initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
+void __init mem_init(unsigned long start_mem, unsigned long end_mem)
X {
X int codepages = 0;
X int datapages = 0;
X int initpages = 0;
X unsigned long tmp;
+ int i;
X
X end_mem &= PAGE_MASK;
X high_memory = (void *) end_mem;
@@ -480,6 +439,14 @@
X #endif
X free_page(tmp);
X }
+
+ /* insert pointer tables allocated so far into the tablelist */
+ init_pointer_table((unsigned long)kernel_pg_dir);
+ for (i = 0; i < PTRS_PER_PGD; i++) {
+ if (pgd_val(kernel_pg_dir[i]))
+ init_pointer_table(pgd_page(kernel_pg_dir[i]));
+ }
+
X printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n",
X (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
X max_mapnr << (PAGE_SHIFT-10),
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/mm/kmap.c linux/arch/m68k/mm/kmap.c
--- v2.2.0-pre8/linux/arch/m68k/mm/kmap.c Sat Sep 5 16:46:40 1998
+++ linux/arch/m68k/mm/kmap.c Tue Jan 19 10:58:34 1999
@@ -2,6 +2,9 @@
X * linux/arch/m68k/mm/kmap.c
X *
X * Copyright (C) 1997 Roman Hodek
+ *
+ * 10/01/99 cleaned up the code and changing to the same interface
+ * used by other architectures /Roman Zippel
X */
X
X #include <linux/mm.h>
@@ -9,250 +12,88 @@
X #include <linux/string.h>
X #include <linux/types.h>
X #include <linux/malloc.h>
+#include <linux/vmalloc.h>
X

X #include <asm/setup.h>
X #include <asm/segment.h>

X #include <asm/page.h>
X #include <asm/pgtable.h>
+#include <asm/io.h>
X #include <asm/system.h>
X
+#undef DEBUG
X
-extern pte_t *kernel_page_table (unsigned long *memavailp);
-
-/* Granularity of kernel_map() allocations */
-#define KMAP_STEP (256*1024)
-
-/* Size of pool of KMAP structures; that is needed, because kernel_map() can
- * be called at times where kmalloc() isn't initialized yet. */
-#define KMAP_POOL_SIZE 16
-
-/* structure for maintainance of kmap regions */
-typedef struct kmap {
- struct kmap *next, *prev; /* linking of list */
- unsigned long addr; /* start address of region */
- unsigned long mapaddr; /* address returned to user */
- unsigned long size; /* size of region */
- unsigned free : 1; /* flag whether free or allocated */
- unsigned kmalloced : 1; /* flag whether got this from kmalloc() */
- unsigned pool_alloc : 1; /* flag whether got this is alloced in pool */
-} KMAP;
-
-KMAP kmap_pool[KMAP_POOL_SIZE] = {
- { NULL, NULL, KMAP_START, KMAP_START, KMAP_END-KMAP_START, 1, 0, 1 },
- { NULL, NULL, 0, 0, 0, 0, 0, 0 },
-};
+#define PTRTREESIZE (256*1024)
X
X /*
- * anchor of kmap region list
- *
- * The list is always ordered by addresses, and regions are always adjacent,
- * i.e. there must be no holes between them!
+ * For 040/060 we can use the virtual memory area like other architectures,
+ * but for 020/030 we want to use early termination page descriptor and we
+ * can't mix this with normal page descriptors, so we have to copy that code
+ * (mm/vmalloc.c) and return appriorate aligned addresses.
X */
-KMAP *kmap_regions = &kmap_pool[0];
-
-/* for protecting the kmap_regions list against races */
-static struct semaphore kmap_sem = MUTEX;
X
+#ifdef CPU_M68040_OR_M68060_ONLY
X
+#define IO_SIZE PAGE_SIZE
X
-/*
- * Low-level allocation and freeing of KMAP structures
- */
-static KMAP *alloc_kmap( int use_kmalloc )
+static inline struct vm_struct *get_io_area(unsigned long size)
X {
- KMAP *p;
- int i;
-
- /* first try to get from the pool if possible */
- for( i = 0; i < KMAP_POOL_SIZE; ++i ) {
- if (!kmap_pool[i].pool_alloc) {
- kmap_pool[i].kmalloced = 0;
- kmap_pool[i].pool_alloc = 1;
- return( &kmap_pool[i] );
- }
- }
-
- if (use_kmalloc && (p = (KMAP *)kmalloc( sizeof(KMAP), GFP_KERNEL ))) {
- p->kmalloced = 1;
- return( p );
- }
-
- return( NULL );
-}
-
-static void free_kmap( KMAP *p )
-{
- if (p->kmalloced)
- kfree( p );
- else
- p->pool_alloc = 0;
+ return get_vm_area(size);
X }
X
X
-/*
- * Get a free region from the kmap address range
- */
-static KMAP *kmap_get_region( unsigned long size, int use_kmalloc )
+static inline void free_io_area(void *addr)
X {
- KMAP *p, *q;
-
- /* look for a suitable free region */
- for( p = kmap_regions; p; p = p->next )
- if (p->free && p->size >= size)
- break;
- if (!p) {
- printk( KERN_ERR "kernel_map: address space for "
- "allocations exhausted\n" );
- return( NULL );
- }
-
- if (p->size > size) {
- /* if free region is bigger than we need, split off the rear free part
- * into a new region */
- if (!(q = alloc_kmap( use_kmalloc ))) {
- printk( KERN_ERR "kernel_map: out of memory\n" );
- return( NULL );
- }
- q->addr = p->addr + size;
- q->size = p->size - size;
- p->size = size;
- q->free = 1;
-
- q->prev = p;
- q->next = p->next;
- p->next = q;
- if (q->next) q->next->prev = q;
- }
-
- p->free = 0;
- return( p );
+ return vfree((void *)(PAGE_MASK & (unsigned long)addr));
X }
X
+#else
X
-/*
- * Free a kernel_map region again
- */
-static void kmap_put_region( KMAP *p )
-{
- KMAP *q;
-
- p->free = 1;
-
- /* merge with previous region if possible */
- q = p->prev;
- if (q && q->free) {
- if (q->addr + q->size != p->addr) {
- printk( KERN_ERR "kernel_malloc: allocation list destroyed\n" );
- return;
- }
- q->size += p->size;
- q->next = p->next;
- if (p->next) p->next->prev = q;
- free_kmap( p );
- p = q;
- }
-
- /* merge with following region if possible */
- q = p->next;
- if (q && q->free) {
- if (p->addr + p->size != q->addr) {
- printk( KERN_ERR "kernel_malloc: allocation list destroyed\n" );
- return;
- }
- p->size += q->size;
- p->next = q->next;
- if (q->next) q->next->prev = p;
- free_kmap( q );
- }
-}
+#define IO_SIZE (256*1024)
X
+static struct vm_struct *iolist = NULL;
X
-/*
- * kernel_map() helpers
- */
-static inline pte_t *
-pte_alloc_kernel_map(pmd_t *pmd, unsigned long address,
- unsigned long *memavailp)
+static struct vm_struct *get_io_area(unsigned long size)
X {
- address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
- if (pmd_none(*pmd)) {
- pte_t *page = kernel_page_table(memavailp);
- if (pmd_none(*pmd)) {
- if (page) {
- pmd_set(pmd, page);
- memset( page, 0, PAGE_SIZE );
- return page + address;
- }
- pmd_set(pmd, BAD_PAGETABLE);
- return NULL;
- }
- if (memavailp)
- panic("kernel_map: slept during init?!?");
- cache_page((unsigned long) page);
- free_page((unsigned long) page);
- }
- if (pmd_bad(*pmd)) {
- printk( KERN_ERR "Bad pmd in pte_alloc_kernel_map: %08lx\n",
- pmd_val(*pmd));
- pmd_set(pmd, BAD_PAGETABLE);
+ unsigned long addr;
+ struct vm_struct **p, *tmp, *area;
+
+ area = (struct vm_struct *)kmalloc(sizeof(*area), GFP_KERNEL);
+ if (!area)
X return NULL;
+ addr = KMAP_START;
+ for (p = &iolist; (tmp = *p) ; p = &tmp->next) {
+ if (size + addr < (unsigned long)tmp->addr)
+ break;
+ if (addr > KMAP_END-size)
+ return NULL;
+ addr = tmp->size + (unsigned long)tmp->addr;
X }
- return (pte_t *) pmd_page(*pmd) + address;
+ area->addr = (void *)addr;
+ area->size = size + IO_SIZE;
+ area->next = *p;
+ *p = area;
+ return area;
X }
X
-static inline void
-kernel_map_pte(pte_t *pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, pgprot_t prot)
+static inline void free_io_area(void *addr)
X {
- unsigned long end;
+ struct vm_struct **p, *tmp;
X
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- do {
- pte_val(*pte) = phys_addr + pgprot_val(prot);
- address += PAGE_SIZE;
- phys_addr += PAGE_SIZE;
- pte++;
- } while (address < end);
-}
-
-static inline int
-kernel_map_pmd (pmd_t *pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, pgprot_t prot,
- unsigned long *memavailp)
-{
- unsigned long end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- phys_addr -= address;
-
- if (CPU_IS_040_OR_060) {
- do {
- pte_t *pte = pte_alloc_kernel_map(pmd, address, memavailp);
- if (!pte)
- return -ENOMEM;
- kernel_map_pte(pte, address, end - address,
- address + phys_addr, prot);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address < end);
- } else {
- /* On the 68030 we use early termination page descriptors.
- Each one points to 64 pages (256K). */
- int i = (address >> (PMD_SHIFT-4)) & 15;
- do {
- (&pmd_val(*pmd))[i++] = (address + phys_addr) | pgprot_val(prot);
- address += PMD_SIZE / 16;
- } while (address < end);
+ if (!addr)
+ return;
+ addr = (void *)((unsigned long)addr & -IO_SIZE);
+ for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {
+ if (tmp->addr == addr) {
+ *p = tmp->next;
+ __iounmap(tmp->addr, tmp->size);
+ kfree(tmp);
+ return;
+ }
X }
- return 0;
X }
X
+#endif
X
X /*
X * Map some physical address range into the kernel address space. The
@@ -260,304 +101,245 @@
X */
X /* Rewritten by Andreas Schwab to remove all races. */
X
-unsigned long kernel_map(unsigned long phys_addr, unsigned long size,
- int cacheflag, unsigned long *memavailp)
+void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
X {
- unsigned long retaddr, from, end;
- pgd_t *dir;
- pgprot_t prot;
- KMAP *kmap;
-
- /* Round down 'phys_addr' to 256 KB and adjust size */
- retaddr = phys_addr & (KMAP_STEP-1);
- size += retaddr;
- phys_addr &= ~(KMAP_STEP-1);
- /* Round up the size to 256 KB. It doesn't hurt if too much is
- mapped... */
- size = (size + KMAP_STEP - 1) & ~(KMAP_STEP-1);
-
- down( &kmap_sem );
- kmap = kmap_get_region(size, memavailp == NULL);
- if (!kmap) {
- up(&kmap_sem);
- return 0;
- }
- from = kmap->addr;
- retaddr += from;
- kmap->mapaddr = retaddr;
- end = from + size;
- up( &kmap_sem );
+ struct vm_struct *area;
+ unsigned long virtaddr, retaddr;
+ long offset;
+ pgd_t *pgd_dir;
+ pmd_t *pmd_dir;
+ pte_t *pte_dir;
+
+ /*
+ * Don't allow mappings that wrap..
+ */
+ if (!size || size > physaddr + size)
+ return NULL;
X
+#ifdef DEBUG
+ printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);
+#endif
+ /*
+ * Mappings have to be aligned
+ */
+ offset = physaddr & (IO_SIZE - 1);
+ physaddr &= -IO_SIZE;
+ size = (size + offset + IO_SIZE - 1) & -IO_SIZE;
+
+ /*
+ * Ok, go for it..
+ */
+ area = get_io_area(size);
+ if (!area)
+ return NULL;
+
+ virtaddr = (unsigned long)area->addr;
+ retaddr = virtaddr + offset;
+#ifdef DEBUG
+ printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr);
+#endif
+
+ /*
+ * add cache and table flags to physical address
+ */
X if (CPU_IS_040_OR_060) {
- pgprot_val(prot) = (_PAGE_PRESENT | _PAGE_GLOBAL040 |
- _PAGE_ACCESSED | _PAGE_DIRTY);
+ physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 |
+ _PAGE_ACCESSED | _PAGE_DIRTY);
X switch (cacheflag) {
- case KERNELMAP_FULL_CACHING:
- pgprot_val(prot) |= _PAGE_CACHE040;
+ case IOMAP_FULL_CACHING:
+ physaddr |= _PAGE_CACHE040;
X break;
- case KERNELMAP_NOCACHE_SER:
+ case IOMAP_NOCACHE_SER:
X default:
- pgprot_val(prot) |= _PAGE_NOCACHE_S;
+ physaddr |= _PAGE_NOCACHE_S;
X break;
- case KERNELMAP_NOCACHE_NONSER:
- pgprot_val(prot) |= _PAGE_NOCACHE;


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 04'
echo 'File patch-2.2.0-pre9 is continued in part 05'
echo 05 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part05

#!/bin/sh
# this is part 05 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 05; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

+ case IOMAP_NOCACHE_NONSER:
+ physaddr |= _PAGE_NOCACHE;
X break;
- case KERNELMAP_NO_COPYBACK:
- pgprot_val(prot) |= _PAGE_CACHE040W;
+ case IOMAP_WRITETHROUGH:
+ physaddr |= _PAGE_CACHE040W;
X break;
X }
- } else
- pgprot_val(prot) = (_PAGE_PRESENT | _PAGE_ACCESSED |
- _PAGE_DIRTY |
- ((cacheflag == KERNELMAP_FULL_CACHING ||
- cacheflag == KERNELMAP_NO_COPYBACK)
- ? 0 : _PAGE_NOCACHE030));
-
- phys_addr -= from;
- dir = pgd_offset_k(from);
- while (from < end) {
- pmd_t *pmd = pmd_alloc_kernel(dir, from);
-
- if (kernel_map_pmd(pmd, from, end - from, phys_addr + from,
- prot, memavailp)) {


- printk( KERN_ERR "kernel_map: out of memory\n" );

- return 0UL;
+ } else {
+ physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
+ switch (cacheflag) {
+ case IOMAP_NOCACHE_SER:
+ case IOMAP_NOCACHE_NONSER:
+ default:
+ physaddr |= _PAGE_NOCACHE030;
+ break;
+ case IOMAP_FULL_CACHING:
+ case IOMAP_WRITETHROUGH:
+ break;
X }
- from = (from + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
X }
X
- return retaddr;
-}


-
+ while (size > 0) {

+#ifdef DEBUG


+ if (!(virtaddr & (PTRTREESIZE-1)))

+ printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);
+#endif
+ pgd_dir = pgd_offset_k(virtaddr);
+ pmd_dir = pmd_alloc_kernel(pgd_dir, virtaddr);
+ if (!pmd_dir) {
+ printk("ioremap: no mem for pmd_dir\n");
+ return NULL;
+ }
X
-/*
- * kernel_unmap() helpers
- */
-static inline void pte_free_kernel_unmap( pmd_t *pmd )
-{
- unsigned long page = pmd_page(*pmd);
- mem_map_t *pagemap = &mem_map[MAP_NR(page)];
-
- pmd_clear(pmd);
- cache_page(page);
-
- if (PageReserved( pagemap )) {
- /* need to unreserve pages that were allocated with memavailp != NULL;
- * this works only if 'page' is page-aligned */
- if (page & ~PAGE_MASK)
- return;
- clear_bit( PG_reserved, &pagemap->flags );
- atomic_set( &pagemap->count, 1 );
- }
- free_page( page );
-}
+ if (CPU_IS_020_OR_030) {
+ pmd_dir->pmd[(virtaddr/PTRTREESIZE)&-16] = physaddr;
+ physaddr += PTRTREESIZE;
+ virtaddr += PTRTREESIZE;
+ size -= PTRTREESIZE;
+ } else {
+ pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
+ if (!pte_dir) {
+ printk("ioremap: no mem for pte_dir\n");
+ return NULL;
+ }
X
-/*
- * This not only unmaps the requested region, but also loops over the whole
- * pmd to determine whether the other pte's are clear (so that the page can be
- * freed.) If so, it returns 1, 0 otherwise.
- */
-static inline int
-kernel_unmap_pte_range(pmd_t * pmd, unsigned long address, unsigned long size)
-{
- pte_t *pte;
- unsigned long addr2, end, end2;
- int all_clear = 1;
-
- if (pmd_none(*pmd))
- return( 0 );
- if (pmd_bad(*pmd)) {
- printk( KERN_ERR "kernel_unmap_pte_range: bad pmd (%08lx)\n",
- pmd_val(*pmd) );
- pmd_clear(pmd);
- return( 0 );
- }
- address &= ~PMD_MASK;
- addr2 = 0;
- pte = pte_offset(pmd, addr2);


- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;

- end2 = addr2 + PMD_SIZE;
- while( addr2 < end2 ) {
- if (!pte_none(*pte)) {
- if (address <= addr2 && addr2 < end)
- pte_clear(pte);
- else
- all_clear = 0;
+ pte_val(*pte_dir) = physaddr;


+ virtaddr += PAGE_SIZE;
+ physaddr += PAGE_SIZE;

+ size -= PAGE_SIZE;
X }
- ++pte;
- addr2 += PAGE_SIZE;
X }
- return( all_clear );
-}
-
-static inline void
-kernel_unmap_pmd_range(pgd_t * dir, unsigned long address, unsigned long size)
-{
- pmd_t * pmd;
- unsigned long end;
+#ifdef DEBUG
+ printk("\n");
+#endif
+ flush_tlb_all();
X
- if (pgd_none(*dir))
- return;
- if (pgd_bad(*dir)) {
- printk( KERN_ERR "kernel_unmap_pmd_range: bad pgd (%08lx)\n",
- pgd_val(*dir) );
- pgd_clear(dir);
- return;
- }
- pmd = pmd_offset(dir, address);


- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
-

- if (CPU_IS_040_OR_060) {
- do {

- if (kernel_unmap_pte_range(pmd, address, end - address))
- pte_free_kernel_unmap( pmd );


- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address < end);
- } else {

- /* On the 68030 clear the early termination descriptors */


- int i = (address >> (PMD_SHIFT-4)) & 15;
- do {

- (&pmd_val(*pmd))[i++] = 0;


- address += PMD_SIZE / 16;
- } while (address < end);

- }
+ return (void *)retaddr;
X }
X
X /*
- * Unmap a kernel_map()ed region again
+ * Unmap a ioremap()ed region again
X */
-void kernel_unmap( unsigned long addr )
+void iounmap(void *addr)


X {
- unsigned long end;

- pgd_t *dir;
- KMAP *p;


-
- down( &kmap_sem );
-

- /* find region for 'addr' in list; must search for mapaddr! */


- for( p = kmap_regions; p; p = p->next )

- if (!p->free && p->mapaddr == addr)


- break;
- if (!p) {

- printk( KERN_ERR "kernel_unmap: trying to free invalid region\n" );
- return;
- }
- addr = p->addr;
- end = addr + p->size;
- kmap_put_region( p );
-
- dir = pgd_offset_k( addr );
- while( addr < end ) {
- kernel_unmap_pmd_range( dir, addr, end - addr );
- addr = (addr + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- }
-
- up( &kmap_sem );
- /* flushing for a range would do, but there's no such function for kernel
- * address space... */
- flush_tlb_all();
+ free_io_area(addr);
X }
X
-
X /*
- * kernel_set_cachemode() helpers
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
X */
-static inline void set_cmode_pte( pmd_t *pmd, unsigned long address,
- unsigned long size, unsigned cmode )
-{ pte_t *pte;


- unsigned long end;
-

- if (pmd_none(*pmd))
- return;
-
- pte = pte_offset( pmd, address );


- address &= ~PMD_MASK;
- end = address + size;

- if (end >= PMD_SIZE)


- end = PMD_SIZE;
-

- for( ; address < end; pte++ ) {
- pte_val(*pte) = (pte_val(*pte) & ~_PAGE_NOCACHE) | cmode;


- address += PAGE_SIZE;
- }

-}
+void __iounmap(void *addr, unsigned long size)
+{
+ unsigned long virtaddr = (unsigned long)addr;


+ pgd_t *pgd_dir;
+ pmd_t *pmd_dir;
+ pte_t *pte_dir;
X

+ while (size > 0) {
+ pgd_dir = pgd_offset_k(virtaddr);
+ if (pgd_bad(*pgd_dir)) {
+ printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
+ pgd_clear(pgd_dir);
+ return;
+ }


+ pmd_dir = pmd_offset(pgd_dir, virtaddr);
X

-static inline void set_cmode_pmd( pgd_t *dir, unsigned long address,
- unsigned long size, unsigned cmode )
-{
- pmd_t *pmd;
- unsigned long end;
+ if (CPU_IS_020_OR_030) {
+ int pmd_off = (virtaddr/PTRTREESIZE) & -16;
X
- if (pgd_none(*dir))
- return;
+ if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
+ pmd_dir->pmd[pmd_off] = 0;
+ virtaddr += PTRTREESIZE;
+ size -= PTRTREESIZE;
+ continue;
+ }
+ }
X
- pmd = pmd_offset( dir, address );


- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
-

- if ((pmd_val(*pmd) & _DESCTYPE_MASK) == _PAGE_PRESENT) {
- /* 68030 early termination descriptor */
- pmd_val(*pmd) = (pmd_val(*pmd) & ~_PAGE_NOCACHE) | cmode;
- return;
- }
- else {
- /* "normal" tables */
- for( ; address < end; pmd++ ) {
- set_cmode_pte( pmd, address, end - address, cmode );


- address = (address + PMD_SIZE) & PMD_MASK;

+ if (pmd_bad(*pmd_dir)) {
+ printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
+ pmd_clear(pmd_dir);
+ return;


X }
+ pte_dir = pte_offset(pmd_dir, virtaddr);
+

+ pte_val(*pte_dir) = 0;
+ virtaddr += PAGE_SIZE;
+ size -= PAGE_SIZE;
X }
-}
X
+ flush_tlb_all();
+}
X
X /*
X * Set new cache mode for some kernel address space.
X * The caller must push data for that range itself, if such data may already
X * be in the cache.
X */
-void kernel_set_cachemode( unsigned long address, unsigned long size,
- unsigned cmode )
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
X {
- pgd_t *dir = pgd_offset_k( address );
- unsigned long end = address + size;
-
+ unsigned long virtaddr = (unsigned long)addr;


+ pgd_t *pgd_dir;
+ pmd_t *pmd_dir;
+ pte_t *pte_dir;
+

X if (CPU_IS_040_OR_060) {
- switch( cmode ) {
- case KERNELMAP_FULL_CACHING:
+ switch (cmode) {
+ case IOMAP_FULL_CACHING:
X cmode = _PAGE_CACHE040;


X break;
- case KERNELMAP_NOCACHE_SER:

- default:
+ case IOMAP_NOCACHE_SER:
+ default:
X cmode = _PAGE_NOCACHE_S;


X break;
- case KERNELMAP_NOCACHE_NONSER:

+ case IOMAP_NOCACHE_NONSER:
X cmode = _PAGE_NOCACHE;
X break;
- case KERNELMAP_NO_COPYBACK:
+ case IOMAP_WRITETHROUGH:
X cmode = _PAGE_CACHE040W;
X break;
X }
- } else
- cmode = ((cmode == KERNELMAP_FULL_CACHING ||
- cmode == KERNELMAP_NO_COPYBACK) ?
- 0 : _PAGE_NOCACHE030);
-
- for( ; address < end; dir++ ) {
- set_cmode_pmd( dir, address, end - address, cmode );
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ } else {
+ switch (cmode) {
+ case IOMAP_NOCACHE_SER:
+ case IOMAP_NOCACHE_NONSER:
+ default:
+ cmode = _PAGE_NOCACHE030;
+ break;
+ case IOMAP_FULL_CACHING:
+ case IOMAP_WRITETHROUGH:
+ cmode = 0;
+ }
+ }
+
+ while (size > 0) {
+ pgd_dir = pgd_offset_k(virtaddr);
+ if (pgd_bad(*pgd_dir)) {
+ printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
+ pgd_clear(pgd_dir);
+ return;
+ }


+ pmd_dir = pmd_offset(pgd_dir, virtaddr);

+
+ if (CPU_IS_020_OR_030) {
+ int pmd_off = (virtaddr/PTRTREESIZE) & -16;
+
+ if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
+ pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] &
+ _CACHEMASK040) | cmode;
+ virtaddr += PTRTREESIZE;
+ size -= PTRTREESIZE;
+ continue;
+ }
+ }
+
+ if (pmd_bad(*pmd_dir)) {
+ printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
+ pmd_clear(pmd_dir);
+ return;
+ }


+ pte_dir = pte_offset(pmd_dir, virtaddr);
+

+ pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode;
+ virtaddr += PAGE_SIZE;
+ size -= PAGE_SIZE;
X }
- /* flushing for a range would do, but there's no such function for kernel
- * address space... */
+
X flush_tlb_all();
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c
--- v2.2.0-pre8/linux/arch/m68k/mm/memory.c Fri Oct 9 13:27:06 1998
+++ linux/arch/m68k/mm/memory.c Tue Jan 19 10:58:34 1999
@@ -10,6 +10,7 @@


X #include <linux/string.h>
X #include <linux/types.h>
X #include <linux/malloc.h>

+#include <linux/init.h>


X
X #include <asm/setup.h>
X #include <asm/segment.h>

@@ -97,6 +98,31 @@
X
X #define PTABLE_SIZE (PTRS_PER_PMD * sizeof(pmd_t))
X
+void __init init_pointer_table(unsigned long ptable)
+{
+ ptable_desc *dp;
+ unsigned long page = ptable & PAGE_MASK;
+ unsigned char mask = 1 << ((ptable - page)/PTABLE_SIZE);
+
+ dp = PAGE_PD(page);
+ if (!(PD_MARKBITS(dp) & mask)) {
+ PD_MARKBITS(dp) = 0xff;
+ (dp->prev = ptable_list.prev)->next = dp;
+ (dp->next = &ptable_list)->prev = dp;
+ }
+
+ PD_MARKBITS(dp) &= ~mask;
+#ifdef DEBUG
+ printk("init_pointer_table: %lx, %x\n", ptable, PD_MARKBITS(dp));
+#endif
+
+ /* unreserve the page so it's possible to free that page */
+ dp->flags &= ~(1 << PG_reserved);
+ atomic_set(&dp->count, 1);
+
+ return;
+}
+
X pmd_t *get_pointer_table (void)
X {
X ptable_desc *dp = ptable_list.next;
@@ -176,103 +202,6 @@
X return 0;
X }
X
-/* maximum pages used for kpointer tables */
-#define KPTR_PAGES 4
-/* # of reserved slots */
-#define RESERVED_KPTR 4
-extern pmd_tablepage kernel_pmd_table; /* reserved in head.S */
-
-static struct kpointer_pages {
- pmd_tablepage *page[KPTR_PAGES];
- u_char alloced[KPTR_PAGES];
-} kptr_pages;
-
-void init_kpointer_table(void) {
- short i = KPTR_PAGES-1;
-
- /* first page is reserved in head.S */
- kptr_pages.page[i] = &kernel_pmd_table;
- kptr_pages.alloced[i] = ~(0xff>>RESERVED_KPTR);
- for (i--; i>=0; i--) {
- kptr_pages.page[i] = NULL;
- kptr_pages.alloced[i] = 0;
- }
-}
-
-pmd_t *get_kpointer_table (void)
-{
- /* For pointer tables for the kernel virtual address space,
- * use the page that is reserved in head.S that can hold up to
- * 8 pointer tables. 3 of these tables are always reserved
- * (kernel_pg_dir, swapper_pg_dir and kernel pointer table for
- * the first 16 MB of RAM). In addition, the 4th pointer table
- * in this page is reserved. On Amiga and Atari, it is used to
- * map in the hardware registers. It may be used for other
- * purposes on other 68k machines. This leaves 4 pointer tables
- * available for use by the kernel. 1 of them are usually used
- * for the vmalloc tables. This allows mapping of 3 * 32 = 96 MB
- * of physical memory. But these pointer tables are also used
- * for other purposes, like kernel_map(), so further pages can
- * now be allocated.
- */
- pmd_tablepage *page;
- pmd_table *table;
- long nr, offset = -8;
- short i;
-
- for (i=KPTR_PAGES-1; i>=0; i--) {
- asm volatile("bfffo %1{%2,#8},%0"
- : "=d" (nr)
- : "d" ((u_char)~kptr_pages.alloced[i]), "d" (offset));
- if (nr)
- break;
- }
- if (i < 0) {
- printk("No space for kernel pointer table!\n");
- return NULL;
- }
- if (!(page = kptr_pages.page[i])) {
- if (!(page = (pmd_tablepage *)get_free_page(GFP_KERNEL))) {
- printk("No space for kernel pointer table!\n");
- return NULL;
- }
- flush_tlb_kernel_page((unsigned long) page);
- nocache_page((u_long)(kptr_pages.page[i] = page));
- }
- asm volatile("bfset %0@{%1,#1}"
- : /* no output */
- : "a" (&kptr_pages.alloced[i]), "d" (nr-offset));
- table = &(*page)[nr-offset];
- memset(table, 0, sizeof(pmd_table));
- return ((pmd_t *)table);
-}
-
-void free_kpointer_table (pmd_t *pmdp)
-{
- pmd_table *table = (pmd_table *)pmdp;
- pmd_tablepage *page = (pmd_tablepage *)((u_long)table & PAGE_MASK);
- long nr;
- short i;
-
- for (i=KPTR_PAGES-1; i>=0; i--) {
- if (kptr_pages.page[i] == page)
- break;
- }
- nr = ((u_long)table - (u_long)page) / sizeof(pmd_table);
- if (!table || i < 0 || (i == KPTR_PAGES-1 && nr < RESERVED_KPTR)) {
- printk("Attempt to free invalid kernel pointer table: %p\n", table);
- return;
- }
- asm volatile("bfclr %0@{%1,#1}"
- : /* no output */
- : "a" (&kptr_pages.alloced[i]), "d" (nr));
- if (!kptr_pages.alloced[i]) {
- kptr_pages.page[i] = 0;
- cache_page ((u_long)page);
- free_page ((u_long)page);
- }
-}
-
X static unsigned long transp_transl_matches( unsigned long regval,
X unsigned long vaddr )
X {
@@ -308,7 +237,6 @@
X */
X unsigned long mm_vtop (unsigned long vaddr)
X {
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
X int i=0;
X unsigned long voff = vaddr;
X unsigned long offset = 0;
@@ -324,10 +252,6 @@
X offset += m68k_memory[i].size;
X i++;
X }while (i < m68k_num_memory);
-#else
- if (vaddr < m68k_memory[0].size)
- return m68k_memory[0].addr + vaddr;
-#endif
X
X return mm_vtop_fallback(vaddr);
X }
@@ -449,7 +373,6 @@
X #ifndef CONFIG_SINGLE_MEMORY_CHUNK
X unsigned long mm_ptov (unsigned long paddr)
X {
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
X int i = 0;
X unsigned long offset = 0;
X
@@ -466,11 +389,6 @@
X offset += m68k_memory[i].size;
X i++;
X }while (i < m68k_num_memory);
-#else
- unsigned long base = m68k_memory[0].addr;
- if (paddr >= base && paddr < (base + m68k_memory[0].size))
- return (paddr - base);
-#endif
X
X /*
X * assume that the kernel virtual address is the same as the
@@ -560,7 +478,7 @@
X * Jes was worried about performance (urhh ???) so its optional
X */
X
-extern void (*mach_l2_flush)(int) = NULL;
+void (*mach_l2_flush)(int) = NULL;
X #endif
X
X /*
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c
--- v2.2.0-pre8/linux/arch/mips/kernel/time.c Fri Oct 23 22:01:19 1998
+++ linux/arch/mips/kernel/time.c Tue Jan 19 10:19:48 1999
@@ -6,6 +6,9 @@
X * This file contains the time handling details for PC-style clocks as
X * found in some MIPS systems.
X *


+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills

+ *
X * $Id: time.c,v 1.6 1998/08/17 13:57:44 ralf Exp $


X */
X #include <linux/errno.h>

@@ -255,9 +258,11 @@


X }
X
X xtime = *tv;
- time_state = TIME_BAD;
- time_maxerror = MAXPHASE;
- time_esterror = MAXPHASE;
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR; /* p. 24, (a) */
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
X sti();
X }

X
@@ -267,6 +272,9 @@


X * nowtime is written into the registers of the CMOS clock, it will
X * jump to the next second precisely 500 ms later. Check the Motorola
X * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ * sets the minutes. Usually you won't notice until after reboot!
X */

X static int set_rtc_mmss(unsigned long nowtime)
X {
@@ -303,8 +311,12 @@


X }
X CMOS_WRITE(real_seconds,RTC_SECONDS);
X CMOS_WRITE(real_minutes,RTC_MINUTES);
- } else
- retval = -1;
+ } else {
+ printk(KERN_WARNING
+ "set_rtc_mmss: can't update from %d to %d\n",
+ cmos_minutes, real_minutes);
+ retval = -1;
+ }
X
X /* The following flags have to be released exactly in this order,
X * otherwise the DS12887 (popular MC146818A clone with integrated

@@ -336,9 +348,10 @@


X * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
X * called as close as possible to 500 ms before the new second starts.
X */
- if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
- xtime.tv_usec > 500000 - (tick >> 1) &&
- xtime.tv_usec < 500000 + (tick >> 1))
+ if ((time_status & STA_UNSYNC) == 0 &&
+ xtime.tv_sec > last_rtc_update + 660 &&
+ xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+ xtime.tv_usec <= 500000 + ((unsigned) tick) / 2)
X if (set_rtc_mmss(xtime.tv_sec) == 0)
X last_rtc_update = xtime.tv_sec;
X else

diff -u --recursive --new-file v2.2.0-pre8/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- v2.2.0-pre8/linux/arch/ppc/kernel/time.c Thu Dec 31 10:28:59 1998
+++ linux/arch/ppc/kernel/time.c Tue Jan 19 10:19:50 1999
@@ -17,6 +17,9 @@
X * This is then divided by 4, providing a 8192 Hz clock into the PIT.
X * Since it is not possible to get a nice 100 Hz clock out of this, without
X * creating a software PLL, I have set HZ to 128. -- Dan


+ *
+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills
X */
X
X #include <linux/config.h>

@@ -195,6 +198,11 @@
X xtime.tv_sec = tv->tv_sec;
X xtime.tv_usec = tv->tv_usec - frac_tick;
X set_dec(frac_tick * count_period_den / count_period_num);


+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR; /* p. 24, (a) */
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;

X restore_flags(flags);
X }
X
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/sparc/kernel/time.c linux/arch/sparc/kernel/time.c
--- v2.2.0-pre8/linux/arch/sparc/kernel/time.c Mon Oct 5 13:13:37 1998
+++ linux/arch/sparc/kernel/time.c Tue Jan 19 10:19:52 1999
@@ -11,6 +11,9 @@
X * Support for MicroSPARC-IIep, PCI CPU.
X *
X * This file handles the Sparc specific time handling details.


+ *
+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills
X */

X #include <linux/config.h>
X #include <linux/errno.h>
@@ -89,9 +92,10 @@
X do_timer(regs);
X
X /* Determine when to update the Mostek clock. */


- if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
- xtime.tv_usec > 500000 - (tick >> 1) &&
- xtime.tv_usec < 500000 + (tick >> 1)) {
+ if ((time_status & STA_UNSYNC) == 0 &&
+ xtime.tv_sec > last_rtc_update + 660 &&
+ xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+ xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
X if (set_rtc_mmss(xtime.tv_sec) == 0)
X last_rtc_update = xtime.tv_sec;
X else

@@ -495,12 +499,18 @@
X }
X #endif


X xtime = *tv;
- time_state = TIME_BAD;

- time_maxerror = 0x70000000;
- time_esterror = 0x70000000;

+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR; /* p. 24, (a) */
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
X sti();
X }

X
+/*


+ * BUG: This routine does not handle hour overflow properly; it just
+ * sets the minutes. Usually you won't notice until after reboot!

+ */
X static int set_rtc_mmss(unsigned long nowtime)
X {
X int real_seconds, real_minutes, mostek_minutes;
@@ -531,9 +541,13 @@
X iregs->clk.int_sec=real_seconds;
X iregs->clk.int_min=real_minutes;
X intersil_start(iregs);
- } else

+ } else {
+ printk(KERN_WARNING
+ "set_rtc_mmss: can't update from %d to %d\n",
+ cmos_minutes, real_minutes);

X return -1;
-
+ }


+
X return 0;
X }

X #endif
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c
--- v2.2.0-pre8/linux/arch/sparc/mm/srmmu.c Mon Oct 5 13:13:37 1998
+++ linux/arch/sparc/mm/srmmu.c Wed Jan 20 13:35:46 1999
@@ -470,7 +470,7 @@
X (unsigned int)ret->pprev_hash = mask & ~tmp;
X if (!(mask & ~tmp))
X pte_quicklist = (unsigned long *)ret->next_hash;
- ret = (struct page *)(PAGE_OFFSET + (ret->map_nr << PAGE_SHIFT) + off);
+ ret = (struct page *)(page_address(ret) + off);
X pgtable_cache_size--;
X }
X spin_unlock(&pte_spinlock);
@@ -508,7 +508,7 @@
X (unsigned int)ret->pprev_hash = mask & ~tmp;
X if (!(mask & ~tmp))
X pgd_quicklist = (unsigned long *)ret->next_hash;
- ret = (struct page *)(PAGE_OFFSET + (ret->map_nr << PAGE_SHIFT) + off);
+ ret = (struct page *)(page_address(ret) + off);
X pgd_cache_size--;
X }
X spin_unlock(&pgd_spinlock);
@@ -682,7 +682,7 @@
X spin_lock(&pgd_spinlock);
X address >>= SRMMU_PGDIR_SHIFT;
X for (page = (struct page *)pgd_quicklist; page; page = page->next_hash) {
- pgd_t *pgd = (pgd_t *)(PAGE_OFFSET + (page->map_nr << PAGE_SHIFT));
+ pgd_t *pgd = (pgd_t *)page_address(page);
X unsigned int mask = (unsigned int)page->pprev_hash;
X
X if (mask & 1)
@@ -2817,7 +2817,7 @@
X page->next_hash = NULL;
X page->pprev_hash = NULL;
X pgtable_cache_size -= 16;
- free_page(PAGE_OFFSET + (page->map_nr << PAGE_SHIFT));
+ __free_page(page);
X freed++;
X if (page2)
X page = page2->next_hash;
@@ -2843,7 +2843,7 @@
X page->next_hash = NULL;
X page->pprev_hash = NULL;
X pgd_cache_size -= 4;
- free_page(PAGE_OFFSET + (page->map_nr << PAGE_SHIFT));
+ __free_page(page);
X freed++;
X if (page2)
X page = page2->next_hash;
diff -u --recursive --new-file v2.2.0-pre8/linux/arch/sparc64/kernel/time.c linux/arch/sparc64/kernel/time.c
--- v2.2.0-pre8/linux/arch/sparc64/kernel/time.c Mon Oct 5 13:13:38 1998
+++ linux/arch/sparc64/kernel/time.c Tue Jan 19 10:19:54 1999
@@ -53,9 +53,10 @@
X static long last_rtc_update=0;
X
X /* Determine when to update the Mostek clock. */


- if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
- xtime.tv_usec > 500000 - (tick >> 1) &&
- xtime.tv_usec < 500000 + (tick >> 1)) {
+ if ((time_status & STA_UNSYNC) == 0 &&
+ xtime.tv_sec > last_rtc_update + 660 &&
+ xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
+ xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
X if (set_rtc_mmss(xtime.tv_sec) == 0)
X last_rtc_update = xtime.tv_sec;
X else

@@ -458,10 +459,11 @@


X }
X
X xtime = *tv;
- time_state = TIME_BAD;

- time_maxerror = 0x70000000;
- time_esterror = 0x70000000;

-


+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR; /* p. 24, (a) */
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
X sti();
X }

X
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
--- v2.2.0-pre8/linux/drivers/block/ide-cd.c Tue Jan 19 11:32:51 1999
+++ linux/drivers/block/ide-cd.c Tue Jan 19 11:10:07 1999
@@ -227,9 +227,12 @@
X * "Ville Hallik" <ville....@mail.ee>.
X * - other minor stuff.
X *
+ * 4.52 Jan 19, 1999 -- Jens Axboe <ax...@image.dk>
+ * - Detect DVD-ROM/RAM drives
+ *
X *************************************************************************/
X
-#define IDECD_VERSION "4.51"
+#define IDECD_VERSION "4.52"
X
X #include <linux/module.h>
X #include <linux/types.h>
@@ -2857,6 +2860,14 @@
X CDROM_CONFIG_FLAGS (drive)->cd_r = 1;
X if (buf.cap.cd_rw_write)
X CDROM_CONFIG_FLAGS (drive)->cd_rw = 1;
+ if (buf.cap.test_write)
+ CDROM_CONFIG_FLAGS (drive)->test_write = 1;
+ if (buf.cap.dvd_ram_read || buf.cap.dvd_r_read || buf.cap.dvd_rom)
+ CDROM_CONFIG_FLAGS (drive)->dvd = 1;
+ if (buf.cap.dvd_ram_write)
+ CDROM_CONFIG_FLAGS (drive)->dvd_r = 1;
+ if (buf.cap.dvd_r_write)
+ CDROM_CONFIG_FLAGS (drive)->dvd_rw = 1;
X
X #if ! STANDARD_ATAPI
X if (CDROM_STATE_FLAGS (drive)->sanyo_slot > 0) {
@@ -2892,18 +2903,26 @@
X (ntohs(buf.cap.maxspeed) + (176/2)) / 176;
X }
X
- printk ("%s: ATAPI %dX CDROM",
- drive->name, CDROM_CONFIG_FLAGS (drive)->max_speed);
+ printk ("%s: ATAPI %dX %s",
+ drive->name, CDROM_CONFIG_FLAGS (drive)->max_speed,
+ (CDROM_CONFIG_FLAGS (drive)->dvd) ? "DVD-ROM" : "CD-ROM");
+
+ if (CDROM_CONFIG_FLAGS (drive)->dvd_r|CDROM_CONFIG_FLAGS (drive)->dvd_rw)
+ printk (" DVD%s%s",
+ (CDROM_CONFIG_FLAGS (drive)->dvd_r)? "-RAM" : "",
+ (CDROM_CONFIG_FLAGS (drive)->dvd_rw)? "/RW" : "");
+
X if (CDROM_CONFIG_FLAGS (drive)->cd_r|CDROM_CONFIG_FLAGS (drive)->cd_rw)
X printk (" CD%s%s",
X (CDROM_CONFIG_FLAGS (drive)->cd_r)? "-R" : "",
X (CDROM_CONFIG_FLAGS (drive)->cd_rw)? "/RW" : "");
+
X if (CDROM_CONFIG_FLAGS (drive)->is_changer)
X printk (" changer w/%d slots", nslots);
X else
X printk (" drive");
- printk (", %dkB Cache\n",
- ntohs(buf.cap.buffer_size) );
+
+ printk (", %dkB Cache\n", ntohs(buf.cap.buffer_size));
X
X return nslots;
X }
@@ -2954,6 +2973,10 @@
X CDROM_CONFIG_FLAGS (drive)->is_changer = 0;
X CDROM_CONFIG_FLAGS (drive)->cd_r = 0;
X CDROM_CONFIG_FLAGS (drive)->cd_rw = 0;
+ CDROM_CONFIG_FLAGS (drive)->test_write = 0;
+ CDROM_CONFIG_FLAGS (drive)->dvd = 0;
+ CDROM_CONFIG_FLAGS (drive)->dvd_r = 0;
+ CDROM_CONFIG_FLAGS (drive)->dvd_rw = 0;
X CDROM_CONFIG_FLAGS (drive)->no_eject = 1;
X CDROM_CONFIG_FLAGS (drive)->supp_disc_present = 0;
X
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/block/ide-cd.h linux/drivers/block/ide-cd.h
--- v2.2.0-pre8/linux/drivers/block/ide-cd.h Tue Jan 19 11:32:51 1999
+++ linux/drivers/block/ide-cd.h Wed Jan 20 16:21:45 1999
@@ -128,6 +128,10 @@
X __u8 is_changer : 1; /* Drive is a changer. */
X __u8 cd_r : 1; /* Drive can write to CD-R media . */
X __u8 cd_rw : 1; /* Drive can write to CD-R/W media . */
+ __u8 dvd : 1; /* Drive is a DVD-ROM */
+ __u8 dvd_r : 1; /* Drive can write DVD-RAM */
+ __u8 dvd_rw : 1; /* Drive can write DVD-R/W */
+ __u8 test_write : 1; /* Drive can fake writes */
X __u8 supp_disc_present: 1; /* Changer can report exact contents
X of slots. */
X __u8 limit_nframes : 1; /* Drive does not provide data in
@@ -294,7 +298,13 @@
X byte page_length;
X
X #if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved2 : 5;
+ __u8 reserved2 : 2;
+ /* Drive supports reading of DVD-RAM discs */
+ __u8 dvd_ram_read : 1;
+ /* Drive supports reading of DVD-R discs */
+ __u8 dvd_r_read : 1;
+ /* Drive supports reading of DVD-ROM discs */
+ __u8 dvd_rom : 1;
X /* Drive supports reading CD-R discs with addressing method 2 */
X __u8 method2 : 1; /* reserved in 1.2 */
X /* Drive can read from CD-R/W (CD-E) discs (orange book, part III) */
@@ -303,28 +313,48 @@
X __u8 cd_r_read : 1; /* reserved in 1.2 */
X #elif defined(__LITTLE_ENDIAN_BITFIELD)
X /* Drive supports read from CD-R discs (orange book, part II) */
- __u8 cd_r_read : 1; /* reserved in 1.2 */
+ __u8 cd_r_read : 1; /* reserved in 1.2 */
X /* Drive can read from CD-R/W (CD-E) discs (orange book, part III) */
- __u8 cd_rw_read : 1; /* reserved in 1.2 */
+ __u8 cd_rw_read : 1; /* reserved in 1.2 */
X /* Drive supports reading CD-R discs with addressing method 2 */
- __u8 reserved2 : 5;
+ __u8 method2 : 1;
+ /* Drive supports reading of DVD-ROM discs */
+ __u8 dvd_rom : 1;
+ /* Drive supports reading of DVD-R discs */
+ __u8 dvd_r_read : 1;
+ /* Drive supports reading of DVD-RAM discs */
+ __u8 dvd_ram_read : 1;
+ __u8 reserved2 : 2;
X #else
X #error "Please fix <asm/byteorder.h>"
X #endif
X
X #if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved3 : 6;
+ __u8 reserved3 : 2;
+ /* Drive can fake writes */
+ __u8 test_write : 1;
+ __u8 reserved3a : 1;
+ /* Drive can write DVD-R discs */
+ __u8 dvd_r_write : 1;
+ /* Drive can write DVD-RAM discs */
+ __u8 dvd_ram_write : 1;
X /* Drive can write to CD-R/W (CD-E) discs (orange book, part III) */
X __u8 cd_rw_write : 1; /* reserved in 1.2 */
X /* Drive supports write to CD-R discs (orange book, part II) */
X __u8 cd_r_write : 1; /* reserved in 1.2 */
X #elif defined(__LITTLE_ENDIAN_BITFIELD)
-
X /* Drive can write to CD-R discs (orange book, part II) */
- __u8 cd_r_write : 1; /* reserved in 1.2 */
+ __u8 cd_r_write : 1; /* reserved in 1.2 */
X /* Drive can write to CD-R/W (CD-E) discs (orange book, part III) */
- __u8 cd_rw_write : 1; /* reserved in 1.2 */
- __u8 reserved3 : 6;
+ __u8 cd_rw_write : 1; /* reserved in 1.2 */
+ /* Drive can write DVD-RAM discs */
+ __u8 dvd_ram_write : 1;
+ /* Drive can write DVD-R discs */
+ __u8 dvd_r_write : 1;
+ __u8 reserved3a : 1;
+ /* Drive can fake writes */
+ __u8 test_write : 1;
+ __u8 reserved3 : 2;
X #else
X #error "Please fix <asm/byteorder.h>"
X #endif
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/cdrom/mcdx.h linux/drivers/cdrom/mcdx.h
--- v2.2.0-pre8/linux/drivers/cdrom/mcdx.h Tue Dec 2 11:41:44 1997
+++ linux/drivers/cdrom/mcdx.h Wed Jan 20 10:20:16 1999
@@ -77,7 +77,6 @@
X /* *** make the following line uncommented, if you're sure,
X * *** all configuration is done */
X /* #define I_WAS_HERE */
-#define I_WAS_HERE /* delete this line, it's for heiko only */
X
X /* The name of the device */
X #define MCDX "mcdx"
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/char/console.c linux/drivers/char/console.c
--- v2.2.0-pre8/linux/drivers/char/console.c Fri Jan 8 22:36:05 1999
+++ linux/drivers/char/console.c Tue Jan 19 10:10:23 1999
@@ -1221,6 +1221,8 @@
X break;
X case 8: /* store colors as defaults */
X def_color = attr;
+ if (hi_font_mask == 0x100)
+ def_color >>= 1;
X default_attr(currcons);
X update_attr(currcons);
X break;
@@ -1894,7 +1896,7 @@
X if (decim)
X insert_char(currcons, 1);
X scr_writew(himask ?
- ((attr & ~himask) << 8) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+ ((attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
X (attr << 8) + tc,
X (u16 *) pos);
X if (DO_UPDATE && draw_x < 0) {
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v2.2.0-pre8/linux/drivers/char/cyclades.c Thu Jan 7 15:11:36 1999
+++ linux/drivers/char/cyclades.c Wed Jan 20 13:26:20 1999
@@ -1,7 +1,7 @@
X #define BLOCKMOVE
X #define Z_WAKE
X static char rcsid[] =
-"$Revision: 2.2.1.9 $$Date: 1998/12/30 18:18:30 $";
+"$Revision: 2.2.1.10 $$Date: 1999/01/20 16:14:29 $";
X
X /*
X * linux/drivers/char/cyclades.c
@@ -31,6 +31,10 @@
X * void cleanup_module(void);
X *
X * $Log: cyclades.c,v $
+ * Revision 2.2.1.10 1999/01/20 16:14:29 ivan
+ * Removed all unnecessary page-alignement operations in ioremap calls
+ * (ioremap is currently safe for these operations).
+ *
X * Revision 2.2.1.9 1998/12/30 18:18:30 ivan
X * Changed access to PLX PCI bridge registers from I/O to MMIO, in
X * order to make PLX9050-based boards work with certain motherboards.
@@ -4461,8 +4465,7 @@
X /* probe for CD1400... */
X
X #if !defined(__alpha__)
- cy_isa_address = ioremap((unsigned int)cy_isa_address,
- CyISA_Ywin);
+ cy_isa_address = ioremap((ulong)cy_isa_address, CyISA_Ywin);
X #endif
X cy_isa_nchan = CyPORTS_PER_CHIP *
X cyy_init_card(cy_isa_address,0);
@@ -4583,11 +4586,11 @@
X pdev->bus->number, pdev->devfn);
X printk("rev_id=%d) IRQ%d\n",
X cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclom-Y/PCI:found winaddr=0x%lx ioaddr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr1);
+ printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
+ (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
X #endif
- cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
- cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
+ cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
+ cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
X
X #if defined(__alpha__)
X if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
@@ -4595,21 +4598,21 @@
X pdev->bus->number, pdev->devfn);
X printk("rev_id=%d) IRQ%d\n",
X cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclom-Y/PCI:found winaddr=0x%lx ioaddr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr1);
+ printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
+ (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
X printk("Cyclom-Y/PCI not supported for low addresses in "
X "Alpha systems.\n");
X i--;
X continue;
X }
X #else
- cy_pci_addr0 = (ulong) ioremap(cy_pci_addr0, CyPCI_Yctl);
- cy_pci_addr2 = (ulong) ioremap(cy_pci_addr2, CyPCI_Ywin);
+ cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Yctl);
+ cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Ywin);
X #endif
X
X #ifdef CY_PCI_DEBUG
- printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ioaddr=0x%lx\n",
- (u_long)cy_pci_addr2, (u_long)cy_pci_addr1);
+ printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
+ (u_long)cy_pci_addr2, (u_long)cy_pci_addr0);
X #endif
X cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP *
X cyy_init_card((volatile ucchar *)cy_pci_addr2, 1));
@@ -4708,20 +4711,14 @@
X #endif
X cy_pci_addr0 &= PCI_BASE_ADDRESS_MEM_MASK;
X #if !defined(__alpha__)
- cy_pci_addr0 = (unsigned int) ioremap(
- cy_pci_addr0 & PAGE_MASK,
- PAGE_ALIGN(CyPCI_Zctl))
- + (cy_pci_addr0 & (PAGE_SIZE-1));
+ cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Zctl);
X #endif
X mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *)
X cy_pci_addr0)->mail_box_0);
X cy_pci_addr2 &= PCI_BASE_ADDRESS_MEM_MASK;
X if (mailbox == ZE_V1) {
X #if !defined(__alpha__)
- cy_pci_addr2 = (unsigned int) ioremap(
- cy_pci_addr2 & PAGE_MASK,
- PAGE_ALIGN(CyPCI_Ze_win))
- + (cy_pci_addr2 & (PAGE_SIZE-1));
+ cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Ze_win);
X #endif
X if (ZeIndex == NR_CARDS) {
X printk("Cyclades-Ze/PCI found at 0x%lx ",
@@ -4737,10 +4734,7 @@
X continue;
X } else {
X #if !defined(__alpha__)
- cy_pci_addr2 = (unsigned int) ioremap(
- cy_pci_addr2 & PAGE_MASK,
- PAGE_ALIGN(CyPCI_Zwin))
- + (cy_pci_addr2 & (PAGE_SIZE-1));
+ cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Zwin);
X #endif
X }
X
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.2.0-pre8/linux/drivers/char/mem.c Thu Jan 7 15:11:36 1999
+++ linux/drivers/char/mem.c Wed Jan 20 10:24:57 1999
@@ -4,20 +4,13 @@
X * Copyright (C) 1991, 1992 Linus Torvalds
X */
X
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/tty.h>
+#include <linux/mm.h>
X #include <linux/miscdevice.h>
X #include <linux/tpqic02.h>
X #include <linux/ftape.h>
X #include <linux/malloc.h>
X #include <linux/vmalloc.h>
X #include <linux/mman.h>
-#include <linux/mm.h>
X #include <linux/random.h>
X #include <linux/init.h>
X #include <linux/joystick.h>
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
--- v2.2.0-pre8/linux/drivers/char/pc_keyb.c Tue Jan 19 11:32:51 1999
+++ linux/drivers/char/pc_keyb.c Wed Jan 20 13:25:29 1999
@@ -744,7 +744,7 @@
X
X if (status & KBD_STAT_OBF) {
X val = inb(KBD_DATA_REG);
- if (val == 0x5a && (status & KBD_STAT_MOUSE_OBF)) {
+ if (status & KBD_STAT_MOUSE_OBF) {
X printk(KERN_INFO "Detected PS/2 Mouse Port.\n");
X retval = 1;
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/char/tty_ioctl.c linux/drivers/char/tty_ioctl.c
--- v2.2.0-pre8/linux/drivers/char/tty_ioctl.c Tue Dec 22 14:16:55 1998
+++ linux/drivers/char/tty_ioctl.c Tue Jan 19 10:12:05 1999
@@ -209,11 +209,12 @@
X {
X int flags = 0;
X
- if (!(tty->termios->c_lflag & ICANON))
+ if (!(tty->termios->c_lflag & ICANON)) {
X if (tty->termios->c_lflag & ISIG)
X flags |= 0x02; /* cbreak */
X else
X flags |= 0x20; /* raw */
+ }
X if (tty->termios->c_lflag & ECHO)
X flags |= 0x08; /* echo */
X if (tty->termios->c_oflag & OPOST)
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/char/videodev.c linux/drivers/char/videodev.c
--- v2.2.0-pre8/linux/drivers/char/videodev.c Tue Jan 19 11:32:51 1999
+++ linux/drivers/char/videodev.c Tue Jan 19 13:49:12 1999
@@ -15,6 +15,7 @@


X */
X
X #include <linux/config.h>

+#include <linux/version.h>
X #include <linux/module.h>
X #include <linux/types.h>
X #include <linux/kernel.h>
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- v2.2.0-pre8/linux/drivers/isdn/isdn_common.c Thu Aug 27 19:56:29 1998
+++ linux/drivers/isdn/isdn_common.c Tue Jan 19 11:06:52 1999
@@ -20,6 +20,10 @@
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
+ * Note: This file differs from the corresponding revision as present in the
+ * isdn4linux CVS repository because some later bug fixes have been extracted
+ * from the repository and merged into this file. -- Henner Eisen
+ *
X * $Log: isdn_common.c,v $
X * Revision 1.55 1998/02/23 23:35:32 fritz
X * Eliminated some compiler warnings.
@@ -770,9 +774,18 @@
X /*
X * isdn_readbchan() tries to get data from the read-queue.
X * It MUST be called with interrupts off.
+ *
+ * Be aware that this is not an atomic operation when sleep != 0, even though
+ * interrupts are turned off! Well, like that we are currently only called
+ * on behalf of a read system call on raw device files (which are documented
+ * to be dangerous and for for debugging purpose only). The inode semaphore
+ * takes care that this is not called for the same minor device number while
+ * we are sleeping, but access is not serialized against simultaneous read()
+ * from the corresponding ttyI device. Can other ugly events, like changes
+ * of the mapping (di,ch)<->minor, happen during the sleep? --he
X */
X int
-isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, int user)
+isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, struct wait_queue **sleep)
X {
X int left;
X int count;
@@ -785,8 +798,8 @@
X if (!dev->drv[di])
X return 0;
X if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) {
- if (user)
- interruptible_sleep_on(&dev->drv[di]->rcv_waitq[channel]);
+ if (sleep)
+ interruptible_sleep_on(sleep);
X else
X return 0;
X }
@@ -808,16 +821,10 @@
X count_pull = count_put = 0;
X while ((count_pull < skb->len) && (left-- > 0)) {
X if (dev->drv[di]->DLEflag & DLEmask) {
- if (user)
- put_user(DLE, cp++);
- else
- *cp++ = DLE;
+ *cp++ = DLE;
X dev->drv[di]->DLEflag &= ~DLEmask;
X } else {
- if (user)
- put_user(*p, cp++);
- else
- *cp++ = *p;
+ *cp++ = *p;
X if (*p == DLE) {
X dev->drv[di]->DLEflag |= DLEmask;
X (ISDN_AUDIO_SKB_DLECOUNT(skb))--;
@@ -838,10 +845,7 @@
X dflag = 0;
X }
X count_put = count_pull;
- if (user)
- copy_to_user(cp, skb->data, count_put);
- else
- memcpy(cp, skb->data, count_put);
+ memcpy(cp, skb->data, count_put);
X cp += count_put;
X left -= count_put;
X #ifdef CONFIG_ISDN_AUDIO
@@ -966,12 +970,12 @@
X ulong flags;
X int drvidx;
X int chidx;
+ char *p;
X
X if (off != &file->f_pos)
X return -ESPIPE;
X
X if (minor == ISDN_MINOR_STATUS) {
- char *p;
X if (!file->private_data) {
X if (file->f_flags & O_NONBLOCK)
X return -EAGAIN;
@@ -996,11 +1000,15 @@
X if (!dev->drv[drvidx]->running)
X return -ENODEV;
X chidx = isdn_minor2chan(minor);
+ if( ! (p = kmalloc(count,GFP_KERNEL)) ) return -ENOMEM;
X save_flags(flags);
X cli();
- len = isdn_readbchan(drvidx, chidx, buf, 0, count, 1);
+ len = isdn_readbchan(drvidx, chidx, p, 0, count,
+ &dev->drv[drvidx]->rcv_waitq[chidx]);
X *off += len;
X restore_flags(flags);
+ if( copy_to_user(buf,p,len) ) len = -EFAULT;
+ kfree(p);
X return len;
X }
X if (minor <= ISDN_MINOR_CTRLMAX) {
@@ -1124,6 +1132,11 @@
X return POLLERR;
X }
X
+/*
+ * This accesses user space with interrupts off, but is not needed by
+ * any of the isdn4k-util programs anyway. Thus, in contrast to your
+ * first impression after looking at the code, fixing is trival!*/
+#if 0
X static int
X isdn_set_allcfg(char *src)
X {
@@ -1135,8 +1148,7 @@
X
X if ((ret = isdn_net_rmall()))
X return ret;
- if ((ret = copy_from_user((char *) &i, src, sizeof(int))))
- return ret;
+ if (copy_from_user((char *) &i, src, sizeof(int))) return -EFAULT;
X save_flags(flags);
X cli();
X src += sizeof(int);
@@ -1144,9 +1156,9 @@
X int phone_len;
X int out_flag;
X
- if ((ret = copy_from_user((char *) &cfg, src, sizeof(cfg)))) {
+ if (copy_from_user((char *) &cfg, src, sizeof(cfg))) {
X restore_flags(flags);
- return ret;
+ return -EFAULT;
X }
X src += sizeof(cfg);
X if (!isdn_net_new(cfg.name, NULL)) {
@@ -1256,6 +1268,7 @@
X restore_flags(flags);


X return 0;
X }
+#endif
X

X static int
X isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
@@ -1319,59 +1332,83 @@
X return 0;
X }
X if (minor <= ISDN_MINOR_CTRLMAX) {
+/*
+ * isdn net devices manage lots of configuration variables as linked lists.
+ * Those lists must only be manipulated from user space. Some of the ioctl's
+ * service routines access user space and are not atomic. Therefor, ioctl's
+ * manipulating the lists and ioctl's sleeping while accessing the lists
+ * are serialized by means of a semaphore.
+ */
X switch (cmd) {
X #ifdef CONFIG_NETDEVICES
X case IIOCNETAIF:
X /* Add a network-interface */
X if (arg) {
- if ((ret = copy_from_user(name, (char *) arg, sizeof(name))))
- return ret;
+ if (copy_from_user(name, (char *) arg, sizeof(name)))
+ return -EFAULT;
X s = name;
- } else
+ } else {
X s = NULL;
+ }
+ ret = down_interruptible(&dev->sem);
+ if( ret ) return ret;
X if ((s = isdn_net_new(s, NULL))) {
- if ((ret = copy_to_user((char *) arg, s, strlen(s) + 1)))
- return ret;
- return 0;
+ if (copy_to_user((char *) arg, s, strlen(s) + 1)){
+ ret = -EFAULT;
+ } else {
+ ret = 0;
+ }
X } else
- return -ENODEV;
+ ret = -ENODEV;
+ up(&dev->sem);
+ return ret;
X case IIOCNETASL:
X /* Add a slave to a network-interface */
X if (arg) {
- if ((ret = copy_from_user(bname, (char *) arg, sizeof(bname) - 1)))
- return ret;
+ if (copy_from_user(bname, (char *) arg, sizeof(bname) - 1))
+ return -EFAULT;
X } else
X return -EINVAL;
+ ret = down_interruptible(&dev->sem);
+ if( ret ) return ret;
X if ((s = isdn_net_newslave(bname))) {
- if ((ret = copy_to_user((char *) arg, s, strlen(s) + 1)))
- return ret;
- return 0;
+ if (copy_to_user((char *) arg, s, strlen(s) + 1)){
+ ret = -EFAULT;
+ } else {
+ ret = 0;
+ }
X } else
- return -ENODEV;
+ ret = -ENODEV;
+ up(&dev->sem);
+ return ret;
X case IIOCNETDIF:
X /* Delete a network-interface */
X if (arg) {
- if ((ret = copy_from_user(name, (char *) arg, sizeof(name))))
- return ret;
- return isdn_net_rm(name);
+ if (copy_from_user(name, (char *) arg, sizeof(name)))
+ return -EFAULT;
+ ret = down_interruptible(&dev->sem);
+ if( ret ) return ret;
+ ret = isdn_net_rm(name);
+ up(&dev->sem);
+ return ret;
X } else
X return -EINVAL;
X case IIOCNETSCF:
X /* Set configurable parameters of a network-interface */
X if (arg) {
- if ((ret = copy_from_user((char *) &cfg, (char *) arg, sizeof(cfg))))
- return ret;
+ if (copy_from_user((char *) &cfg, (char *) arg, sizeof(cfg)))
+ return -EFAULT;
X return isdn_net_setcfg(&cfg);
X } else
X return -EINVAL;
X case IIOCNETGCF:
X /* Get configurable parameters of a network-interface */
X if (arg) {
- if ((ret = copy_from_user((char *) &cfg, (char *) arg, sizeof(cfg))))
- return ret;
+ if (copy_from_user((char *) &cfg, (char *) arg, sizeof(cfg)))
+ return -EFAULT;
X if (!(ret = isdn_net_getcfg(&cfg))) {
- if ((ret = copy_to_user((char *) arg, (char *) &cfg, sizeof(cfg))))
- return ret;
+ if (copy_to_user((char *) arg, (char *) &cfg, sizeof(cfg)))
+ return -EFAULT;
X }
X return ret;
X } else
@@ -1379,32 +1416,44 @@
X case IIOCNETANM:
X /* Add a phone-number to a network-interface */
X if (arg) {
- if ((ret = copy_from_user((char *) &phone, (char *) arg, sizeof(phone))))
- return ret;
- return isdn_net_addphone(&phone);
+ if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone)))
+ return -EFAULT;
+ ret = down_interruptible(&dev->sem);
+ if( ret ) return ret;
+ ret = isdn_net_addphone(&phone);
+ up(&dev->sem);
+ return ret;
X } else
X return -EINVAL;
X case IIOCNETGNM:
X /* Get list of phone-numbers of a network-interface */
X if (arg) {
- if ((ret = copy_from_user((char *) &phone, (char *) arg, sizeof(phone))))
- return ret;
- return isdn_net_getphones(&phone, (char *) arg);
+ if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone)))
+ return -EFAULT;
+ ret = down_interruptible(&dev->sem);
+ if( ret ) return ret;
+ ret = isdn_net_getphones(&phone, (char *) arg);
+ up(&dev->sem);
+ return ret;
X } else
X return -EINVAL;
X case IIOCNETDNM:
X /* Delete a phone-number of a network-interface */
X if (arg) {
- if ((ret = copy_from_user((char *) &phone, (char *) arg, sizeof(phone))))
- return ret;
- return isdn_net_delphone(&phone);
+ if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone)))
+ return -EFAULT;
+ ret = down_interruptible(&dev->sem);
+ if( ret ) return ret;
+ ret = isdn_net_delphone(&phone);
+ up(&dev->sem);
+ return ret;
X } else
X return -EINVAL;
X case IIOCNETDIL:
X /* Force dialing of a network-interface */
X if (arg) {
- if ((ret = copy_from_user(name, (char *) arg, sizeof(name))))
- return ret;
+ if (copy_from_user(name, (char *) arg, sizeof(name)))
+ return -EFAULT;
X return isdn_net_force_dial(name);
X } else
X return -EINVAL;
@@ -1412,22 +1461,22 @@
X case IIOCNETALN:
X if (!arg)
X return -EINVAL;
- if ((ret = copy_from_user(name, (char *) arg, sizeof(name))))
- return ret;
+ if (copy_from_user(name, (char *) arg, sizeof(name)))
+ return -EFAULT;
X return isdn_ppp_dial_slave(name);
X case IIOCNETDLN:
X if (!arg)
X return -EINVAL;
- if ((ret = copy_from_user(name, (char *) arg, sizeof(name))))
- return ret;
+ if (copy_from_user(name, (char *) arg, sizeof(name)))
+ return -EFAULT;
X return isdn_ppp_hangup_slave(name);
X #endif
X case IIOCNETHUP:
X /* Force hangup of a network-interface */
X if (!arg)
X return -EINVAL;
- if ((ret = copy_from_user(name, (char *) arg, sizeof(name))))
- return ret;
+ if (copy_from_user(name, (char *) arg, sizeof(name)))
+ return -EFAULT;
X return isdn_net_force_hangup(name);
X break;
X #endif /* CONFIG_NETDEVICES */
@@ -1448,9 +1497,9 @@
X if (arg) {
X int i;
X char *p;
- if ((ret = copy_from_user((char *) &iocts, (char *) arg,
- sizeof(isdn_ioctl_struct))))
- return ret;
+ if (copy_from_user((char *) &iocts, (char *) arg,
+ sizeof(isdn_ioctl_struct)))
+ return -EFAULT;
X if (strlen(iocts.drvid)) {
X if ((p = strchr(iocts.drvid, ',')))
X *p = 0;
@@ -1466,6 +1515,7 @@
X return -ENODEV;
X dev->drv[drvidx]->reject_bus = iocts.arg;
X return 0;
+#if 0
X case IIOCGETSET:
X /* Get complete setup (all network-interfaces and profile-
X settings of all tty-devices */
@@ -1482,6 +1532,7 @@
X else
X return -EINVAL;
X break;
+#endif
X case IIOCSIGPRF:
X dev->profd = current;
X return 0;
@@ -1522,12 +1573,12 @@
X return ret;
X
X for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
- if ((ret = copy_from_user(dev->mdm.info[i].emu.profile, p,
- ISDN_MODEM_ANZREG)))
- return ret;
+ if (copy_from_user(dev->mdm.info[i].emu.profile, p,
+ ISDN_MODEM_ANZREG))
+ return -EFAULT;
X p += ISDN_MODEM_ANZREG;
- if ((ret = copy_from_user(dev->mdm.info[i].emu.pmsn, p, ISDN_MSNLEN)))
- return ret;
+ if (copy_from_user(dev->mdm.info[i].emu.pmsn, p, ISDN_MSNLEN))
+ return -EFAULT;
X p += ISDN_MSNLEN;
X }
X return 0;
@@ -1539,10 +1590,10 @@
X /* Set/Get MSN->EAZ-Mapping for a driver */
X if (arg) {
X
- if ((ret = copy_from_user((char *) &iocts,
+ if (copy_from_user((char *) &iocts,
X (char *) arg,
- sizeof(isdn_ioctl_struct))))
- return ret;
+ sizeof(isdn_ioctl_struct)))
+ return -EFAULT;
X if (strlen(iocts.drvid)) {
X drvidx = -1;
X for (i = 0; i < ISDN_MAX_DRIVERS; i++)
@@ -1591,8 +1642,8 @@
X strlen(dev->drv[drvidx]->msn2eaz[i]) ?
X dev->drv[drvidx]->msn2eaz[i] : "-",
X (i < 9) ? "," : "\0");
- if ((ret = copy_to_user(p, bname, strlen(bname) + 1)))
- return ret;
+ if (copy_to_user(p, bname, strlen(bname) + 1))
+ return -EFAULT;
X p += strlen(bname);
X }
X }
@@ -1601,8 +1652,8 @@
X return -EINVAL;
X case IIOCDBGVAR:
X if (arg) {
- if ((ret = copy_to_user((char *) arg, (char *) &dev, sizeof(ulong))))
- return ret;
+ if (copy_to_user((char *) arg, (char *) &dev, sizeof(ulong)))
+ return -EFAULT;
X return 0;
X } else
X return -EINVAL;
@@ -1615,8 +1666,8 @@
X if (arg) {
X int i;
X char *p;
- if ((ret = copy_from_user((char *) &iocts, (char *) arg, sizeof(isdn_ioctl_struct))))
- return ret;
+ if (copy_from_user((char *) &iocts, (char *) arg, sizeof(isdn_ioctl_struct)))
+ return -EFAULT;
X if (strlen(iocts.drvid)) {
X if ((p = strchr(iocts.drvid, ',')))
X *p = 0;
@@ -1639,7 +1690,7 @@
X memcpy(c.parm.num, (char *) &iocts.arg, sizeof(ulong));
X ret = isdn_command(&c);
X memcpy((char *) &iocts.arg, c.parm.num, sizeof(ulong));
- if ((copy_to_user((char *) arg, &iocts, sizeof(isdn_ioctl_struct))))
+ if (copy_to_user((char *) arg, &iocts, sizeof(isdn_ioctl_struct)))
X return -EFAULT;
X return ret;
X } else
@@ -2164,6 +2215,7 @@
X memset((char *) dev, 0, sizeof(isdn_dev));
X init_timer(&dev->timer);
X dev->timer.function = isdn_timer_funct;
+ dev->sem = MUTEX;
X for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
X dev->drvmap[i] = -1;
X dev->chanmap[i] = -1;
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/isdn/isdn_common.h linux/drivers/isdn/isdn_common.h
--- v2.2.0-pre8/linux/drivers/isdn/isdn_common.h Wed Apr 1 20:11:51 1998
+++ linux/drivers/isdn/isdn_common.h Tue Jan 19 11:06:52 1999
@@ -20,6 +20,10 @@
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
+ * Note: This file differs from the corresponding revision as present in the
+ * isdn4linux CVS repository because some later bug fixes have been extracted
+ * from the repository and merged into this file. -- Henner Eisen
+ *
X * $Log: isdn_common.h,v $
X * Revision 1.9 1998/02/20 17:19:01 fritz
X * Added common stub for sending commands to lowlevel.
@@ -86,7 +90,7 @@
X extern void isdn_timer_ctrl(int tf, int onoff);
X extern void isdn_unexclusive_channel(int di, int ch);
X extern int isdn_getnum(char **);
-extern int isdn_readbchan(int, int, u_char *, u_char *, int, int);
+extern int isdn_readbchan(int, int, u_char *, u_char *, int, struct wait_queue**);
X extern int isdn_get_free_channel(int, int, int, int, int);
X extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
X extern int register_isdn(isdn_if * i);
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- v2.2.0-pre8/linux/drivers/isdn/isdn_net.c Mon Oct 5 13:13:39 1998
+++ linux/drivers/isdn/isdn_net.c Tue Jan 19 11:06:52 1999
@@ -20,6 +20,10 @@
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
+ * Note: This file differs from the corresponding revision as present in the
+ * isdn4linux CVS repository because some later bug fixes have been extracted
+ * from the repository and merged into this file. -- Henner Eisen
+ *
X * $Log: isdn_net.c,v $
X * Revision 1.55 1998/02/23 19:38:22 fritz
X * Corrected check for modified feature-flags.
@@ -243,7 +247,7 @@
X #include <linux/module.h>
X #include <linux/isdn.h>
X #include <net/arp.h>
-#include <net/icmp.h>
+#include <net/dst.h>
X #ifndef DEV_NUMBUFFS
X #include <net/pkt_sched.h>
X #endif
@@ -277,9 +281,18 @@
X static void
X isdn_net_unreachable(struct device *dev, struct sk_buff *skb, char *reason)
X {
- printk(KERN_DEBUG "isdn_net: %s: %s, send ICMP\n",
- dev->name, reason);
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
+
+ if(skb) {
+
+ u_short proto = ntohs(skb->protocol);
+
+ printk(KERN_DEBUG "isdn_net: %s: %s, signalling dst_link_failure %s\n",
+ dev->name,
+ (reason != NULL) ? reason : "unknown",
+ (proto != ETH_P_IP) ? "Protocol != ETH_P_IP" : "");
+
+ dst_link_failure(skb);
+ }
X }
X
X static void
@@ -610,6 +623,13 @@
X
X if (!(isdn_net_xmit(&p->dev, lp, lp->first_skb)))
X lp->first_skb = NULL;
+ } else {
+ /*
+ * dev.tbusy is usually cleared implicitly by isdn_net_xmit(,,lp->first_skb).
+ * With an empty lp->first_skb, we need to do this ourselves
+ */
+ lp->netdev->dev.tbusy = 0;
+ mark_bh(NET_BH);
X }
X return 1;
X }
@@ -2696,7 +2716,8 @@
X }
X
X /*
- * Return a string of all phone-numbers of an interface.
+ * Copy a string of all phone-numbers of an interface to user space.
+ * This might sleep and must be called with the isdn semaphore down.
X */
X int
X isdn_net_getphones(isdn_net_ioctl_phone * phone, char *phones)
@@ -2706,22 +2727,17 @@
X int more = 0;
X int count = 0;
X isdn_net_phone *n;
- int flags;
- int ret;
X
X if (!p)
X return -ENODEV;
- save_flags(flags);
- cli();
X inout &= 1;
X for (n = p->local->phone[inout]; n; n = n->next) {
X if (more) {
X put_user(' ', phones++);
X count++;
X }
- if ((ret = copy_to_user(phones, n->num, strlen(n->num) + 1))) {
- restore_flags(flags);
- return ret;
+ if (copy_to_user(phones, n->num, strlen(n->num) + 1)) {
+ return -EFAULT;
X }
X phones += strlen(n->num);
X count += strlen(n->num);
@@ -2729,7 +2745,6 @@
X }
X put_user(0, phones);
X count++;
- restore_flags(flags);
X return count;
X }
X
@@ -2760,6 +2775,7 @@
X else
X p->local->phone[inout] = n->next;
X kfree(n);
+ restore_flags(flags);
X return 0;
X }
X m = n;
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- v2.2.0-pre8/linux/drivers/isdn/isdn_ppp.c Wed Apr 1 20:11:51 1998
+++ linux/drivers/isdn/isdn_ppp.c Tue Jan 19 11:06:52 1999
@@ -18,6 +18,10 @@
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
+ * Note: This file differs from the corresponding revision as present in the
+ * isdn4linux CVS repository because some later bug fixes have been extracted
+ * from the repository and merged into this file. -- Henner Eisen
+ *
X * $Log: isdn_ppp.c,v $
X * Revision 1.33 1998/02/20 17:11:54 fritz
X * Changes for recent kernels.
@@ -500,11 +504,10 @@
X static int
X get_arg(void *b, void *val, int len)
X {
- int r;
X if (len <= 0)
X len = sizeof(unsigned long);
- if ((r = copy_from_user((void *) val, b, len)))


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 05'
echo 'File patch-2.2.0-pre9 is continued in part 06'
echo 06 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part06

#!/bin/sh
# this is part 06 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 06; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

- return r;
+ if (copy_from_user((void *) val, b, len))


+ return -EFAULT;
X return 0;
X }

X
@@ -514,13 +517,12 @@
X static int
X set_arg(void *b, unsigned long val, void *str)
X {
- int r;
X if (!str) {
- if ((r = copy_to_user(b, (void *) &val, 4)))
- return r;
+ if (copy_to_user(b, (void *) &val, 4))
+ return -EFAULT;
X } else {
- if ((r = copy_to_user(b, str, val)))
- return r;
+ if (copy_to_user(b, str, val))
+ return -EFAULT;
X }
X return 0;
X }
@@ -1851,13 +1853,14 @@
X }
X #endif
X }
- return copy_to_user(res, &t, sizeof(struct ppp_stats));
+ if( copy_to_user(res, &t, sizeof(struct ppp_stats))) return -EFAULT;
+ return 0;
X }
X
X int
X isdn_ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
X {
- int error;
+ int error=0;
X char *r;
X int len;
X isdn_net_local *lp = (isdn_net_local *) dev->priv;
@@ -1873,7 +1876,7 @@
X case SIOCGPPPVER:
X r = (char *) ifr->ifr_ifru.ifru_data;
X len = strlen(PPP_VERSION) + 1;
- error = copy_to_user(r, PPP_VERSION, len);
+ if(copy_to_user(r, PPP_VERSION, len)) error = -EFAULT;
X break;
X case SIOCGPPPSTATS:
X error = isdn_ppp_dev_ioctl_stats(lp->ppp_slot, ifr, dev);
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/misc/parport_ieee1284.c linux/drivers/misc/parport_ieee1284.c
--- v2.2.0-pre8/linux/drivers/misc/parport_ieee1284.c Sun Nov 8 14:02:59 1998
+++ linux/drivers/misc/parport_ieee1284.c Wed Jan 20 13:29:18 1999
@@ -47,8 +47,12 @@
X */
X int parport_ieee1284_nibble_mode_ok(struct parport *port, unsigned char mode)
X {
+ /* make sure it's a valid state, set nStrobe & nAutoFeed high */
+ parport_write_control(port, (parport_read_control(port) \
+ & ~1 ) & ~2);
+ udelay(1);
X parport_write_data(port, mode);
- udelay(500);
+ udelay(1);
X /* nSelectIn high, nAutoFd low */
X parport_write_control(port, (parport_read_control(port) & ~8) | 2);
X if (parport_wait_peripheral(port, 0x78, 0x38)) {
@@ -58,11 +62,12 @@
X }
X /* nStrobe low */
X parport_write_control(port, parport_read_control(port) | 1);
- udelay(5); /* Strobe wait */
- /* nStrobe high */
- parport_write_control(port, parport_read_control(port) & ~1);
- udelay(5);
- /* nAutoFd low */
- parport_write_control(port, parport_read_control(port) & ~2);
- return (parport_wait_peripheral(port, 0x20, 0))?2:1;
+ udelay(1); /* Strobe wait */
+ /* nStrobe high, nAutoFeed low, last step before transferring
+ * reverse data */
+ parport_write_control(port, (parport_read_control(port) \
+ & ~1) & ~2);
+ udelay(1);
+ /* Data available? */
+ return (parport_wait_peripheral(port, 0x20, 0))?1:2;
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- v2.2.0-pre8/linux/drivers/net/3c59x.c Tue Jan 19 11:32:51 1999
+++ linux/drivers/net/3c59x.c Tue Jan 19 14:47:15 1999
@@ -1245,7 +1245,7 @@
X printk(KERN_DEBUG "%s: Media selection failed, now trying "
X "%s port.\n",
X dev->name, media_tbl[dev->if_port].name);
- next_tick = RUN_AT(media_tbl[dev->if_port].wait);
+ next_tick = media_tbl[dev->if_port].wait;
X }
X outw((media_status & ~(Media_10TP|Media_SQE)) |
X media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.2.0-pre8/linux/drivers/net/Config.in Tue Jan 19 11:32:51 1999
+++ linux/drivers/net/Config.in Tue Jan 19 10:13:13 1999
@@ -85,17 +85,15 @@
X fi
X bool 'Other ISA cards' CONFIG_NET_ISA
X if [ "$CONFIG_NET_ISA" = "y" ]; then
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700
- fi
+ tristate 'AT1700/1720 support' CONFIG_AT1700
X tristate 'Cabletron E21xx support' CONFIG_E2100
X tristate 'DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA
X tristate 'EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3
X tristate 'EtherExpress 16 support' CONFIG_EEXPRESS


X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then

X tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO
- tristate 'FMV-181/182/183/184 support' CONFIG_FMV18X
X fi
+ tristate 'FMV-181/182/183/184 support' CONFIG_FMV18X
X tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS
X tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN
X tristate 'HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/at1700.c linux/drivers/net/at1700.c
--- v2.2.0-pre8/linux/drivers/net/at1700.c Fri Jan 8 22:36:07 1999
+++ linux/drivers/net/at1700.c Tue Jan 19 10:51:24 1999
@@ -12,8 +12,12 @@
X Center of Excellence in Space Data and Information Sciences
X Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
X
- This is a device driver for the Allied Telesis AT1700, which is a
- straight-forward Fujitsu MB86965 implementation.
+ This is a device driver for the Allied Telesis AT1700, and
+ Fujitsu FMV-181/182/181A/182A/183/184/183A/184A, which are
+ straight-forward Fujitsu MB86965 implementations.
+
+ Modification for Fujitsu FMV-18X cards is done by Yutaka Tamiya
+ (ta...@flab.fujitsu.co.jp).
X
X Sources:
X The Fujitsu MB86965 datasheet.
@@ -81,7 +85,7 @@
X /*
X * MCA
X */
-
+#ifdef CONFIG_MCA
X static int at1700_ioaddr_pattern[] = {
X 0x00, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07
X };
@@ -94,6 +98,7 @@
X 0x00, 0x00, 0x00, 0x30, 0x70, 0xb0, 0x00, 0x00,
X 0x00, 0xf0, 0x34, 0x74, 0xb4, 0x00, 0x00, 0xf4, 0x00
X };
+#endif
X
X /* use 0 for production, 1 for verification, >2 for debug */
X #ifndef NET_DEBUG
@@ -109,6 +114,8 @@
X unsigned char mc_filter[8];
X uint jumpered:1; /* Set iff the board has jumper config. */
X uint tx_started:1; /* Packets are on the Tx queue. */
+ uint tx_queue_ready:1; /* Tx queue is ready to be sent. */
+ uint rx_started:1; /* Packets are Rxing. */
X uint invalid_irq:1;
X uchar tx_queue; /* Number of packet on the Tx queue. */
X char mca_slot; /* -1 means ISA */
@@ -129,10 +136,13 @@
X /* Run-time register bank 2 definitions. */
X #define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
X #define TX_START 10
+#define COL16CNTL 11 /* Controll Reg for 16 collisions */
X #define MODE13 13
X /* Configuration registers only on the '865A/B chips. */
X #define EEPROM_Ctrl 16
X #define EEPROM_Data 17
+#define CARDSTATUS 16 /* FMV-18x Card Status */
+#define CARDSTATUS1 17 /* FMV-18x Card Status */
X #define IOCONFIG 18 /* Either read the jumper, or move the I/O. */
X #define IOCONFIG1 19
X #define SAPROM 20 /* The station address PROM, if no EEPROM. */
@@ -214,9 +224,9 @@
X int at1700_probe1(struct device *dev, int ioaddr)
X {
X char fmv_irqmap[4] = {3, 7, 10, 15};
+ char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
X char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
X unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
- int l_i;
X int slot;
X
X /* Resetting the chip doesn't reset the ISA interface, so don't bother.
@@ -238,16 +248,17 @@
X /* redone for multi-card detection by ZP Gu (z...@castle.net) */
X /* now works as a module */
X
- if( MCA_bus ) {
+ if (MCA_bus) {
X int j;
+ int l_i;
X u_char pos3, pos4;
X
- for( j = 0; at1720_mca_adapters[j].name != NULL; j ++ ) {
+ for (j = 0; at1720_mca_adapters[j].name != NULL; j ++) {
X slot = 0;
- while( slot != MCA_NOTFOUND ) {
+ while (slot != MCA_NOTFOUND) {
X
X slot = mca_find_unused_adapter( at1720_mca_adapters[j].id, slot );
- if( slot == MCA_NOTFOUND ) break;
+ if (slot == MCA_NOTFOUND) break;
X
X /* if we get this far, an adapter has been detected and is
X enabled */
@@ -292,15 +303,16 @@
X && read_eeprom(ioaddr, 4) == 0x0000
X && (read_eeprom(ioaddr, 5) & 0xff00) == 0xF400)
X is_at1700 = 1;
- else if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] == ioaddr
- && inb(ioaddr + SAPROM ) == 0x00
+ else if (inb(ioaddr + SAPROM ) == 0x00
X && inb(ioaddr + SAPROM + 1) == 0x00
X && inb(ioaddr + SAPROM + 2) == 0x0e)
X is_fmv18x = 1;
X else
X return -ENODEV;
X
+#ifdef CONFIG_MCA
X found:
+#endif
X
X /* Reset the internal state machines. */
X outb(0, ioaddr + RESET);
@@ -312,24 +324,46 @@
X if (is_at1700)
X irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
X | (read_eeprom(ioaddr, 0)>>14)];
- else
- if (is_fmv18x)
+ else {
+ /* Check PnP mode for FMV-183/184/183A/184A. */
+ /* This PnP routine is very poor. IO and IRQ should be known. */
+ if (inb(ioaddr + CARDSTATUS1) & 0x20) {
+ irq = dev->irq;
+ for (i = 0; i < 8; i++) {
+ if (irq == fmv_irqmap_pnp[i])
+ break;
+ }
+ if (i == 8)
+ return -ENODEV;
+ } else {
+ if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr)
+ return -ENODEV;
X irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
-
+ }
+ }
+
X /* Grab the region so that we can find another board if the IRQ request
X fails. */
X request_region(ioaddr, AT1700_IO_EXTENT, dev->name);
X
- printk("%s: AT1700 found at %#3x, IRQ %d, address ", dev->name,
- ioaddr, irq);
+ printk("%s: %s found at %#3x, IRQ %d, address ", dev->name,
+ is_at1700 ? "AT1700" : "FMV-18X", ioaddr, irq);
X
X dev->base_addr = ioaddr;
X dev->irq = irq;
X
- for(i = 0; i < 3; i++) {
- unsigned short eeprom_val = read_eeprom(ioaddr, 4+i);
- printk("%04x", eeprom_val);
- ((unsigned short *)dev->dev_addr)[i] = ntohs(eeprom_val);
+ if (is_at1700) {
+ for(i = 0; i < 3; i++) {
+ unsigned short eeprom_val = read_eeprom(ioaddr, 4+i);
+ printk("%04x", eeprom_val);
+ ((unsigned short *)dev->dev_addr)[i] = ntohs(eeprom_val);
+ }
+ } else {
+ for(i = 0; i < 6; i++) {
+ unsigned char val = inb(ioaddr + SAPROM + i);
+ printk("%02x", val);
+ dev->dev_addr[i] = val;
+ }
X }
X
X /* The EEPROM word 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
@@ -340,32 +374,44 @@
X */
X {
X const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2"};
- ushort setup_value = read_eeprom(ioaddr, 12);
-
- dev->if_port = setup_value >> 8;
+ if (is_at1700) {
+ ushort setup_value = read_eeprom(ioaddr, 12);
+ dev->if_port = setup_value >> 8;
+ } else {
+ ushort setup_value = inb(ioaddr + CARDSTATUS);
+ switch (setup_value & 0x07) {
+ case 0x01: /* 10base5 */
+ case 0x02: /* 10base2 */
+ dev->if_port = 0x18; break;
+ case 0x04: /* 10baseT */
+ dev->if_port = 0x08; break;
+ default: /* auto-sense */
+ dev->if_port = 0x00; break;
+ }
+ }
X printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
X }
X
+ /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
+ bus access, two 4K Tx queues, and disabled Tx and Rx. */
+ outb(0xda, ioaddr + CONFIG_0);
+
X /* Set the station address in bank zero. */
- outb(0xe0, ioaddr + CONFIG_1);
+ outb(0x00, ioaddr + CONFIG_1);
X for (i = 0; i < 6; i++)
X outb(dev->dev_addr[i], ioaddr + 8 + i);
X
X /* Switch to bank 1 and set the multicast table to accept none. */
- outb(0xe4, ioaddr + CONFIG_1);
+ outb(0x04, ioaddr + CONFIG_1);
X for (i = 0; i < 8; i++)
X outb(0x00, ioaddr + 8 + i);
X
- /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
- bus access, two 4K Tx queues, and disabled Tx and Rx. */
- outb(0xda, ioaddr + CONFIG_0);
-
- /* Switch to bank 2 and lock our I/O address. */
- outb(0xe8, ioaddr + CONFIG_1);
- outb(dev->if_port, MODE13);
X
- /* Power-down the chip. Aren't we green! */
- outb(0x00, ioaddr + CONFIG_1);
+ /* Switch to bank 2 */
+ /* Lock our I/O address, and set manual processing mode for 16 collisions. */
+ outb(0x08, ioaddr + CONFIG_1);
+ outb(dev->if_port, ioaddr + MODE13);
+ outb(0x00, ioaddr + COL16CNTL);
X
X if (net_debug)
X printk(version);
@@ -456,35 +502,29 @@
X {
X struct net_local *lp = (struct net_local *)dev->priv;
X int ioaddr = dev->base_addr;
- int i;
-
- /* Powerup the chip, initialize config register 1, and select bank 0. */
- outb(0xe0, ioaddr + CONFIG_1);
-
- /* Set the station address in bank zero. */
- for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + 8 + i);
-
- /* Switch to bank 1 and set the multicast table to accept none. */
- outb(0xe4, ioaddr + CONFIG_1);
- for (i = 0; i < 8; i++)
- outb(0x00, ioaddr + 8 + i);
X
X /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
X bus access, and two 4K Tx queues. */
- outb(0xda, ioaddr + CONFIG_0);
+ outb(0x5a, ioaddr + CONFIG_0);
X
- /* Switch to register bank 2, enable the Rx and Tx. */
- outw(0xe85a, ioaddr + CONFIG_0);
+ /* Powerup, switch to register bank 2, and enable the Rx and Tx. */
+ outb(0xe8, ioaddr + CONFIG_1);
X
X lp->tx_started = 0;
+ lp->tx_queue_ready = 1;
+ lp->rx_started = 0;
X lp->tx_queue = 0;
X lp->tx_queue_len = 0;
X
- /* Turn on Rx interrupts, leave Tx interrupts off until packet Tx. */
- outb(0x00, ioaddr + TX_INTR);
+ /* Turn on hardware Tx and Rx interrupts. */
+ outb(0x82, ioaddr + TX_INTR);
X outb(0x81, ioaddr + RX_INTR);
X
+ /* Enable the IRQ on boards of fmv18x it is feasible. */
+ if (lp->jumpered) {
+ outb(0x80, ioaddr + IOCONFIG1);
+ }
+
X dev->tbusy = 0;
X dev->interrupt = 0;
X dev->start = 1;
@@ -518,10 +558,14 @@
X outw(0xffff, ioaddr + 24);
X outw(0xffff, ioaddr + TX_STATUS);
X outw(0xe85a, ioaddr + CONFIG_0);
- outw(0x8100, ioaddr + TX_INTR);
+ outw(0x8182, ioaddr + TX_INTR);
+ outb(0x00, ioaddr + TX_START);
+ outb(0x03, ioaddr + COL16CNTL);
X dev->tbusy=0;
X dev->trans_start = jiffies;
X lp->tx_started = 0;
+ lp->tx_queue_ready = 1;
+ lp->rx_started = 0;
X lp->tx_queue = 0;
X lp->tx_queue_len = 0;
X }
@@ -534,14 +578,20 @@
X short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
X unsigned char *buf = skb->data;
X
- /* Turn off the possible Tx interrupts. */
- outb(0x00, ioaddr + TX_INTR);
-
- outw(length, ioaddr + DATAPORT);
- outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
+ /* We may not start transmitting unless we finish transferring
+ a packet into the Tx queue. During executing the following
+ codes we possibly catch a Tx interrupt. Thus we flag off
+ tx_queue_ready, so that we prevent the interrupt routine
+ (net_interrupt) to start transmitting. */
+ lp->tx_queue_ready = 0;
+ {
+ outw(length, ioaddr + DATAPORT);
+ outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
X
- lp->tx_queue++;
- lp->tx_queue_len += length + 2;
+ lp->tx_queue++;
+ lp->tx_queue_len += length + 2;
+ }
+ lp->tx_queue_ready = 1;
X
X if (lp->tx_started == 0) {
X /* If the Tx is idle, always trigger a transmit. */
@@ -554,9 +604,6 @@
X } else if (lp->tx_queue_len < 4096 - 1502)
X /* Yes, there is room for one more packet. */
X dev->tbusy = 0;
-
- /* Turn on Tx interrupts back on. */
- outb(0x82, ioaddr + TX_INTR);
X }
X dev_kfree_skb (skb);
X
@@ -585,14 +632,35 @@
X
X if (net_debug > 4)
X printk("%s: Interrupt with status %04x.\n", dev->name, status);
- if (status & 0xff00
- || (inb(ioaddr + RX_MODE) & 0x40) == 0) { /* Got a packet(s). */
+ if (lp->rx_started == 0 &&
+ (status & 0xff00 || (inb(ioaddr + RX_MODE) & 0x40) == 0)) {
+ /* Got a packet(s).
+ We cannot execute net_rx more than once at the same time for
+ the same device. During executing net_rx, we possibly catch a
+ Tx interrupt. Thus we flag on rx_started, so that we prevent
+ the interrupt routine (net_interrupt) to dive into net_rx
+ again. */
+ lp->rx_started = 1;
+ outb(0x00, ioaddr + RX_INTR); /* Disable RX intr. */
X net_rx(dev);
+ outb(0x81, ioaddr + RX_INTR); /* Enable RX intr. */
+ lp->rx_started = 0;
X }
X if (status & 0x00ff) {
- if (status & 0x80) {
+ if (status & 0x02) {
+ /* More than 16 collisions occurred */
+ if (net_debug > 4)
+ printk("%s: 16 Collision occur during Txing.\n", dev->name);
+ /* Cancel sending a packet. */
+ outb(0x03, ioaddr + COL16CNTL);
+ lp->stats.collisions++;
+ }
+ if (status & 0x82) {
X lp->stats.tx_packets++;
- if (lp->tx_queue) {
+ /* The Tx queue has any packets and is not being
+ transferred a packet from the host, start
+ transmitting. */
+ if (lp->tx_queue && lp->tx_queue_ready) {
X outb(0x80 | lp->tx_queue, ioaddr + TX_START);
X lp->tx_queue = 0;
X lp->tx_queue_len = 0;
@@ -601,8 +669,6 @@
X mark_bh(NET_BH); /* Inform upper layers. */
X } else {
X lp->tx_started = 0;
- /* Turn on Tx interrupts off. */
- outb(0x00, ioaddr + TX_INTR);
X dev->tbusy = 0;
X mark_bh(NET_BH); /* Inform upper layers. */
X }
@@ -698,7 +764,7 @@
X /* The inverse routine to net_open(). */
X static int net_close(struct device *dev)
X {
-/* struct net_local *lp = (struct net_local *)dev->priv;*/
+ struct net_local *lp = (struct net_local *)dev->priv;
X int ioaddr = dev->base_addr;
X
X dev->tbusy = 1;
@@ -709,13 +775,11 @@
X
X /* No statistic counters on the chip to update. */
X
-#if 0
- /* Disable the IRQ on boards where it is feasible. */
+ /* Disable the IRQ on boards of fmv18x where it is feasible. */
X if (lp->jumpered) {
X outb(0x00, ioaddr + IOCONFIG1);
X free_irq(dev->irq, dev);
X }
-#endif
X
X /* Power-down the chip. Green, green, green! */
X outb(0x00, ioaddr + CONFIG_1);
@@ -820,6 +884,10 @@
X static int io = 0x260;
X static int irq = 0;
X
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(net_debug, "i");
+
X int init_module(void)
X {
X if (io == 0)
@@ -836,14 +904,14 @@
X void
X cleanup_module(void)
X {
- struct net_local *lp = dev_at1700.priv;
- unregister_netdev(&dev_at1700);
X #ifdef CONFIG_MCA
+ struct net_local *lp = dev_at1700.priv;
X if(lp->mca_slot)
X {
X mca_mark_as_unused(lp->mca_slot);
X }
X #endif
+ unregister_netdev(&dev_at1700);
X kfree(dev_at1700.priv);
X dev_at1700.priv = NULL;
X
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c
--- v2.2.0-pre8/linux/drivers/net/fmv18x.c Thu Feb 12 20:56:08 1998
+++ linux/drivers/net/fmv18x.c Tue Jan 19 10:13:13 1999
@@ -32,7 +32,7 @@
X */
X
X static const char *version =
- "fmv18x.c:v1.3.71e 03/04/96 Yutaka TAMIYA (ta...@flab.fujitsu.co.jp)\n";
+ "fmv18x.c:v2.2.0 09/24/98 Yutaka TAMIYA (ta...@flab.fujitsu.co.jp)\n";


X
X #include <linux/module.h>
X

@@ -74,6 +74,8 @@
X struct net_device_stats stats;
X long open_time; /* Useless example local info. */
X uint tx_started:1; /* Number of packet on the Tx queue. */
+ uint tx_queue_ready:1; /* Tx queue is ready to be sent. */
+ uint rx_started:1; /* Packets are Rxing. */
X uchar tx_queue; /* Number of packet on the Tx queue. */
X ushort tx_queue_len; /* Current length of the Tx queue. */
X };
@@ -92,7 +94,7 @@
X /* Run-time register bank 2 definitions. */
X #define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
X #define TX_START 10
-#define COL16CNTL 11
+#define COL16CNTL 11 /* Controll Reg for 16 collisions */
X #define MODE13 13
X /* Fujitsu FMV-18x Card Configuration */
X #define FJ_STATUS0 0x10
@@ -164,6 +166,7 @@
X __initfunc(int fmv18x_probe1(struct device *dev, short ioaddr))
X {
X char irqmap[4] = {3, 7, 10, 15};
+ char irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
X unsigned int i, irq;
X
X /* Resetting the chip doesn't reset the ISA interface, so don't bother.
@@ -171,13 +174,26 @@
X */
X
X /* Check I/O address configuration and Fujitsu vendor code */
- if (fmv18x_probe_list[inb(ioaddr + FJ_CONFIG0) & 0x07] != ioaddr
- || inb(ioaddr+FJ_MACADDR ) != 0x00
+ if (inb(ioaddr+FJ_MACADDR ) != 0x00
X || inb(ioaddr+FJ_MACADDR+1) != 0x00
X || inb(ioaddr+FJ_MACADDR+2) != 0x0e)
X return -ENODEV;
X
- irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
+ /* Check PnP mode for FMV-183/184/183A/184A. */
+ /* This PnP routine is very poor. IO and IRQ should be known. */
+ if (inb(ioaddr + FJ_STATUS1) & 0x20) {
+ irq = dev->irq;
+ for (i = 0; i < 8; i++) {
+ if (irq == irqmap_pnp[i])
+ break;
+ }
+ if (i == 8)
+ return -ENODEV;
+ } else {
+ if (fmv18x_probe_list[inb(ioaddr + FJ_CONFIG0) & 0x07] != ioaddr)
+ return -ENODEV;
+ irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
+ }
X
X /* Snarf the interrupt vector now. */
X if (request_irq(irq, &net_interrupt, 0, "fmv18x", dev)) {
@@ -247,6 +263,7 @@
X /* Switch to bank 2 and lock our I/O address. */
X outb(0x08, ioaddr + CONFIG_1);
X outb(dev->if_port, ioaddr + MODE13);
+ outb(0x00, ioaddr + COL16CNTL);
X
X if (net_debug)
X printk(version);
@@ -283,6 +300,8 @@
X outb(0xe8, ioaddr + CONFIG_1);
X
X lp->tx_started = 0;
+ lp->tx_queue_ready = 1;
+ lp->rx_started = 0;
X lp->tx_queue = 0;
X lp->tx_queue_len = 0;
X
@@ -364,14 +383,20 @@
X printk("%s: Transmitting a packet of length %lu.\n", dev->name,
X (unsigned long)skb->len);
X
- /* Disable both interrupts. */
- outw(0x0000, ioaddr + TX_INTR);
-
- outw(length, ioaddr + DATAPORT);
- outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
+ /* We may not start transmitting unless we finish transferring
+ a packet into the Tx queue. During executing the following
+ codes we possibly catch a Tx interrupt. Thus we flag off
+ tx_queue_ready, so that we prevent the interrupt routine
+ (net_interrupt) to start transmitting. */
+ lp->tx_queue_ready = 0;
+ {
+ outw(length, ioaddr + DATAPORT);
+ outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
X
- lp->tx_queue++;
- lp->tx_queue_len += length + 2;
+ lp->tx_queue++;
+ lp->tx_queue_len += length + 2;
+ }
+ lp->tx_queue_ready = 1;
X
X if (lp->tx_started == 0) {
X /* If the Tx is idle, always trigger a transmit. */
@@ -384,9 +409,6 @@
X } else if (lp->tx_queue_len < 4096 - 1502)
X /* Yes, there is room for one more packet. */
X dev->tbusy = 0;
-
- /* Re-enable interrupts */
- outw(0x8182, ioaddr + TX_INTR);
X }
X dev_kfree_skb (skb);
X
@@ -410,23 +432,37 @@
X
X ioaddr = dev->base_addr;
X lp = (struct net_local *)dev->priv;
-
- /* Avoid multiple interrupts. */
- outw(0x0000, ioaddr + TX_INTR);
-
- status = inw(ioaddr + TX_STATUS);
+ status = inw(ioaddr + TX_STATUS);
X outw(status, ioaddr + TX_STATUS);
X
X if (net_debug > 4)
X printk("%s: Interrupt with status %04x.\n", dev->name, status);
- if (status & 0xff00
- || (inb(ioaddr + RX_MODE) & 0x40) == 0) { /* Got a packet(s). */
+ if (lp->rx_started == 0 &&
+ (status & 0xff00 || (inb(ioaddr + RX_MODE) & 0x40) == 0)) {
+ /* Got a packet(s).
+ We cannot execute net_rx more than once at the same time for
+ the same device. During executing net_rx, we possibly catch a
+ Tx interrupt. Thus we flag on rx_started, so that we prevent
+ the interrupt routine (net_interrupt) to dive into net_rx
+ again. */
+ lp->rx_started = 1;
+ outb(0x00, ioaddr + RX_INTR); /* Disable RX intr. */
X net_rx(dev);
+ outb(0x81, ioaddr + RX_INTR); /* Enable RX intr. */
+ lp->rx_started = 0;
X }
X if (status & 0x00ff) {
- if (status & 0x80) {
+ if (status & 0x02) {
+ /* More than 16 collisions occurred */
+ if (net_debug > 4)
+ printk("%s: 16 Collision occur during Txing.\n", dev->name);
+ /* Cancel sending a packet. */
+ outb(0x03, ioaddr + COL16CNTL);
+ lp->stats.collisions++;
+ }
+ if (status & 0x82) {
X lp->stats.tx_packets++;
- if (lp->tx_queue) {
+ if (lp->tx_queue && lp->tx_queue_ready) {
X outb(0x80 | lp->tx_queue, ioaddr + TX_START);
X lp->tx_queue = 0;
X lp->tx_queue_len = 0;
@@ -439,16 +475,9 @@
X mark_bh(NET_BH); /* Inform upper layers. */
X }
X }
- if (status & 0x02 ) {
- if (net_debug > 4)
- printk("%s: 16 Collision occur during Txing.\n", dev->name);
- /* Retry to send the packet */
- outb(0x02, ioaddr + COL16CNTL);
- }
X }
X
X dev->interrupt = 0;
- outw(0x8182, ioaddr + TX_INTR);
X return;
X }
X
@@ -458,7 +487,7 @@
X {
X struct net_local *lp = (struct net_local *)dev->priv;
X int ioaddr = dev->base_addr;
- int boguscount = 10; /* 5 -> 10: by agy 19940922 */
+ int boguscount = 5;
X
X while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
X /* Clear PKT_RDY bit: by agy 19940922 */
@@ -619,6 +648,7 @@
X
X MODULE_PARM(io, "i");
X MODULE_PARM(irq, "i");
+MODULE_PARM(net_debug, "i");
X
X int init_module(void)
X {
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/irda/Config.in linux/drivers/net/irda/Config.in
--- v2.2.0-pre8/linux/drivers/net/irda/Config.in Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/irda/Config.in Wed Jan 20 11:05:33 1999
@@ -13,4 +13,5 @@
X fi
X dep_tristate ' NSC PC87108' CONFIG_NSC_FIR $CONFIG_IRDA
X dep_tristate ' Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
+dep_tristate ' Sharp UIRCC' CONFIG_SHARP_FIR $CONFIG_IRDA
X endmenu
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/irda/Makefile linux/drivers/net/irda/Makefile
--- v2.2.0-pre8/linux/drivers/net/irda/Makefile Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/irda/Makefile Wed Jan 20 11:05:33 1999
@@ -36,6 +36,14 @@
X endif
X endif
X
+ifeq ($(CONFIG_SHARP_FIR),y)
+L_OBJS += uircc.o irport.o
+else
+ ifeq ($(CONFIG_SHARP_FIR),m)
+ M_OBJS += uircc.o irport.o
+ endif
+endif
+
X ifeq ($(CONFIG_ESI_DONGLE),y)
X L_OBJS += esi.o
X else
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/irda/actisys.c linux/drivers/net/irda/actisys.c
--- v2.2.0-pre8/linux/drivers/net/irda/actisys.c Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/irda/actisys.c Wed Jan 20 11:05:33 1999
@@ -1,13 +1,13 @@
X /*********************************************************************
X *
X * Filename: actisys.c
- * Version: 0.3
+ * Version: 0.4
X * Description: Implementation for the ACTiSYS IR-220L and IR-220L+
X * dongles
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Wed Oct 21 20:02:35 1998
- * Modified at: Mon Dec 14 11:50:32 1998
+ * Modified at: Mon Jan 18 11:30:25 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
@@ -95,7 +95,7 @@
X {
X struct irtty_cb *self;
X struct tty_struct *tty;
- int arg = 0;
+ int arg;
X struct termios old_termios;
X int cflag;
X int current_baudrate;
@@ -132,7 +132,7 @@
X DEBUG( 0, __FUNCTION__ "(), Clearing RTS\n");
X
X /* Set DTR, clear RTS */
- arg = TIOCM_DTR;
+ arg = TIOCM_DTR|TIOCM_OUT2;
X
X fs = get_fs();
X set_fs( get_ds());
@@ -149,7 +149,7 @@
X schedule_timeout(2);
X
X /* Set DTR, Set RTS */
- arg = TIOCM_DTR | TIOCM_RTS;
+ arg = TIOCM_DTR | TIOCM_RTS |TIOCM_OUT2;
X
X fs = get_fs();
X set_fs( get_ds());
@@ -237,7 +237,7 @@
X return;
X
X DEBUG( 0, __FUNCTION__ "(), Clearing DTR\n");
- arg = TIOCM_RTS;
+ arg = TIOCM_RTS | TIOCM_OUT2;
X
X fs = get_fs();
X set_fs( get_ds());
@@ -245,7 +245,7 @@
X if ( tty->driver.ioctl( tty, NULL, TIOCMSET,
X (unsigned long) &arg))
X {
- DEBUG( 0, __FUNCTION__"(), Ioctl error!\n");
+ DEBUG( 0, __FUNCTION__"(), ioctl error!\n");
X }
X set_fs(fs);
X
@@ -254,7 +254,7 @@
X schedule_timeout(2);
X
X DEBUG( 0, __FUNCTION__ "(), Setting DTR\n");
- arg = TIOCM_RTS | TIOCM_DTR;
+ arg = TIOCM_RTS | TIOCM_DTR | TIOCM_OUT2;
X
X fs = get_fs();
X set_fs( get_ds());
@@ -262,7 +262,7 @@
X if ( tty->driver.ioctl( tty, NULL, TIOCMSET,
X (unsigned long) &arg))
X {
- DEBUG( 0, __FUNCTION__"(), Ioctl error!\n");
+ DEBUG( 0, __FUNCTION__"(), ioctl error!\n");
X }
X set_fs(fs);
X
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/irda/esi.c linux/drivers/net/irda/esi.c
--- v2.2.0-pre8/linux/drivers/net/irda/esi.c Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/irda/esi.c Wed Jan 20 11:05:33 1999
@@ -1,12 +1,12 @@
X /*********************************************************************
X *
X * Filename: esi.c
- * Version: 1.0
+ * Version: 1.1
X * Description: Driver for the Extended Systems JetEye PC
X * Status: Experimental.
X * Author: Thomas Davis, <rat...@radiks.net>
X * Created at: Sat Feb 21 18:54:38 1998
- * Modified at: Mon Dec 14 11:48:22 1998
+ * Modified at: Mon Jan 18 11:30:32 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X * Sources: esi.c
X *
@@ -68,7 +68,7 @@
X
X static void esi_open( struct irda_device *idev, int type)
X {
- strcat( idev->name, " <-> esi");
+ strcat( idev->description, " <-> esi");
X
X idev->io.dongle_id = type;
X
@@ -90,13 +90,11 @@
X {
X struct irtty_cb *self;
X struct tty_struct *tty;
- int arg = 0;
+ int arg = TIOCM_OUT2;
X struct termios old_termios;
X int cflag;
X mm_segment_t fs;
X
- DEBUG( 4, __FUNCTION__ "()\n");
-
X ASSERT( idev != NULL, return;);
X ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
X
@@ -118,16 +116,16 @@
X switch (baud) {
X case 19200:
X cflag |= B19200;
- arg = TIOCM_DTR;
+ arg |= TIOCM_DTR;
X break;
X case 115200:
X cflag |= B115200;
- arg = TIOCM_RTS | TIOCM_DTR;
+ arg |= TIOCM_RTS | TIOCM_DTR;
X break;
X case 9600:
X default:
X cflag |= B9600;
- arg = TIOCM_RTS;
+ arg |= TIOCM_RTS;
X break;
X }
X
@@ -146,7 +144,7 @@
X set_fs( get_ds());
X
X if ( tty->driver.ioctl( tty, NULL, TIOCMSET, (unsigned long) &arg)) {
- DEBUG(0, "error setting ESI speed!\n");
+ DEBUG( 0, __FUNCTION__ "(), error setting ESI speed!\n");
X }
X set_fs(fs);
X }
@@ -193,3 +191,4 @@
X }
X
X #endif
+
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
--- v2.2.0-pre8/linux/drivers/net/irda/irport.c Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/irda/irport.c Wed Jan 20 11:05:33 1999
@@ -1,10 +1,8 @@
X /*********************************************************************
X *
X * Filename: irport.c
- * Version: 0.1
- * Description: Serial driver for IrDA. The functions in this file
- * may be used by FIR drivers, but this file knows
- * nothing about FIR drivers!!!
+ * Version: 0.8
+ * Description: Serial driver for IrDA.
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Sun Aug 3 13:49:59 1997
@@ -25,38 +23,91 @@
X * provide warranty for any of this software. This material is
X * provided "AS-IS" and at no charge.
X *
+ * NOTICE:
+ *
+ * This driver is ment to be a small serial driver to be used for
+ * IR-chipsets that has a UART (16550) compatibility mode. If your
+ * chipset is is UART only, you should probably use IrTTY instead since
+ * the Linux serial driver is probably more robust and optimized.
+ *
+ * The functions in this file may be used by FIR drivers, but this
+ * driver knows nothing about FIR drivers so don't ever insert such
+ * code into this file. Instead you should code your FIR driver in a
+ * separate file, and then call the functions in this file if
+ * necessary. This is becase it is difficult to use the Linux serial
+ * driver with a FIR driver becase they must share interrupts etc. Most
+ * FIR chipsets can function in advanced SIR mode, and you should
+ * probably use that mode instead of the UART compatibility mode (and
+ * then just forget about this file)
+ *
X ********************************************************************/
X
-/* #include <linux/module.h> */
+#include <linux/module.h>
X
X #include <linux/kernel.h>
X #include <linux/types.h>
X #include <linux/ioport.h>
-#include <linux/in.h>
X #include <linux/malloc.h>
X #include <linux/string.h>
X #include <asm/system.h>
X #include <asm/bitops.h>
X #include <asm/io.h>
X #include <linux/errno.h>
+#include <linux/config.h>
+#include <linux/init.h>
X
X #include <linux/skbuff.h>
X #include <linux/serial_reg.h>
X
-#include "irda.h"
-#include "ircompat.h"
-#include "irport.h"
-#include "timer.h"
-#include "crc.h"
-#include "wrapper.h"
-#include "irlap_frame.h"
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/wrapper.h>
+#include <net/irda/irport.h>
X
-#define IO_EXTENT 8
+#define IO_EXTENT 8
+
+static unsigned int io[] = { 0x3e8, ~0, ~0, ~0 };
+static unsigned int irq[] = { 11, 0, 0, 0 };
X
X static void irport_write_wakeup( struct irda_device *idev);
-static int irport_write( int iobase, int fifo_size, __u8 *buf, int len);
+static int irport_write( int iobase, int fifo_size, __u8 *buf, int len);
X static void irport_receive( struct irda_device *idev);
X
+__initfunc(int irport_init(void))
+{
+/* int i; */
+
+/* for ( i=0; (io[i] < 2000) && (i < 4); i++) { */
+/* int ioaddr = io[i]; */
+/* if (check_region(ioaddr, IO_EXTENT)) */
+/* continue; */
+/* if (irport_open( i, io[i], io2[i], irq[i], dma[i]) == 0) */
+/* return 0; */
+/* } */
+/* return -ENODEV; */
+ return 0;
+}
+
+/*
+ * Function pc87108_cleanup ()
+ *
+ * Close all configured chips
+ *
+ */
+#ifdef MODULE
+static void irport_cleanup(void)


+{
+ int i;
+

+ DEBUG( 4, __FUNCTION__ "()\n");
+
+ /* for ( i=0; i < 4; i++) { */
+/* if ( dev_self[i]) */
+/* irport_close( &(dev_self[i]->idev)); */
+/* } */
+}
+#endif /* MODULE */
+
X /*
X * Function irport_open (void)
X *
@@ -65,14 +116,14 @@
X */
X int irport_open( int iobase)
X {
+ DEBUG( 0, __FUNCTION__ "(), iobase=%#x\n", iobase);
+
X /* Initialize UART */
- outb_p( UART_LCR_WLEN8, iobase+UART_LCR); /* Reset DLAB */
- outb_p(( UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2),
- iobase+UART_MCR);
+ outb( UART_LCR_WLEN8, iobase+UART_LCR); /* Reset DLAB */
+ outb(( UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
X
X /* Turn on interrups */
- outb_p(( UART_IER_THRI |UART_IER_RLSI | UART_IER_RDI),
- iobase+UART_IER);
+ outb(( UART_IER_THRI |UART_IER_RLSI | UART_IER_RDI), iobase+UART_IER);
X
X return 0;
X }
@@ -88,10 +139,10 @@
X DEBUG( 0, __FUNCTION__ "()\n");
X
X /* Reset UART */
- outb_p( 0, iobase+UART_MCR);
+ outb( 0, iobase+UART_MCR);
X
X /* Turn off interrupts */
- outb_p( 0, iobase+UART_IER);
+ outb( 0, iobase+UART_IER);
X }
X
X /*
@@ -108,8 +159,10 @@
X
X DEBUG( 0, __FUNCTION__ "(), Setting speed to: %d\n", speed);
X
+ DEBUG( 0, __FUNCTION__ "(), iobase=%#x\n", iobase);
+
X /* Turn off interrupts */
- outb_p( 0, iobase+UART_IER);
+ outb( 0, iobase+UART_IER);
X
X divisor = SPEED_MAX/speed;
X
@@ -118,15 +171,14 @@
X /* IrDA ports use 8N1 */
X lcr = UART_LCR_WLEN8;
X
- outb_p( UART_LCR_DLAB | lcr, iobase+UART_LCR); /* Set DLAB */
- outb_p( divisor & 0xff, iobase+UART_DLL); /* Set speed */
- outb_p( divisor >> 8, iobase+UART_DLM);
- outb_p( lcr, iobase+UART_LCR); /* Set 8N1 */
- outb_p( fcr, iobase+UART_FCR); /* Enable FIFO's */
+ outb( UART_LCR_DLAB | lcr, iobase+UART_LCR); /* Set DLAB */
+ outb( divisor & 0xff, iobase+UART_DLL); /* Set speed */
+ outb( divisor >> 8, iobase+UART_DLM);
+ outb( lcr, iobase+UART_LCR); /* Set 8N1 */
+ outb( fcr, iobase+UART_FCR); /* Enable FIFO's */
X
X /* Turn on interrups */
- outb_p(( UART_IER_THRI |UART_IER_RLSI | UART_IER_RDI),
- iobase+UART_IER);
+ outb( UART_IER_THRI|UART_IER_RLSI|UART_IER_RDI, iobase+UART_IER);
X }
X
X /*
@@ -149,21 +201,25 @@
X return;
X }
X
- iobase = idev->io.iobase;
- iir = inb( iobase + UART_IIR);
+ idev->netdev.interrupt = 1;
+
+ iobase = idev->io.iobase2;
X
+ iir = inb(iobase + UART_IIR);
X do {
X status = inb( iobase+UART_LSR);
X
- if ( status & UART_LSR_DR) {
+ if (status & UART_LSR_DR) {
X /* Receive interrupt */
- irport_receive( idev);
+ irport_receive(idev);
X }
- if ( status & UART_LSR_THRE) {
+ if (status & UART_LSR_THRE) {
X /* Transmitter ready for data */
- irport_write_wakeup( idev);
+ irport_write_wakeup(idev);
X }
- } while ( !(inb( iobase+UART_IIR) & UART_IIR_NO_INT));
+ } while (!(inb(iobase+UART_IIR) & UART_IIR_NO_INT));
+
+ idev->netdev.interrupt = 0;
X }
X
X /*
@@ -179,16 +235,11 @@
X
X DEBUG( 4, __FUNCTION__ "() <%ld>\n", jiffies);
X
- /*
- * First make sure we're connected.
- */
X ASSERT( idev != NULL, return;);
X ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
X
- /*
- * Finished with frame?
- */
- if ( idev->tx.ptr == idev->tx.len) {
+ /* Finished with frame? */
+ if ( idev->tx_buff.offset == idev->tx_buff.len) {
X
X /*
X * Now serial buffer is almost free & we can start
@@ -201,16 +252,16 @@
X
X /* Schedule network layer, so we can get some more frames */
X mark_bh( NET_BH);
+
X return;
X }
- /*
- * Write data left in transmit buffer
- */
- count = idev->tx.len - idev->tx.ptr;
- actual = irport_write( idev->io.iobase, idev->io.fifo_size,
- idev->tx.head, count);
- idev->tx.ptr += actual;
- idev->tx.head += actual;
+
+ /* Write data left in transmit buffer */
+ count = idev->tx_buff.len - idev->tx_buff.offset;
+ actual = irport_write( idev->io.iobase2, idev->io.fifo_size,
+ idev->tx_buff.head, count);
+ idev->tx_buff.offset += actual;
+ idev->tx_buff.head += actual;
X }
X
X /*
@@ -223,7 +274,8 @@
X {
X int actual = 0;
X
- if (!(inb_p( iobase+UART_LSR) & UART_LSR_THRE)) {
+ /* Tx FIFO should be empty! */
+ if (!(inb( iobase+UART_LSR) & UART_LSR_THRE)) {
X DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
X return -1;
X }
@@ -265,19 +317,11 @@
X return -EBUSY;
X }
X
- idev = (struct irda_device *) dev->priv;
+ idev = (struct irda_device *) dev->priv;
X
X ASSERT( idev != NULL, return -1;);
X ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
X
- if ( skb == NULL) {
- DEBUG( 0, __FUNCTION__ "(), skb==NULL\n");
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,0)
- dev_tint(dev);
-#endif


- return 0;
- }
-

X /* Lock transmit buffer */
X if ( irda_lock( (void *) &dev->tbusy) == FALSE)
X return -EBUSY;
@@ -285,18 +329,17 @@
X /*
X * Transfer skb to tx_buff while wrapping, stuffing and making CRC
X */
- idev->tx.len = async_wrap_skb( skb, idev->tx.buff, idev->tx.buffsize);
-
- actual = irport_write( idev->io.iobase, idev->io.fifo_size,
- idev->tx.buff, idev->tx.len);
-
- idev->tx.ptr = actual;
- idev->tx.head = idev->tx.buff + actual;
-
- IS_SKB( skb, return 0;);
- FREE_SKB_MAGIC( skb);
- DEV_KFREE_SKB( skb, FREE_WRITE);
-
+ idev->tx_buff.len = async_wrap_skb( skb, idev->tx_buff.data,
+ idev->tx_buff.truesize);
+
+ actual = irport_write( idev->io.iobase2, idev->io.fifo_size,
+ idev->tx_buff.data, idev->tx_buff.len);
+
+ idev->tx_buff.offset = actual;
+ idev->tx_buff.head = idev->tx_buff.data + actual;
+
+ dev_kfree_skb( skb);


+
X return 0;
X }
X

@@ -308,54 +351,54 @@
X */
X static void irport_receive( struct irda_device *idev)
X {
- __u8 byte = 0x00;
X int iobase;
X
X if ( !idev)
X return;
X
- DEBUG( 0, __FUNCTION__ "()\n");
-
- iobase = idev->io.iobase;
+ DEBUG( 4, __FUNCTION__ "()\n");
X
- if ( idev->rx.len == 0) {
- idev->rx.head = idev->rx.buff;
- }
+ iobase = idev->io.iobase2;
X
- /*
- * Receive all characters in FIFO
+ if ( idev->rx_buff.len == 0)
+ idev->rx_buff.head = idev->rx_buff.data;
+
+ /*
+ * Receive all characters in Rx FIFO, unwrap and unstuff them.
+ * async_unwrap_char will deliver all found frames
X */
X do {
- byte = inb_p( iobase+UART_RX);
- async_unwrap_char( idev, byte);
+ async_unwrap_char( idev, inb( iobase+UART_RX));
X
- } while ( inb_p( iobase+UART_LSR) & UART_LSR_DR);
+ } while ( inb( iobase+UART_LSR) & UART_LSR_DR);
X }
X
+#ifdef MODULE
+
X /*
X * Function cleanup_module (void)
X *
X *
X *
X */
-/* void cleanup_module(void) */
-/* { */
-/* DEBUG( 3, "IrPORT: cleanup_module!\n"); */
-/* irport_cleanup(irport_drv); */
-/* } */
+void cleanup_module(void)
+{
+ irport_cleanup();
+}
X
X /*
X * Function init_module (void)
X *
X *
- *
X */
-/* int init_module(void) */
-/* { */
-/* if (irport_init() < 0) { */
-/* cleanup_module(); */
-/* return 1; */
-/* } */
-/* return(0); */
-/* } */
+int init_module(void)
+{
+ if (irport_init() < 0) {
+ cleanup_module();
+ return 1;
+ }
+ return(0);
+}
+
+#endif /* MODULE */
X
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
--- v2.2.0-pre8/linux/drivers/net/irda/irtty.c Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/irda/irtty.c Wed Jan 20 11:05:33 1999
@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Tue Dec 9 21:18:38 1997
- * Modified at: Mon Dec 14 20:09:42 1998
+ * Modified at: Mon Jan 18 15:32:03 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X * Sources: slip.c by Laurence Culhane, <l...@holmes.demon.co.uk>
X * Fred N. van Kempen, <wal...@uwalt.nl.mugnet.org>
@@ -205,6 +205,7 @@
X /* The only value we must override it the baudrate */
X self->idev.qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
X IR_115200;
+ self->idev.qos.min_turn_time.bits = 0x03;
X irda_qos_bits_to_value( &self->idev.qos);
X
X /* Specify which buffer allocation policy we need */
@@ -468,7 +469,6 @@
X */
X async_unwrap_char( &self->idev, *cp++);
X /* self->rx_over_errors++; */
-
X }
X }
X
@@ -586,9 +586,9 @@
X
X tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
X
-
X idev->netdev.tbusy = 0; /* Unlock */
X idev->stats.tx_packets++;
+ idev->stats.tx_bytes += idev->tx_buff.len;
X
X /* Tell network layer that we want more frames */
X mark_bh( NET_BH);
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/irda/pc87108.c linux/drivers/net/irda/pc87108.c
--- v2.2.0-pre8/linux/drivers/net/irda/pc87108.c Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/irda/pc87108.c Wed Jan 20 11:05:33 1999
@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Sat Nov 7 21:43:15 1998
- * Modified at: Mon Dec 14 11:40:24 1998
+ * Modified at: Mon Dec 28 08:46:16 1998
X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>
@@ -129,9 +129,6 @@
X {
X int i;
X
- DEBUG( 0, __FUNCTION__ "()\n");
-
-
X for ( i=0; (io[i] < 2000) && (i < 4); i++) {
X int ioaddr = io[i];
X if (check_region(ioaddr, CHIP_IO_EXTENT))
@@ -369,12 +366,12 @@
X
X /* Receiver frame length */
X switch_bank( iobase, BANK4);
- outb( 4000 & 0xff, iobase+6);
- outb(( 4000 >> 8) & 0x1f, iobase+7);
+ outb( 2048 & 0xff, iobase+6);
+ outb(( 2048 >> 8) & 0x1f, iobase+7);
X
X /* Transmitter frame length */
- outb( 4000 & 0xff, iobase+4);
- outb(( 4000 >> 8) & 0x1f, iobase+5);
+ outb( 2048 & 0xff, iobase+4);
+ outb(( 2048 >> 8) & 0x1f, iobase+5);
X
X DEBUG( 0, "PC87108 driver loaded. Version: 0x%02x\n", version);
X
@@ -676,7 +673,12 @@
X
X /* Set FIFO threshold to TX17, RX16 */
X switch_bank( iobase, BANK0);
- outb( FCR_RXTH|FCR_TXTH|FCR_TXSR|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
+ outb( FCR_RXTH| /* Set Rx FIFO threshold */
+ FCR_TXTH| /* Set Tx FIFO threshold */
+ FCR_TXSR| /* Reset Tx FIFO */
+ FCR_RXSR| /* Reset Rx FIFO */
+ FCR_FIFO_EN, /* Enable FIFOs */
+ iobase+FCR);
X /* outb( 0xa7, iobase+FCR); */
X
X /* Set FIFO size to 32 */
@@ -894,7 +896,7 @@
X idev->stats.tx_errors++;
X idev->stats.tx_fifo_errors++;
X
- /* Clear bit, by writing 1 to it */
+ /* Clear bit, by writing 1 into it */
X outb( ASCR_TXUR, iobase+ASCR);
X } else {
X idev->stats.tx_packets++;
@@ -1049,7 +1051,7 @@
X /* Put this entry back in fifo */
X st_fifo->head--;
X st_fifo->len++;
- st_fifo->entries[ st_fifo->head].status = status;
+ st_fifo->entries[st_fifo->head].status = status;
X st_fifo->entries[ st_fifo->head].len = len;
X
X /* Restore bank register */
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/irda/tekram.c linux/drivers/net/irda/tekram.c
--- v2.2.0-pre8/linux/drivers/net/irda/tekram.c Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/irda/tekram.c Wed Jan 20 11:05:33 1999
@@ -1,12 +1,12 @@
X /*********************************************************************
X *
X * Filename: tekram.c
- * Version: 0.3
+ * Version: 0.4
X * Description: Implementation of the Tekram IrMate IR-210B dongle
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Wed Oct 21 20:02:35 1998
- * Modified at: Mon Dec 14 11:48:37 1998
+ * Modified at: Mon Jan 18 11:30:38 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
@@ -148,7 +148,7 @@
X
X /* Set DTR, Clear RTS */
X DEBUG( 0, __FUNCTION__ "(), Setting DTR, Clearing RTS\n");
- arg = TIOCM_DTR;
+ arg = TIOCM_DTR | TIOCM_OUT2;
X
X fs = get_fs();
X set_fs( get_ds());
@@ -173,7 +173,7 @@
X
X /* Set DTR, Set RTS */
X DEBUG( 0, __FUNCTION__ "(), Setting DTR, Setting RTS\n");
- arg = TIOCM_DTR | TIOCM_RTS;
+ arg = TIOCM_DTR | TIOCM_RTS | TIOCM_OUT2;
X
X fs = get_fs();
X set_fs( get_ds());
@@ -226,7 +226,7 @@
X return;
X
X DEBUG( 0, __FUNCTION__ "(), Power off dongle\n");
- arg = TIOCM_RTS | TIOCM_DTR;
+ arg = TIOCM_RTS | TIOCM_DTR | TIOCM_OUT2;
X
X fs = get_fs();
X set_fs( get_ds());
@@ -244,7 +244,7 @@
X
X DEBUG( 0, __FUNCTION__ "(), Set DTR, clear RTS\n");
X /* Set DTR, clear RTS */
- arg = TIOCM_DTR;
+ arg = TIOCM_DTR | TIOCM_OUT2;
X
X fs = get_fs();
X set_fs( get_ds());
@@ -261,6 +261,8 @@
X
X DEBUG( 0, __FUNCTION__ "(), STATE3\n");
X /* Clear DTR, clear RTS */
+ arg = TIOCM_OUT2;
+
X fs = get_fs();
X set_fs( get_ds());
X
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/irda/uircc.c linux/drivers/net/irda/uircc.c
--- v2.2.0-pre8/linux/drivers/net/irda/uircc.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/irda/uircc.c Wed Jan 20 11:05:33 1999
@@ -0,0 +1,915 @@
+/*********************************************************************
+ *
+ * Filename: uircc.c
+ * Version: 0.1
+ * Description: Driver for the Sharp Universal Infrared
+ * Communications Controller (UIRCC)
+ * Status: Experimental.
+ * Author: Dag Brattli <da...@cs.uit.no>
+ * Created at: Sat Dec 26 10:59:03 1998
+ * Modified at: Tue Jan 19 23:54:04 1999
+ * Modified by: Dag Brattli <da...@cs.uit.no>
+ *
+ * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *
+ * 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.
+ *
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
+ * provide warranty for any of this software. This material is
+ * provided "AS-IS" and at no charge.
+ *
+ * Applicable Models : Tecra 510CDT, 500C Series, 530CDT, 520CDT,
+ * 740CDT, Portege 300CT, 660CDT, Satellite 220C Series,
+ * Satellite Pro, 440C Series, 470CDT, 460C Series, 480C Series
+ *
+ * Notice that FIR mode is not working yet, since I don't know
+ * how to make the UIRCC drive the interrupt line, and not the
+ * UART (which is used for SIR speeds). Please mail me if you know!
+ *
+ ********************************************************************/
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/byteorder.h>
+
+#include <net/irda/wrapper.h>
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/irlap_frame.h>
+#include <net/irda/irda_device.h>
+
+#include <net/irda/uircc.h>
+#include <net/irda/irport.h>
+
+static char *driver_name = "uircc";
+
+#define CHIP_IO_EXTENT 16
+
+static unsigned int io[] = { 0x300, ~0, ~0, ~0 };
+static unsigned int io2[] = { 0x3e8, 0, 0, 0};
+static unsigned int irq[] = { 11, 0, 0, 0 };
+static unsigned int dma[] = { 5, 0, 0, 0 };
+
+static struct uircc_cb *dev_self[] = { NULL, NULL, NULL, NULL};
+
+/* Some prototypes */
+static int uircc_open( int i, unsigned int iobase, unsigned int board_addr,
+ unsigned int irq, unsigned int dma);
+static int uircc_close( struct irda_device *idev);
+static int uircc_probe( int iobase, int board_addr, int irq, int dma);
+static int uircc_dma_receive( struct irda_device *idev);
+static int uircc_dma_receive_complete(struct irda_device *idev, int iobase);
+static int uircc_hard_xmit( struct sk_buff *skb, struct device *dev);
+static void uircc_dma_write( struct irda_device *idev, int iobase);
+static void uircc_change_speed( struct irda_device *idev, int baud);
+static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void uircc_wait_until_sent( struct irda_device *idev);
+static int uircc_is_receiving( struct irda_device *idev);
+
+static int uircc_net_init( struct device *dev);
+static int uircc_net_open( struct device *dev);
+static int uircc_net_close( struct device *dev);
+
+/*
+ * Function uircc_init ()
+ *
+ * Initialize chip. Just try to find out how many chips we are dealing with
+ * and where they are
+ */
+__initfunc(int uircc_init(void))


+{
+ int i;
+

+ for ( i=0; (io[i] < 2000) && (i < 4); i++) {
+ int ioaddr = io[i];
+ if (check_region(ioaddr, CHIP_IO_EXTENT))
+ continue;
+ if (uircc_open( i, io[i], io2[i], irq[i], dma[i]) == 0)
+ return 0;
+ }
+ return -ENODEV;
+}
+
+/*
+ * Function uircc_cleanup ()
+ *
+ * Close all configured chips
+ *
+ */
+#ifdef MODULE
+static void uircc_cleanup(void)


+{
+ int i;
+

+ DEBUG( 4, __FUNCTION__ "()\n");
+
+ for ( i=0; i < 4; i++) {
+ if ( dev_self[i])
+ uircc_close( &(dev_self[i]->idev));
+ }
+}
+#endif /* MODULE */
+
+/*
+ * Function uircc_open (iobase, irq)
+ *
+ * Open driver instance
+ *
+ */
+static int uircc_open( int i, unsigned int iobase, unsigned int iobase2,
+ unsigned int irq, unsigned int dma)
+{
+ struct uircc_cb *self;
+ struct irda_device *idev;
+ int ret;
+
+ DEBUG( 0, __FUNCTION__ "()\n");
+
+ if (( uircc_probe( iobase, iobase2, irq, dma)) == -1)
+ return -1;
+
+ /*
+ * Allocate new instance of the driver
+ */
+ self = kmalloc( sizeof(struct uircc_cb), GFP_KERNEL);
+ if ( self == NULL) {
+ printk( KERN_ERR "IrDA: Can't allocate memory for "
+ "IrDA control block!\n");
+ return -ENOMEM;
+ }
+ memset( self, 0, sizeof(struct uircc_cb));
+
+ /* Need to store self somewhere */
+ dev_self[i] = self;
+
+ idev = &self->idev;
+
+ /* Initialize IO */
+ idev->io.iobase = iobase;
+ idev->io.iobase2 = iobase2; /* Used by irport */
+ idev->io.irq = irq;
+ idev->io.io_ext = CHIP_IO_EXTENT;
+ idev->io.io_ext2 = 8; /* Used by irport */
+ idev->io.dma = dma;
+ idev->io.fifo_size = 16;
+
+ /* Lock the port that we need */
+ ret = check_region( idev->io.iobase, idev->io.io_ext);
+ if ( ret < 0) {
+ DEBUG( 0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+ idev->io.iobase);
+ /* uircc_cleanup( self->idev); */
+ return -ENODEV;
+ }
+ ret = check_region( idev->io.iobase2, idev->io.io_ext2);
+ if ( ret < 0) {
+ DEBUG( 0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+ idev->io.iobase2);
+ /* uircc_cleanup( self->idev); */
+ return -ENODEV;
+ }
+ request_region( idev->io.iobase, idev->io.io_ext, idev->name);
+ request_region( idev->io.iobase2, idev->io.io_ext2, idev->name);
+
+ /* Initialize QoS for this device */
+ irda_init_max_qos_capabilies( &idev->qos);
+
+ /* The only value we must override it the baudrate */
+ idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+ IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
+
+ idev->qos.min_turn_time.bits = 0x07;
+ irda_qos_bits_to_value( &idev->qos);
+
+ /* Specify which buffer allocation policy we need */
+ idev->rx_buff.flags = GFP_KERNEL | GFP_DMA;
+ idev->tx_buff.flags = GFP_KERNEL | GFP_DMA;
+
+ /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
+ idev->rx_buff.truesize = 4000;
+ idev->tx_buff.truesize = 4000;
+
+ /* Initialize callbacks */
+ idev->hard_xmit = uircc_hard_xmit;
+ idev->change_speed = uircc_change_speed;
+ idev->wait_until_sent = uircc_wait_until_sent;
+ idev->is_receiving = uircc_is_receiving;
+
+ /* Override the network functions we need to use */
+ idev->netdev.init = uircc_net_init;
+ idev->netdev.hard_start_xmit = uircc_hard_xmit;
+ idev->netdev.open = uircc_net_open;
+ idev->netdev.stop = uircc_net_close;
+
+ irport_open( iobase2);
+
+ /* Open the IrDA device */
+ irda_device_open( idev, driver_name, self);
+
+ return 0;
+}
+
+/*
+ * Function uircc_close (idev)
+ *
+ * Close driver instance
+ *
+ */
+static int uircc_close( struct irda_device *idev)
+{
+ int iobase;
+
+ DEBUG( 4, __FUNCTION__ "()\n");
+
+ ASSERT( idev != NULL, return -1;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+ iobase = idev->io.iobase;
+
+ /* Disable modem */
+ outb( 0x00, iobase+UIRCC_CR10);
+
+ irport_close( idev->io.iobase2);
+
+ /* Release the PORT that this driver is using */
+ DEBUG( 4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase);
+ release_region( idev->io.iobase, idev->io.io_ext);
+
+ if ( idev->io.iobase2) {
+ DEBUG( 4, __FUNCTION__ "(), Releasing Region %03x\n",
+ idev->io.iobase2);
+ release_region( idev->io.iobase2, idev->io.io_ext2);
+ }
+
+ irda_device_close( idev);
+
+ return 0;
+}
+
+/*
+ * Function uircc_probe (iobase, board_addr, irq, dma)
+ *
+ * Returns non-negative on success.
+ *
+ */
+static int uircc_probe( int iobase, int iobase2, int irq, int dma)
+{
+ int version;
+ int probe_irq=0;
+ unsigned long mask;
+ int i;
+
+ DEBUG( 0, __FUNCTION__ "()\n");
+
+ /* read the chip version, should be 0x03 */
+ version = inb( iobase+UIRCC_SR8);
+
+ if ( version != 0x03) {
+ DEBUG( 0, __FUNCTION__ "(), Wrong chip version");
+ return -1;
+ }
+ DEBUG( 0, "UIRCC driver loaded. Version: 0x%02x\n", version);
+
+ /* Reset chip */
+ outb( UIRCC_CR0_SYS_RST, iobase+UIRCC_CR0);
+
+ /* Initialize some registers */
+ outb( 0, iobase+UIRCC_CR11);
+ outb( 0, iobase+UIRCC_CR9);
+
+ /* Enable DMA single mode */
+ outb( UIRCC_CR1_RX_DMA|UIRCC_CR1_TX_DMA|UIRCC_CR1_MUST_SET,
+ iobase+UIRCC_CR1);
+
+ /* Disable interrupts */
+ outb( 0xff, iobase+UIRCC_CR2);
+
+#if 0
+ irport_close( iobase2);
+
+ for (i=0;i<1;i++) {
+
+ /* Set appropriate speed mode */
+ outb( UIRCC_CR10_FIR, iobase+UIRCC_CR10);
+
+ /* Enable DMA single mode */
+ outb( UIRCC_CR1_RX_DMA|UIRCC_CR1_TX_DMA|UIRCC_CR1_MUST_SET,
+ iobase+UIRCC_CR1);
+
+ /* Set up timer */
+ outb( 0x01, iobase+UIRCC_CR12);
+ outb( 0x00, iobase+UIRCC_CR13);
+
+ /* Set interrupt mask */
+ outb( 0x82, iobase+UIRCC_CR2);
+
+ DEBUG( 0, __FUNCTION__ "(*), sr3=%#x, sr2=%#x, sr10=%#x, sr12=%#x\n",
+ inb( iobase+UIRCC_SR3), inb( iobase+UIRCC_SR2),
+ inb( iobase+UIRCC_SR10), inb( iobase+UIRCC_SR12));
+
+ mask = probe_irq_on();
+
+ /* Enable timer */
+ outb( 0x08, iobase+UIRCC_CR11);
+
+ udelay( 10000); /* Wait for interrupt! */
+
+ probe_irq = probe_irq_off( mask);
+
+ DEBUG( 0, "Found irq=%d\n", probe_irq);
+
+ DEBUG( 0, __FUNCTION__ "(), sr3=%#x, sr2=%#x, sr10=%#x, sr12=%#x\n",
+ inb( iobase+UIRCC_SR3), inb( iobase+UIRCC_SR2),
+ inb( iobase+UIRCC_SR10), inb( iobase+UIRCC_SR12));
+
+
+ /* Diable timer */
+ outb( 0x00, iobase+UIRCC_CR11);
+ }
+#endif
+
+ /* Set self poll address */
+
+ return 0;
+}
+
+/*
+ * Function uircc_change_speed (idev, baud)
+ *
+ * Change the speed of the device
+ *
+ */
+static void uircc_change_speed( struct irda_device *idev, int speed)
+{
+ struct uircc_cb *self;
+ int iobase;
+ int modem = UIRCC_CR10_SIR;
+
+ DEBUG( 0, __FUNCTION__ "()\n");
+
+ ASSERT( idev != NULL, return;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ self = idev->priv;
+ iobase = idev->io.iobase;
+
+ /* Update accounting for new speed */
+ idev->io.baudrate = speed;
+
+ /* Disable interrupts */
+ outb( 0xff, iobase+UIRCC_CR2);
+
+ switch ( speed) {
+ case 9600:
+ case 19200:
+ case 37600:
+ case 57600:
+ case 115200:
+/* irport_open( idev->io.iobase2); */
+ irport_change_speed( idev->io.iobase2, speed);
+ modem = UIRCC_CR10_SIR;
+ break;
+ case 576000:
+
+ DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
+ break;
+ case 1152000:
+
+ DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
+ break;
+ case 4000000:
+ irport_close( idev->io.iobase2);
+ modem = UIRCC_CR10_FIR;
+ DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
+ break;
+ default:
+ DEBUG( 0, __FUNCTION__ "(), unknown baud rate of %d\n", speed);
+ break;
+ }
+
+ /* Set appropriate speed mode */
+ outb( modem, iobase+UIRCC_CR10);
+
+ idev->netdev.tbusy = 0;
+
+ /* Enable some interrupts so we can receive frames */
+ if ( speed > 115200) {
+ /* Enable DMA single mode */
+ outb( UIRCC_CR1_RX_DMA|UIRCC_CR1_TX_DMA|UIRCC_CR1_MUST_SET,
+ iobase+UIRCC_CR1);
+
+ /* outb( UIRCC_CR2_RECV_MASK, iobase+UIRCC_CR2); */
+ outb( 0, iobase+UIRCC_CR2);
+ uircc_dma_receive( idev);
+ }
+}
+
+/*
+ * Function uircc_hard_xmit (skb, dev)
+ *
+ * Transmit the frame!
+ *
+ */
+static int uircc_hard_xmit( struct sk_buff *skb, struct device *dev)
+{
+ struct irda_device *idev;
+ int iobase;
+ int mtt;
+
+ idev = (struct irda_device *) dev->priv;
+
+ ASSERT( idev != NULL, return 0;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+
+ iobase = idev->io.iobase;
+
+ DEBUG(0, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len);
+
+ /* Use irport for SIR speeds */
+ if ( idev->io.baudrate <= 115200) {


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 06'
echo 'File patch-2.2.0-pre9 is continued in part 07'
echo 07 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part07

#!/bin/sh
# this is part 07 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 07; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

+ return irport_hard_xmit( skb, dev);
+ }
+
+ if ( dev->tbusy) {
+ __u8 sr3;
+
+ DEBUG( 4, __FUNCTION__ "(), tbusy==TRUE\n");
+
+ return -EBUSY;
+ }
+
+ /* Lock transmit buffer */
+ if ( irda_lock( (void *) &dev->tbusy) == FALSE)
+ return -EBUSY;
+
+ memcpy( idev->tx_buff.data, skb->data, skb->len);
+
+ /* Make sure that the length is a multiple of 16 bits */
+ if ( skb->len & 0x01)
+ skb->len++;
+
+ idev->tx_buff.len = skb->len;


+ idev->tx_buff.head = idev->tx_buff.data;

+ idev->tx_buff.offset = 0;
+
+ mtt = irda_get_mtt( skb);
+
+ /* Use udelay for delays less than 50 us. */
+ if (mtt)
+ udelay( mtt);
+
+ /* Enable transmit interrupts */
+ /* outb( UIRCC_CR2_XMIT_MASK, iobase+UIRCC_CR2); */


+ outb( 0, iobase+UIRCC_CR2);
+

+ uircc_dma_write( idev, iobase);


+
+ dev_kfree_skb( skb);
+

+ return 0;
+}
+
+/*

+ * Function uircc_dma_xmit (idev, iobase)
+ *
+ * Transmit data using DMA
+ *
+ */


+static void uircc_dma_write( struct irda_device *idev, int iobase)

+{
+ struct uircc_cb *self;

+ int i;
+
+ DEBUG( 0, __FUNCTION__ "()\n");
+

+ ASSERT( idev != NULL, return;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ self = idev->priv;
+

+ /* Receiving disable */
+ self->cr3 &= ~UIRCC_CR3_RECV_EN;
+ outb( self->cr3, iobase+UIRCC_CR3);
+
+ setup_dma( idev->io.dma, idev->tx_buff.data, idev->tx_buff.len,
+ DMA_MODE_WRITE);
+
+ DEBUG( 0, __FUNCTION__ "residue=%d\n",
+ get_dma_residue( idev->io.dma));
+
+ idev->io.direction = IO_XMIT;
+
+ /* Set frame length */
+ outb( idev->tx_buff.len & 0xff, iobase+UIRCC_CR4); /* Low byte */
+ outb( idev->tx_buff.len >> 8, iobase+UIRCC_CR5); /* High byte */
+
+ /* Enable transmit and transmit CRC */
+ self->cr3 |= (UIRCC_CR3_XMIT_EN|UIRCC_CR3_TX_CRC_EN);
+ outb( self->cr3, iobase+UIRCC_CR3);
+}
+
+/*
+ * Function uircc_dma_xmit_complete (idev)
+ *
+ * The transfer of a frame in finished. This function will only be called
+ * by the interrupt handler
+ *
+ */
+static void uircc_dma_xmit_complete( struct irda_device *idev, int underrun)


+{
+ struct uircc_cb *self;
+ int iobase;

+ int len;


+
+ DEBUG( 4, __FUNCTION__ "()\n");
+

+ ASSERT( idev != NULL, return;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ self = idev->priv;
+

+ iobase = idev->io.iobase;
+

+ /* Select TX counter */
+ outb( UIRCC_CR0_CNT_SWT, iobase+UIRCC_CR0);
+
+ /* Read TX length counter */
+ len = inb( iobase+UIRCC_SR4); /* Low byte */
+ len |= inb( iobase+UIRCC_SR5) << 8; /* High byte */
+
+ /* Disable transmit */
+ self->cr3 &= ~UIRCC_CR3_XMIT_EN;
+ outb( self->cr3, iobase+UIRCC_CR3);
+
+ /* Check for underrrun! */
+ if ( underrun) {
+ idev->stats.tx_errors++;
+ idev->stats.tx_fifo_errors++;
+ } else {
+ idev->stats.tx_packets++;


+ idev->stats.tx_bytes += idev->tx_buff.len;

+ }
+
+ /* Unlock tx_buff and request another frame */
+ idev->netdev.tbusy = 0; /* Unlock */
+ idev->media_busy = FALSE;
+
+ /* Tell the network layer, that we can accept more frames */
+ mark_bh( NET_BH);
+}
+
+/*
+ * Function uircc_dma_receive (idev)
+ *
+ * Get ready for receiving a frame. The device will initiate a DMA
+ * if it starts to receive a frame.
+ *
+ */
+static int uircc_dma_receive( struct irda_device *idev)
+{


+ struct uircc_cb *self;
+ int iobase;
+

+ ASSERT( idev != NULL, return -1;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+

+ DEBUG( 0, __FUNCTION__ "\n");


+
+ self = idev->priv;

+ iobase= idev->io.iobase;
+
+ /* Disable DMA */
+
+ setup_dma( idev->io.dma, idev->rx_buff.data, idev->rx_buff.truesize,
+ DMA_MODE_READ);
+
+ /* driver->media_busy = FALSE; */
+ idev->io.direction = IO_RECV;


+ idev->rx_buff.head = idev->rx_buff.data;

+ idev->rx_buff.offset = 0;
+
+ /* Enable receiving with CRC */
+ self->cr3 |= (UIRCC_CR3_RECV_EN|UIRCC_CR3_RX_CRC_EN);
+ outb( self->cr3, iobase+UIRCC_CR3);
+
+ /* Address check? */
+
+ DEBUG( 4, __FUNCTION__ "(), done!\n");

+
+ return 0;
+}
+
+/*

+ * Function uircc_dma_receive_complete (idev)
+ *
+ * Finished with receiving frames
+ *
+ *
+ */
+static int uircc_dma_receive_complete( struct irda_device *idev, int iobase)
+{
+ struct sk_buff *skb;
+ struct uircc_cb *self;
+ int len;


+
+ self = idev->priv;
+

+ DEBUG( 0, __FUNCTION__ "()\n");
+

+ /* Check for CRC or framing error */
+ if ( inb( iobase+UIRCC_SR0) & UIRCC_SR0_RX_CRCFRM) {
+ DEBUG( 0, __FUNCTION__ "(), crc or frm error\n");


+ return -1;
+ }
+

+ /* Select receive length counter */
+ outb( 0x00, iobase+UIRCC_CR0);
+
+ /* Read frame length */
+ len = inb( iobase+UIRCC_SR4); /* Low byte */
+ len |= inb( iobase+UIRCC_SR5) << 8; /* High byte */
+
+ DEBUG( 0, __FUNCTION__ "(), len=%d\n", len);
+
+ /* Receiving disable */
+ self->cr3 &= ~UIRCC_CR3_RECV_EN;
+ outb( self->cr3, iobase+UIRCC_CR3);
+
+ skb = dev_alloc_skb( len+1);
+ if (skb == NULL) {
+ printk( KERN_INFO __FUNCTION__
+ "(), memory squeeze, dropping frame.\n");
+ /* Restore bank register */
+ return FALSE;
+ }
+
+ /* Make sure IP header gets aligned */
+ skb_reserve( skb, 1);
+
+ /* Copy frame without CRC */
+ /* if ( idev->io.baudrate < 4000000) { */
+/* skb_put( skb, len-2); */
+/* memcpy( skb->data, idev->rx_buff.head, len-2); */
+/* } else { */
+/* skb_put( skb, len-4); */
+/* memcpy( skb->data, idev->rx_buff.head, len-4); */
+/* } */
+
+ skb_put( skb, len);
+ memcpy( skb->data, idev->rx_buff.head, len);
+ idev->stats.rx_packets++;
+
+ skb->dev = &idev->netdev;
+ skb->mac.raw = skb->data;
+ skb->protocol = htons(ETH_P_IRDA);
+ netif_rx( skb);
+
+ return TRUE;
+}
+
+/*
+ * Function uircc_interrupt (irq, dev_id, regs)
+ *
+ * An interrupt from the chip has arrived. Time to do some work
+ *
+ */


+static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)

+{
+ __u8 sr3;
+ int iobase;
+
+ struct irda_device *idev = (struct irda_device *) dev_id;
+
+ if (idev == NULL) {
+ printk( KERN_WARNING "%s: irq %d for unknown device.\n",
+ driver_name, irq);
+ return;
+ }
+
+ if (idev->io.baudrate <= 115200)
+ return irport_interrupt( irq, dev_id, regs);


+
+ iobase = idev->io.iobase;
+

+ /* Read interrupt status */
+ sr3 = inb( iobase+UIRCC_SR3);
+ if (!sr3) {
+ return;
+ }
+
+ idev->netdev.interrupt = 1;
+
+ DEBUG( 4, __FUNCTION__ "(), sr3=%#x, sr2=%#x, sr10=%#x\n",

+ inb( iobase+UIRCC_SR3), inb( iobase+UIRCC_SR2),

+ inb( iobase+UIRCC_SR10));
+
+ /*
+ * Check what interrupt this is. The UIRCC will not report two
+ * different interrupts at the same time!
+ */
+ switch( sr3) {
+ case UIRCC_SR3_RX_EOF: /* Check of end of frame */
+ uircc_dma_receive_complete( idev, iobase);
+ break;
+ case UIRCC_SR3_TXUR: /* Check for transmit underrun */
+ uircc_dma_xmit_complete( idev, TRUE);
+ break;
+ case UIRCC_SR3_TX_DONE:
+ uircc_dma_xmit_complete( idev, FALSE);
+ break;
+ case UIRCC_SR3_TMR_OUT:
+ /* Disable timer */
+ outb( inb( iobase+UIRCC_CR11) & ~UIRCC_CR11_TMR_EN,
+ iobase+UIRCC_CR11);
+ break;
+ default:
+ DEBUG( 0, __FUNCTION__ "(), unknown interrupt status=%#x\n",
+ sr3);
+ break;
+ }
+
+ idev->netdev.interrupt = 0;
+}
+
+/*
+ * Function uircc_wait_until_sent (idev)
+ *
+ * This function should put the current thread to sleep until all data
+ * have been sent, so it is safe to change the speed.
+ */


+static void uircc_wait_until_sent( struct irda_device *idev)

+{
+ /* Just delay 60 ms */
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(6);
+}
+
+/*
+ * Function uircc_is_receiving (idev)
+ *
+ * Return TRUE is we are currently receiving a frame
+ *
+ */


+static int uircc_is_receiving( struct irda_device *idev)

+{
+ int status = FALSE;
+ /* int iobase; */
+
+ ASSERT( idev != NULL, return FALSE;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return FALSE;);
+
+ if ( idev->io.baudrate > 115200) {
+
+ } else
+ status = ( idev->rx_buff.state != OUTSIDE_FRAME);
+
+ return status;
+}
+
+/*
+ * Function uircc_net_init (dev)
+ *
+ * Initialize network device
+ *
+ */


+static int uircc_net_init( struct device *dev)

+{
+ DEBUG( 4, __FUNCTION__ "()\n");
+

+ /* Setup to be a normal IrDA network device driver */
+ irda_device_setup( dev);
+
+ /* Insert overrides below this line! */


+
+ return 0;
+}
+

+
+/*
+ * Function uircc_net_open (dev)
+ *
+ * Start the device
+ *
+ */


+static int uircc_net_open( struct device *dev)

+{
+ struct irda_device *idev;
+ int iobase;
+

+ DEBUG( 4, __FUNCTION__ "()\n");
+

+ ASSERT( dev != NULL, return -1;);


+ idev = (struct irda_device *) dev->priv;
+
+ ASSERT( idev != NULL, return 0;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+
+ iobase = idev->io.iobase;
+

+ if (request_irq( idev->io.irq, uircc_interrupt, 0, idev->name,
+ (void *) idev)) {
+ return -EAGAIN;
+ }
+ /*
+ * Always allocate the DMA channel after the IRQ,
+ * and clean up on failure.
+ */
+ if (request_dma(idev->io.dma, idev->name)) {
+ free_irq( idev->io.irq, idev);
+ return -EAGAIN;
+ }
+
+ /* Ready to play! */
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+ /* turn on interrupts */
+
+ MOD_INC_USE_COUNT;


+
+ return 0;
+}
+
+/*

+ * Function uircc_net_close (dev)
+ *
+ * Stop the device
+ *
+ */
+static int uircc_net_close(struct device *dev)


+{
+ struct irda_device *idev;
+ int iobase;
+

+ DEBUG( 4, __FUNCTION__ "()\n");
+

+ /* Stop device */
+ dev->tbusy = 1;
+ dev->start = 0;
+
+ ASSERT( dev != NULL, return -1;);


+ idev = (struct irda_device *) dev->priv;
+
+ ASSERT( idev != NULL, return 0;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+
+ iobase = idev->io.iobase;
+

+ disable_dma( idev->io.dma);


+
+ /* Disable interrupts */
+

+ free_irq( idev->io.irq, idev);
+ free_dma( idev->io.dma);
+
+ MOD_DEC_USE_COUNT;


+
+ return 0;
+}
+

+#ifdef MODULE
+
+/*
+ * Function init_module (void)


+ *
+ *
+ *

+ */
+int init_module(void)
+{
+ uircc_init();


+
+ return(0);
+}
+

+/*
+ * Function cleanup_module (void)


+ *
+ *
+ *

+ */
+void cleanup_module(void)
+{
+ uircc_cleanup();
+}
+
+#endif
+
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/net/tulip.c linux/drivers/net/tulip.c
--- v2.2.0-pre8/linux/drivers/net/tulip.c Wed Jan 13 15:00:42 1999
+++ linux/drivers/net/tulip.c Tue Jan 19 13:18:45 1999
@@ -279,7 +279,7 @@
X HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM,
X tulip_timer },
X { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_21142,
- "Digital DS21142/3 Tulip", 256, 0x0801fbff,
+ "Digital DS21142/3 Tulip", 128, 0x0801fbff,
X HAS_MII | HAS_MEDIA_TABLE, t21142_timer },
X { PCI_VENDOR_ID_LITEON, 0x0002,
X "Lite-On 82c168 PNIC", 256, 0x0001ebef, HAS_MII, pnic_timer },
@@ -2397,7 +2397,6 @@
X memcpy(skb_put(skb, pkt_len),
X bus_to_virt(tp->rx_ring[entry].buffer1), pkt_len);
X #else
-#warning Code untested
X eth_copy_and_sum(skb, bus_to_virt(tp->rx_ring[entry].buffer1),
X pkt_len, 0);
X skb_put(skb, pkt_len);
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.2.0-pre8/linux/drivers/pci/pci.c Wed Sep 9 14:51:08 1998
+++ linux/drivers/pci/pci.c Wed Jan 20 10:18:53 1999
@@ -28,6 +28,9 @@
X #endif
X
X struct pci_bus pci_root;
+#ifdef CONFIG_VISWS
+struct pci_bus pci_other;
+#endif
X struct pci_dev *pci_devices = NULL;
X static struct pci_dev **pci_last_dev_p = &pci_devices;
X static int pci_reverse __initdata = 0;


@@ -382,6 +385,11 @@
X

X memset(&pci_root, 0, sizeof(pci_root));
X pci_root.subordinate = pci_scan_bus(&pci_root);
+#ifdef CONFIG_VISWS
+ pci_other.number = 1; /* XXX unless bridge(s) on pci_root */
+ pci_other.subordinate = pci_scan_bus(&pci_other);
+ pci_root.next = &pci_other;
+#endif
X
X /* give BIOS a chance to apply platform specific fixes: */
X pcibios_fixup();
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/pnp/parport_probe.c linux/drivers/pnp/parport_probe.c
--- v2.2.0-pre8/linux/drivers/pnp/parport_probe.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/pnp/parport_probe.c Wed Jan 20 13:29:18 1999
@@ -105,13 +105,13 @@
X parport_claim_or_block(dev);
X
X switch (parport_ieee1284_nibble_mode_ok(port, 4)) {
- case 1:
+ case 2:
X current->state=TASK_INTERRUPTIBLE;
X /* HACK: wait 10ms because printer seems to ack wrong */
X schedule_timeout((HZ+99)/100);
X result = read_polled(port, buffer, len);
X break;
- case 0:
+ default:
X result = -EIO;
X break;
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.2.0-pre8/linux/drivers/scsi/aha152x.c Tue Jan 19 11:32:51 1999
+++ linux/drivers/scsi/aha152x.c Tue Jan 19 11:01:04 1999
@@ -566,6 +566,7 @@
X { "Adaptec BIOS:AVA-282X", 0xc, 21 }, /* Adaptec 282x */
X { "Adaptec IBM Dock II SCSI", 0x2edd, 24 }, /* IBM Thinkpad Dock II */
X { "Adaptec BIOS:AHA-1532P", 0x1c, 22 }, /* IBM Thinkpad Dock II SCSI */
+ { "DTC3520A Host Adapter BIOS", 0x318a, 26 }, /* DTC 3520A ISA SCSI */
X };
X #define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature))
X #endif
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/scsi/ini9100u.c linux/drivers/scsi/ini9100u.c
--- v2.2.0-pre8/linux/drivers/scsi/ini9100u.c Wed Jan 13 15:00:42 1999
+++ linux/drivers/scsi/ini9100u.c Tue Jan 19 11:23:23 1999
@@ -247,6 +247,19 @@
X /* ---- EXTERNAL VARIABLES ---- */
X extern HCS tul_hcs[];
X
+struct id {
+ int vendor_id;
+ int device_id;
+};
+
+const struct id id_table[] = {
+ { INI_VENDOR_ID, I950_DEVICE_ID },
+ { INI_VENDOR_ID, I940_DEVICE_ID },
+ { INI_VENDOR_ID, I935_DEVICE_ID },
+ { INI_VENDOR_ID, 0x0002 },
+ { DMX_VENDOR_ID, 0x0002 },
+};
+
X /*
X * queue services:
X */
@@ -338,64 +351,27 @@
X int iAdapters = 0;
X long dRegValue;
X WORD wBIOS;
+ const int iNumIdEntries = sizeof(id_table)/sizeof(id_table[0]);
+ int i = 0;
X
X init_i91uAdapter_table();
X
- while ((pDev = pci_find_device(INI_VENDOR_ID, I950_DEVICE_ID, pDev)) != NULL) {
- pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
- wBIOS = (UWORD) (dRegValue & 0xFF);
- if (((dRegValue & 0xFF00) >> 8) == 0xFF)
- dRegValue = 0;
- wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8));
- if (Addi91u_into_Adapter_table(wBIOS,
- (pDev->base_address[0] & 0xFFFE),
- pDev->irq,
- pDev->bus->number,
- (pDev->devfn >> 3)
- ) == 0)
- iAdapters++;
- }
- while ((pDev = pci_find_device(INI_VENDOR_ID, I940_DEVICE_ID, pDev)) != NULL) {
- pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
- wBIOS = (UWORD) (dRegValue & 0xFF);
- if (((dRegValue & 0xFF00) >> 8) == 0xFF)
- dRegValue = 0;
- wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8));
- if (Addi91u_into_Adapter_table(wBIOS,
- (pDev->base_address[0] & 0xFFFE),
- pDev->irq,
- pDev->bus->number,
- (pDev->devfn >> 3)
- ) == 0)
- iAdapters++;
- }
- while ((pDev = pci_find_device(INI_VENDOR_ID, I935_DEVICE_ID, pDev)) != NULL) {
- pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
- wBIOS = (UWORD) (dRegValue & 0xFF);
- if (((dRegValue & 0xFF00) >> 8) == 0xFF)
- dRegValue = 0;
- wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8));
- if (Addi91u_into_Adapter_table(wBIOS,
- (pDev->base_address[0] & 0xFFFE),
- pDev->irq,
- pDev->bus->number,
- (pDev->devfn >> 3)
- ) == 0)
- iAdapters++;
- }
- while ((pDev = pci_find_device(INI_VENDOR_ID, 0x0002, pDev)) != NULL) {
- pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
- wBIOS = (UWORD) (dRegValue & 0xFF);
- if (((dRegValue & 0xFF00) >> 8) == 0xFF)
- dRegValue = 0;
- wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8));
- if (Addi91u_into_Adapter_table(wBIOS,
- (pDev->base_address[0] & 0xFFFE),
- pDev->irq,
- pDev->bus->number,
- (pDev->devfn >> 3)
- ) == 0)
- iAdapters++;
+ for (i=0; i < iNumIdEntries; i++) {
+ struct id curId = id_table[i];
+ while ((pDev = pci_find_device(curId.vendor_id, curId.device_id, pDev)) != NULL) {
+ pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
+ wBIOS = (UWORD) (dRegValue & 0xFF);
+ if (((dRegValue & 0xFF00) >> 8) == 0xFF)
+ dRegValue = 0;
+ wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8));
+ if (Addi91u_into_Adapter_table(wBIOS,
+ (pDev->base_address[0] & 0xFFFE),
+ pDev->irq,
+ pDev->bus->number,
+ (pDev->devfn >> 3)
+ ) == 0)
+ iAdapters++;
+ }
X }
X
X return (iAdapters);
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/scsi/ini9100u.h linux/drivers/scsi/ini9100u.h
--- v2.2.0-pre8/linux/drivers/scsi/ini9100u.h Wed Jan 13 15:00:42 1999
+++ linux/drivers/scsi/ini9100u.h Wed Jan 20 16:22:57 1999
@@ -207,6 +207,7 @@
X #define SENSE_SIZE 14
X
X #define INI_VENDOR_ID 0x1101 /* Initio's PCI vendor ID */
+#define DMX_VENDOR_ID 0x134a /* Domex's PCI vendor ID */
X #define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */
X #define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */
X #define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v2.2.0-pre8/linux/drivers/sound/ad1848.c Tue Jan 19 11:32:52 1999
+++ linux/drivers/sound/ad1848.c Tue Jan 19 14:47:48 1999
@@ -2420,7 +2420,7 @@
X ad1848_unload(hw_config->io_base + 4,
X hw_config->irq,
X hw_config->dma,
- hw_config->dma, 0);
+ hw_config->dma2, 0);
X sound_unload_audiodev(hw_config->slots[0]);
X release_region(hw_config->io_base, 4);
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/Config.in linux/drivers/video/Config.in
--- v2.2.0-pre8/linux/drivers/video/Config.in Tue Dec 22 14:16:56 1998
+++ linux/drivers/video/Config.in Tue Jan 19 10:48:17 1999
@@ -4,6 +4,15 @@
X
X if [ "$CONFIG_FB" = "y" ]; then
X define_bool CONFIG_DUMMY_CONSOLE y
+ if [ "$CONFIG_APUS" = "y" ]; then
+ bool 'Permedia2 support' CONFIG_FB_PM2
+ if [ "$CONFIG_FB_PM2" = "y" ]; then
+ bool ' enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT
+ if [ "$CONFIG_APUS" = "y" ]; then
+ bool ' Phase5 CVisionPPC/BVisionPPC support' CONFIG_FB_PM2_CVPPC
+ fi
+ fi
+ fi
X if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
X bool 'Acorn VIDC support' CONFIG_FB_ACORN
X fi
@@ -22,7 +31,6 @@
X tristate 'Amiga CyberVision support' CONFIG_FB_CYBER


X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then

X bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_VIRGE
- bool 'Amiga CyberVisionPPC support (experimental)' CONFIG_FB_CVPPC
X tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3
X tristate 'Amiga CLgen driver' CONFIG_FB_CLGEN
X fi
@@ -157,7 +165,7 @@
X "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
X "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
X "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
- "$CONFIG_FB_CT65550" = "y" ]; then
+ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" ]; then
X define_bool CONFIG_FBCON_CFB8 y
X else
X if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
@@ -170,7 +178,7 @@
X "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
X "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
X "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
- "$CONFIG_FB_CT65550" = "m" ]; then
+ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" ]; then
X define_bool CONFIG_FBCON_CFB8 m
X fi
X fi
@@ -180,7 +188,8 @@
X "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
X "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
X "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
- "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" ]; then
+ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
+ "$CONFIG_FB_PM2" = "y" ]; then
X define_bool CONFIG_FBCON_CFB16 y
X else
X if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
@@ -189,18 +198,19 @@
X "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
X "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
X "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
- "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" ]; then
+ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
+ "$CONFIG_FB_PM2" = "m" ]; then
X define_bool CONFIG_FBCON_CFB16 m
X fi
X fi
X if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
X "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
- "$CONFIG_FB_MATROX" = "y" ]; then
+ "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" ]; then
X define_bool CONFIG_FBCON_CFB24 y
X else
X if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
X "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
- "$CONFIG_FB_MATROX" = "m" ]; then
+ "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" ]; then
X define_bool CONFIG_FBCON_CFB24 m
X fi
X fi
@@ -208,14 +218,14 @@
X "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
X "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
X "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
- "$CONFIG_FB_MATROX" = "y" ]; then
+ "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" ]; then
X define_bool CONFIG_FBCON_CFB32 y
X else
X if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
X "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
X "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
X "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
- "$CONFIG_FB_MATROX" = "m" ]; then
+ "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" ]; then
X define_bool CONFIG_FBCON_CFB32 m
X fi
X fi
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/Makefile linux/drivers/video/Makefile
--- v2.2.0-pre8/linux/drivers/video/Makefile Thu Nov 19 09:56:28 1998
+++ linux/drivers/video/Makefile Tue Jan 19 10:48:17 1999
@@ -79,6 +79,11 @@


X endif
X endif
X

+ifeq ($(CONFIG_FB_PM2),y)
+L_OBJS += pm2fb.o
+CONFIG_FBGEN_BUILTIN = y
+endif
+
X ifeq ($(CONFIG_FB_APOLLO),y)
X L_OBJS += dnfb.o
X endif
@@ -121,11 +126,6 @@
X ifeq ($(CONFIG_FB_CYBER),m)
X M_OBJS += cyberfb.o
X endif
-endif
-
-ifeq ($(CONFIG_FB_CVPPC),y)
-L_OBJS += cvppcfb.o
-CONFIG_FBGEN_BUILTIN = y
X endif
X
X ifeq ($(CONFIG_FB_MAC),y)
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/amifb.c linux/drivers/video/amifb.c
--- v2.2.0-pre8/linux/drivers/video/amifb.c Thu Nov 19 09:56:28 1998
+++ linux/drivers/video/amifb.c Tue Jan 19 10:47:48 1999
@@ -623,6 +623,7 @@
X
X static u_long videomemory, spritememory;
X static u_long videomemorysize;
+static u_long videomemory_phys;
X
X /*
X * This is the earliest allowed start of fetching display data.
@@ -1479,8 +1480,7 @@
X struct fb_fix_screeninfo fix;
X
X ami_encode_fix(&fix, &par);
- display->screen_base =
- phys_to_virt ((unsigned long) fix.smem_start);
+ display->screen_base = (char *)videomemory;
X display->visual = fix.visual;
X display->type = fix.type;
X display->type_aux = fix.type_aux;
@@ -1877,6 +1877,18 @@
X assignchunk(copdisplay.list[1][0], copins *, chipptr, COPLISTSIZE);
X assignchunk(copdisplay.list[1][1], copins *, chipptr, COPLISTSIZE);
X
+ /*
+ * access the videomem with writethrough cache
+ */
+ videomemory_phys = (u_long)ZTWO_PADDR(videomemory);
+#if 1
+ videomemory = (u_long)ioremap_writethrough(videomemory_phys, videomemorysize);
+#endif
+ if (!videomemory) {
+ printk("amifb: WARNING! unable to map videomem cached writethrough\n");
+ videomemory = ZTWO_VADDR(videomemory_phys);
+ }
+
X memset(dummysprite, 0, DUMMYSPRITEMEMSIZE);
X
X /*
@@ -2126,7 +2138,7 @@
X {
X memset(fix, 0, sizeof(struct fb_fix_screeninfo));
X strcpy(fix->id, amifb_name);
- fix->smem_start = (char*) virt_to_phys((void *)videomemory);
+ fix->smem_start = (char *)videomemory_phys;
X fix->smem_len = videomemorysize;
X
X #ifdef FBCON_HAS_MFB
@@ -2742,16 +2754,16 @@
X par->bpl1mod = par->bpl2mod;
X
X if (par->yoffset) {
- par->bplpt0 = ZTWO_PADDR((u_long)videomemory + par->next_line*par->yoffset + move);
+ par->bplpt0 = videomemory_phys + par->next_line*par->yoffset + move;
X if (par->vmode & FB_VMODE_YWRAP) {
X if (par->yoffset > par->vyres-par->yres) {
- par->bplpt0wrap = ZTWO_PADDR((u_long)videomemory + move);
+ par->bplpt0wrap = videomemory_phys + move;
X if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v+par->vyres-par->yoffset))
X par->bplpt0wrap += par->next_line;
X }
X }
X } else
- par->bplpt0 = ZTWO_PADDR((u_long)videomemory + move);
+ par->bplpt0 = videomemory_phys + move;
X
X if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v))
X par->bplpt0 += par->next_line;
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/atafb.c linux/drivers/video/atafb.c
--- v2.2.0-pre8/linux/drivers/video/atafb.c Fri Oct 9 13:27:12 1998
+++ linux/drivers/video/atafb.c Tue Jan 19 10:47:48 1999
@@ -62,6 +62,7 @@
X #include <asm/uaccess.h>


X #include <asm/pgtable.h>
X #include <asm/irq.h>
+#include <asm/io.h>
X

X #include <asm/atarihw.h>
X #include <asm/atariints.h>
@@ -669,7 +670,7 @@
X addr = ((shifter.bas_hi & 0xff) << 16) |
X ((shifter.bas_md & 0xff) << 8) |
X ((shifter.bas_lo & 0xff));
- par->screen_base = PTOV(addr);
+ par->screen_base = phys_to_virt(addr);
X }
X
X static void tt_set_par( struct atafb_par *par )
@@ -1502,7 +1503,7 @@
X addr = (shifter.bas_hi & 0xff) << 16 |
X (shifter.bas_md & 0xff) << 8 |
X (shifter.bas_lo & 0xff);
- par->screen_base = PTOV(addr);
+ par->screen_base = phys_to_virt(addr);
X
X /* derived parameters */
X hw->ste_mode = (hw->f_shift & 0x510)==0 && hw->st_shift==0x100;
@@ -1929,7 +1930,7 @@
X ((shifter.bas_md & 0xff) << 8);
X if (ATARIHW_PRESENT(EXTD_SHIFTER))
X addr |= (shifter.bas_lo & 0xff);
- par->screen_base = PTOV(addr);
+ par->screen_base = phys_to_virt(addr);
X }
X
X static void stste_set_par( struct atafb_par *par )
@@ -2026,7 +2027,7 @@
X static void stste_set_screen_base(unsigned long s_base)
X {
X unsigned long addr;
- addr= VTOP(s_base);
+ addr= virt_to_phys(s_base);
X /* Setup Screen Memory */
X shifter.bas_hi=(unsigned char) ((addr & 0xff0000) >> 16);
X shifter.bas_md=(unsigned char) ((addr & 0x00ff00) >> 8);
@@ -2297,7 +2298,7 @@
X static void set_screen_base(unsigned long s_base)
X {
X unsigned long addr;
- addr= VTOP(s_base);
+ addr= virt_to_phys(s_base);
X /* Setup Screen Memory */
X shifter.bas_hi=(unsigned char) ((addr & 0xff0000) >> 16);
X shifter.bas_md=(unsigned char) ((addr & 0x00ff00) >> 8);
@@ -2819,9 +2820,9 @@
X if (CPU_IS_040_OR_060) {
X /* On a '040+, the cache mode of video RAM must be set to
X * write-through also for internal video hardware! */
- cache_push( VTOP(screen_base), screen_len );
+ cache_push( virt_to_phys(screen_base), screen_len );
X kernel_set_cachemode( screen_base, screen_len,
- KERNELMAP_NO_COPYBACK );
+ IOMAP_WRITETHROUGH );
X }
X #ifdef ATAFB_EXT
X }
@@ -2829,11 +2830,9 @@
X /* Map the video memory (physical address given) to somewhere
X * in the kernel address space.
X */
- external_addr = kernel_map(external_addr, external_len,
- KERNELMAP_NO_COPYBACK, NULL);
+ external_addr = ioremap_writethrough(external_addr, external_len);
X if (external_vgaiobase)
- external_vgaiobase = kernel_map(external_vgaiobase,
- 0x10000, KERNELMAP_NOCACHE_SER, NULL);
+ external_vgaiobase = ioremap(external_vgaiobase, 0x10000 );
X screen_base =
X real_screen_base = external_addr;
X screen_len = external_len & PAGE_MASK;
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- v2.2.0-pre8/linux/drivers/video/atyfb.c Thu Jan 7 15:11:38 1999
+++ linux/drivers/video/atyfb.c Tue Jan 19 10:47:48 1999
@@ -1,4 +1,4 @@
-/* $Id: atyfb.c,v 1.93 1998/12/18 18:33:13 geert Exp $
+/* $Id: atyfb.c,v 1.98 1999/01/14 08:50:53 geert Exp $
X * linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
X *
X * Copyright (C) 1997-1998 Geert Uytterhoeven
@@ -222,6 +222,7 @@
X u32 cfb32[16];
X #endif
X } fbcon_cmap;
+ u8 blitter_may_be_busy;
X #ifdef __sparc__
X u8 open;
X u8 mmaped;
@@ -320,8 +321,7 @@
X #endif
X
X static void reset_engine(const struct fb_info_aty *info);
-static void init_engine(const struct atyfb_par *par,
- const struct fb_info_aty *info);
+static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info);
X static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info);
X static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info);
X #if defined(__sparc__) || defined(DEBUG)
@@ -533,10 +533,11 @@
X ((u32)(0x8000 >> entries)));
X }
X
-static inline void wait_for_idle(const struct fb_info_aty *info)
+static inline void wait_for_idle(struct fb_info_aty *info)
X {
X wait_for_fifo(16, info);
X while ((aty_ld_le32(GUI_STAT, info) & 1)!= 0);
+ info->blitter_may_be_busy = 0;
X }
X
X static void reset_engine(const struct fb_info_aty *info)
@@ -553,8 +554,7 @@
X BUS_FIFO_ERR_ACK, info);
X }
X
-static void init_engine(const struct atyfb_par *par,
- const struct fb_info_aty *info)
+static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info)
X {
X u32 pitch_value;
X
@@ -872,7 +872,8 @@
X aty_ld_le32(GEN_TEST_CNTL, fb) & ~HWCURSOR_ENABLE,
X fb);
X }
- wait_for_idle(fb);
+ if (fb->blitter_may_be_busy)
+ wait_for_idle(fb);


X }
X
X static void

@@ -1608,6 +1609,7 @@
X return err;
X
X if ((((Gx == GT_CHIP_ID) && (Rev & 0x03)) || (Gx == GU_CHIP_ID) ||
+ (Gx == GV_CHIP_ID) || (Gx == GW_CHIP_ID) || (Gx == GZ_CHIP_ID) ||
X (Gx == LG_CHIP_ID) || (Gx == GB_CHIP_ID) || (Gx == GD_CHIP_ID) ||
X (Gx == GI_CHIP_ID) || (Gx == GP_CHIP_ID) || (Gx == GQ_CHIP_ID) ||
X (Gx == VU_CHIP_ID)) && (info->ram_type >= SDRAM))
@@ -1703,6 +1705,8 @@
X
X info->current_par = *par;
X
+ if (info->blitter_may_be_busy)
+ wait_for_idle(info);
X aty_set_crtc(info, &par->crtc);
X aty_st_8(CLOCK_CNTL, 0, info);
X aty_st_8(CLOCK_CNTL, CLOCK_STROBE, info);
@@ -1717,8 +1721,8 @@
X break;
X }
X aty_set_pll_gx(info, &par->pll.gx);
- aty_st_le32(BUS_CNTL, 0x890e20f1, info);
- aty_st_le32(DAC_CNTL, 0x47052100, info);
+ aty_st_le32(BUS_CNTL, 0x590e10ff, info);
+ aty_st_le32(DAC_CNTL, 0x47012100, info);
X
X /* Don't forget MEM_CNTL */
X i = aty_ld_le32(MEM_CNTL, info) & 0xf0ffffff;
@@ -2472,9 +2476,13 @@
X (Rev == 0x48))) ||
X ((Gx == VT_CHIP_ID) && ((Rev == 0x01) ||
X (Rev == 0x9a))) ||
- (Gx == VU_CHIP_ID)) {
+ Gx == VU_CHIP_ID) {
X /* VTA4 or VTB */
X pll = 200;
+ } else if (Gx == VV_CHIP_ID) {
+ /* VT4 */
+ pll = 230;
+ mclk = 83;
X } else if (Gx == VT_CHIP_ID) {
X /* other VT */
X pll = 135;
@@ -2486,15 +2494,19 @@
X (Gx == GU_CHIP_ID)) {
X /* RAGE II+ */
X pll = 200;
+ } else if (Gx == GV_CHIP_ID || Gx == GW_CHIP_ID ||
+ Gx == GZ_CHIP_ID) {
+ /* RAGE IIC */
+ pll = 230;
+ mclk = 83;
X } else if (Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
X Gx == GI_CHIP_ID || Gx == GP_CHIP_ID ||
- Gx == GQ_CHIP_ID || Gx == VV_CHIP_ID ||
- Gx == GV_CHIP_ID || Gx == GW_CHIP_ID ||
- Gx == GZ_CHIP_ID || Gx == LD_CHIP_ID ||
- Gx == LG_CHIP_ID || Gx == LB_CHIP_ID ||
+ Gx == GQ_CHIP_ID || Gx == LB_CHIP_ID ||
+ Gx == LD_CHIP_ID || Gx == LG_CHIP_ID ||
X Gx == LI_CHIP_ID || Gx == LP_CHIP_ID) {
- /* RAGE PRO or IIC */
+ /* RAGE PRO or LT PRO */
X pll = 230;
+ mclk = 100;
X } else {
X /* other RAGE */
X pll = 135;
@@ -3023,12 +3035,9 @@
X * Map the video memory (physical address given) to somewhere in the
X * kernel address space.
X */
- info->frame_buffer = kernel_map(phys_vmembase[m64_num],
- phys_size[m64_num],
- KERNELMAP_NOCACHE_SER, NULL);
+ info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
X info->frame_buffer_phys = info->frame_buffer;
- info->ati_regbase = kernel_map(phys_guiregbase[m64_num], 0x10000,
- KERNELMAP_NOCACHE_SER, NULL)+0xFC00ul;
+ info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul;
X info->ati_regbase_phys = info->ati_regbase;
X
X if (!aty_init(info, "ISA bus")) {
@@ -3416,6 +3425,7 @@
X wait_for_fifo(2, info);
X aty_st_le32(DST_Y_X, (x << 16) | y, info);
X aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | height, info);
+ info->blitter_may_be_busy = 1;
X }
X
X static inline void aty_rectcopy(int srcx, int srcy, int dstx, int dsty,
@@ -3578,14 +3588,15 @@
X static void fbcon_aty8_putc(struct vc_data *conp, struct display *p, int c,
X int yy, int xx)
X {
-#ifdef __sparc__
X struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X
+#ifdef __sparc__
X if (fb->mmaped && currcon == fb->vtconsole)
X return;
X #endif
X
- wait_for_idle((struct fb_info_aty *)p->fb_info);
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
X fbcon_cfb8_putc(conp, p, c, yy, xx);
X }
X
@@ -3593,20 +3604,36 @@
X const unsigned short *s, int count, int yy,
X int xx)
X {
-#ifdef __sparc__
X struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X
+#ifdef __sparc__
X if (fb->mmaped && currcon == fb->vtconsole)
X return;
X #endif
X
- wait_for_idle((struct fb_info_aty *)p->fb_info);
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
X fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
X }
X
+static void fbcon_aty8_clear_margins(struct vc_data *conp, struct display *p,
+ int bottom_only)
+{
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+#ifdef __sparc__
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb8_clear_margins(conp, p, bottom_only);
+}
+
X static struct display_switch fbcon_aty8 = {
X fbcon_cfb8_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty8_putc,
- fbcon_aty8_putcs, fbcon_cfb8_revc, NULL, NULL, fbcon_cfb8_clear_margins,
+ fbcon_aty8_putcs, fbcon_cfb8_revc, NULL, NULL, fbcon_aty8_clear_margins,
X FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
X };
X #endif
@@ -3615,14 +3642,15 @@
X static void fbcon_aty16_putc(struct vc_data *conp, struct display *p, int c,
X int yy, int xx)
X {
-#ifdef __sparc__
X struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X
+#ifdef __sparc__
X if (fb->mmaped && currcon == fb->vtconsole)
X return;
X #endif
X
- wait_for_idle((struct fb_info_aty *)p->fb_info);
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
X fbcon_cfb16_putc(conp, p, c, yy, xx);
X }
X
@@ -3630,20 +3658,36 @@
X const unsigned short *s, int count, int yy,
X int xx)
X {
-#ifdef __sparc__
X struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X
+#ifdef __sparc__
X if (fb->mmaped && currcon == fb->vtconsole)
X return;
X #endif
X
- wait_for_idle((struct fb_info_aty *)p->fb_info);
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
X fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
X }
X
+static void fbcon_aty16_clear_margins(struct vc_data *conp, struct display *p,
+ int bottom_only)
+{
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+#ifdef __sparc__
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb16_clear_margins(conp, p, bottom_only);
+}
+
X static struct display_switch fbcon_aty16 = {
X fbcon_cfb16_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty16_putc,
- fbcon_aty16_putcs, fbcon_cfb16_revc, NULL, NULL, fbcon_cfb16_clear_margins,
+ fbcon_aty16_putcs, fbcon_cfb16_revc, NULL, NULL, fbcon_aty16_clear_margins,
X FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
X };
X #endif
@@ -3652,14 +3696,15 @@
X static void fbcon_aty24_putc(struct vc_data *conp, struct display *p, int c,
X int yy, int xx)
X {
-#ifdef __sparc__
X struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X
+#ifdef __sparc__
X if (fb->mmaped && currcon == fb->vtconsole)
X return;
X #endif
X
- wait_for_idle((struct fb_info_aty *)p->fb_info);
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
X fbcon_cfb24_putc(conp, p, c, yy, xx);
X }
X
@@ -3667,20 +3712,36 @@
X const unsigned short *s, int count, int yy,
X int xx)
X {
-#ifdef __sparc__
X struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X
+#ifdef __sparc__
X if (fb->mmaped && currcon == fb->vtconsole)
X return;
X #endif
X
- wait_for_idle((struct fb_info_aty *)p->fb_info);
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
X fbcon_cfb24_putcs(conp, p, s, count, yy, xx);
X }
X
+static void fbcon_aty24_clear_margins(struct vc_data *conp, struct display *p,
+ int bottom_only)
+{
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+#ifdef __sparc__
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb24_clear_margins(conp, p, bottom_only);
+}
+
X static struct display_switch fbcon_aty24 = {
- fbcon_cfb24_setup, fbcon_cfb24_bmove, fbcon_cfb24_clear, fbcon_aty24_putc,
- fbcon_aty24_putcs, fbcon_cfb24_revc, NULL, NULL, fbcon_cfb24_clear_margins,
+ fbcon_cfb24_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty24_putc,
+ fbcon_aty24_putcs, fbcon_cfb24_revc, NULL, NULL, fbcon_aty24_clear_margins,
X FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
X };
X #endif
@@ -3689,14 +3750,15 @@
X static void fbcon_aty32_putc(struct vc_data *conp, struct display *p, int c,
X int yy, int xx)
X {
-#ifdef __sparc__
X struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X
+#ifdef __sparc__
X if (fb->mmaped && currcon == fb->vtconsole)
X return;
X #endif
X
- wait_for_idle((struct fb_info_aty *)p->fb_info);
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
X fbcon_cfb32_putc(conp, p, c, yy, xx);
X }
X
@@ -3704,20 +3766,36 @@
X const unsigned short *s, int count, int yy,
X int xx)
X {
-#ifdef __sparc__
X struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X
+#ifdef __sparc__
X if (fb->mmaped && currcon == fb->vtconsole)
X return;
X #endif
X
- wait_for_idle((struct fb_info_aty *)p->fb_info);
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
X fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
X }
X
+static void fbcon_aty32_clear_margins(struct vc_data *conp, struct display *p,
+ int bottom_only)
+{
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+#ifdef __sparc__
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ if (fb->blitter_may_be_busy)
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb32_clear_margins(conp, p, bottom_only);
+}
+
X static struct display_switch fbcon_aty32 = {
X fbcon_cfb32_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty32_putc,
- fbcon_aty32_putcs, fbcon_cfb32_revc, NULL, NULL, fbcon_cfb32_clear_margins,
+ fbcon_aty32_putcs, fbcon_cfb32_revc, NULL, NULL, fbcon_aty32_clear_margins,
X FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
X };
X #endif
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/clgenfb.c linux/drivers/video/clgenfb.c
--- v2.2.0-pre8/linux/drivers/video/clgenfb.c Thu Nov 19 09:56:28 1998
+++ linux/drivers/video/clgenfb.c Tue Jan 19 10:47:48 1999
@@ -16,6 +16,7 @@
X #include <asm/amigahw.h>
X #include <asm/pgtable.h>
X #include <asm/delay.h>
+#include <asm/io.h>
X
X #include <video/fbcon.h>
X #include <video/fbcon-mfb.h>
@@ -1533,15 +1534,13 @@
X /* begin of the board, but the begin of RAM. */
X /* for P4, map in its address space in 2 chunks (### TEST! ) */
X /* (note the ugly hardcoded 16M number) */
- fb_info->regs = (unsigned char *)kernel_map(board_addr, 16777216,
- KERNELMAP_NOCACHE_SER, NULL);
+ fb_info->regs = ioremap(board_addr, 16777216);
X DEBUG printk(KERN_INFO "clgen: Virtual address for board set to: $%p\n", fb_info->regs);
X fb_info->regs += 0x600000;
X fb_info->fbregs_phys = board_addr + 0x600000;
X
X fb_info->fbmem_phys = board_addr + 16777216;
- fb_info->fbmem = kernel_map(fb_info->fbmem_phys, 16777216,
- KERNELMAP_NOCACHE_SER, NULL);
+ fb_info->fbmem = ioremap(fb_info->fbmem_phys, 16777216);
X DEBUG printk(KERN_INFO "clgen: (RAM start set to: $%lx)\n", fb_info->fbmem);
X }
X else
@@ -1551,8 +1550,7 @@
X
X fb_info->fbmem_phys = board_addr;
X if (board_addr > 0x01000000)
- fb_info->fbmem = kernel_map(board_addr, board_size,
- KERNELMAP_NOCACHE_SER, NULL);
+ fb_info->fbmem = ioremap(board_addr, board_size);
X else
X fb_info->fbmem = ZTWO_VADDR(board_addr);
X
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/creatorfb.c linux/drivers/video/creatorfb.c
--- v2.2.0-pre8/linux/drivers/video/creatorfb.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/video/creatorfb.c Tue Jan 19 10:48:39 1999
@@ -1,4 +1,4 @@
-/* $Id: creatorfb.c,v 1.16 1998/12/21 05:14:39 davem Exp $
+/* $Id: creatorfb.c,v 1.17 1998/12/28 11:23:37 jj Exp $
X * creatorfb.c: Creator/Creator3D frame buffer driver
X *
X * Copyright (C) 1997,1998 Jakub Jelinek (j...@ultra.linux.cz)
@@ -342,6 +342,7 @@
X register struct ffb_fbc *fbc = fb->s.ffb.fbc;
X int x, y, w, h;
X
+ FFBWait(fbc);
X FFBFifo(fbc, 6);
X fbc->fg = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p,conp)];
X fbc->drawop = FFB_DRAWOP_RECTANGLE;
@@ -360,7 +361,6 @@
X fbc->bx = x + fb->x_margin;
X fbc->bh = h;
X fbc->bw = w;
- FFBWait(fbc);
X }
X
X static void ffb_fill(struct fb_info_sbusfb *fb, struct display *p, int s,
@@ -368,6 +368,7 @@
X {
X register struct ffb_fbc *fbc = fb->s.ffb.fbc;
X
+ FFBWait(fbc);
X FFBFifo(fbc, 2);
X fbc->fg = ((u32 *)p->dispsw_data)[attr_bgcol(p,s)];
X fbc->drawop = FFB_DRAWOP_RECTANGLE;
@@ -379,7 +380,6 @@
X fbc->bw = boxes[2] - boxes[0];
X boxes += 4;
X }
- FFBWait(fbc);
X }
X
X static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
@@ -404,6 +404,7 @@
X xy += (xx << fontwidthlog(p)) + fb->s.ffb.xy_margin;
X else
X xy += (xx * fontwidth(p)) + fb->s.ffb.xy_margin;
+ FFBWait(fbc);
X FFBFifo(fbc, 5);
X fbc->fg = ((u32 *)p->dispsw_data)[attr_fgcol(p,c)];
X fbc->bg = ((u32 *)p->dispsw_data)[attr_bgcol(p,c)];
@@ -420,7 +421,6 @@
X fd += 2;
X }
X }
- FFBWait(fbc);
X }
X
X static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
@@ -431,6 +431,7 @@
X int i, xy;
X u8 *fd1, *fd2, *fd3, *fd4;
X
+ FFBWait(fbc);
X FFBFifo(fbc, 2);
X fbc->fg = ((u32 *)p->dispsw_data)[attr_fgcol(p,*s)];
X fbc->bg = ((u32 *)p->dispsw_data)[attr_bgcol(p,*s)];


@@ -520,7 +521,6 @@
X }

X xy += fontwidth(p);
X }
- FFBWait(fbc);
X }
X
X static void ffb_revc(struct display *p, int xx, int yy)
@@ -618,6 +618,7 @@
X {
X register struct ffb_fbc *fbc = fb->s.ffb.fbc;
X
+ FFBWait(fbc);
X FFBFifo(fbc, 4);
X fbc->ppc = FFB_PPC_VCE_DISABLE|FFB_PPC_TBE_OPAQUE|FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST;
X fbc->fbc = 0x2000707f;
@@ -635,7 +636,9 @@
X struct display *disp = &fb->disp;
X struct fbtype *type = &fb->type;
X struct linux_prom64_registers regs[2*PROMREG_MAX];
- int i;
+ int i, afb = 0;
+ unsigned int btype;
+ char name[64];
X
X if (prom_getproperty(fb->prom_node, "reg", (void *) regs, sizeof(regs)) <= 0)
X return NULL;
@@ -644,10 +647,22 @@
X if (!disp->dispsw_data)
X return NULL;
X memset(disp->dispsw_data, 0, 16 * sizeof(u32));
+
+ prom_getstring(fb->prom_node, "name", name, sizeof(name));
+ if (!strcmp(name, "SUNW,afb"))
+ afb = 1;
X
- strcpy(fb->info.modename, "Creator");
+ btype = prom_getintdefault(fb->prom_node, "board_type", 0);
X
- strcpy(fix->id, "Creator");
+ strcpy(fb->info.modename, "Creator");
+ if (!afb) {
+ if ((btype & 7) == 3)
+ strcpy(fix->id, "Creator 3D");
+ else
+ strcpy(fix->id, "Creator");
+ } else
+ strcpy(fix->id, "Elite 3D");
+
X fix->visual = FB_VISUAL_TRUECOLOR;
X fix->line_length = 8192;
X fix->accel = FB_ACCEL_SUN_CREATOR;
@@ -693,7 +708,7 @@
X
X i = prom_getintdefault (fb->prom_node, "board_type", 8);
X
- sprintf(idstring, "Creator at %016lx type %d DAC %d", regs[0].phys_addr, i, fb->s.ffb.dac_rev);
+ sprintf(idstring, "%s at %016lx type %d DAC %d", fix->id, regs[0].phys_addr, i, fb->s.ffb.dac_rev);
X
X return idstring;
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/cvisionppc.h linux/drivers/video/cvisionppc.h
--- v2.2.0-pre8/linux/drivers/video/cvisionppc.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/cvisionppc.h Tue Jan 19 10:48:17 1999
@@ -0,0 +1,51 @@
+/*
+ * Phase5 CybervisionPPC (TVP4020) definitions for the Permedia2 framebuffer
+ * driver.
+ *
+ * Copyright (c) 1998-1999 Ilario Nardinocchi (nard...@CS.UniBO.IT)
+ * --------------------------------------------------------------------------
+ * $Id: cvisionppc.h,v 1.1.2.1 1999/01/12 19:52:59 geert Exp $
+ * --------------------------------------------------------------------------
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef CVISIONPPC_H
+#define CVISIONPPC_H
+
+#ifndef PM2FB_H
+#include "pm2fb.h"
+#endif
+
+struct cvppc_par {
+ unsigned char* pci_config;
+ unsigned char* pci_bridge;
+ unsigned long user_flags;
+};
+
+#define CSPPC_PCI_BRIDGE 0xfffe0000
+#define CSPPC_BRIDGE_ENDIAN 0x0000
+#define CSPPC_BRIDGE_INT 0x0010
+
+#define CVPPC_PCI_CONFIG 0xfffc0000
+#define CVPPC_ROM_ADDRESS 0xe2000001
+#define CVPPC_REGS_REGION 0xef000000
+#define CVPPC_FB_APERTURE_ONE 0xe0000000
+#define CVPPC_FB_APERTURE_TWO 0xe1000000
+#define CVPPC_FB_SIZE 0x00800000
+#define CVPPC_MEM_CONFIG_OLD 0xed61fcaa /* FIXME Fujitsu?? */
+#define CVPPC_MEM_CONFIG_NEW 0xed41c532 /* FIXME USA?? */
+#define CVPPC_MEMCLOCK 83000 /* in KHz */
+
+/* CVPPC_BRIDGE_ENDIAN */
+#define CSPPCF_BRIDGE_BIG_ENDIAN 0x02
+
+/* CVPPC_BRIDGE_INT */
+#define CSPPCF_BRIDGE_ACTIVE_INT2 0x01
+
+#endif /* CVISIONPPC_H */
+
+/*****************************************************************************
+ * That's all folks!
+ *****************************************************************************/
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/cvppcfb.c linux/drivers/video/cvppcfb.c
--- v2.2.0-pre8/linux/drivers/video/cvppcfb.c Thu Nov 19 09:56:28 1998
+++ linux/drivers/video/cvppcfb.c Wed Dec 31 16:00:00 1969
@@ -1,606 +0,0 @@
-/*
- * CybervisionPPC (TVP4020) low level driver for the frame buffer device
- * ^^^^^^^^^
- * literally ;)
- *
- * Copyright (c) 1998 Ilario Nardinocchi (nard...@CS.UniBO.IT) (v124)
- * --------------------------------------------------------------------------
- * based on linux/drivers/video/skeletonfb.c by Geert Uytterhoeven
- * --------------------------------------------------------------------------
- * TODO h/w parameters detect/modify, 8-bit CLUT, acceleration
- * --------------------------------------------------------------------------
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/malloc.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
-#include <asm/amigahw.h>
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb32.h>
-#include <asm/setup.h>
-#include <asm/io.h>
-
-#define ISDIGIT(a) ((a)>='0' && (a)<='9')
-
-#undef CVPPCFB_MASTER_DEBUG
-#ifdef CVPPCFB_MASTER_DEBUG
-#define FBEGIN if (usr_startup.debug>1)\
- printk(__FUNCTION__ " {\n")
-#define FEND if (usr_startup.debug>1)\
- printk("} /* " __FUNCTION__ " */\n")
-#define DPRINTK(a,b...) if (usr_startup.debug)\
- printk("%s: " a, __FUNCTION__ , ## b)
-#else
-#define FBEGIN
-#define FEND
-#define DPRINTK(a,b...)
-#endif
-
-static const char cvppcfb_name[16]="CybervisionPPC";
-
-struct cvppcfb_startup { /* startup options */
- char font[40];
- u32 xres;
- u32 yres;
- u32 bpp;
- unsigned long debug;
- unsigned long YANW; /* You Are Not Welcome */
- struct fb_monspecs monitor;
-};
-static struct cvppcfb_startup usr_startup = {
- "\0", 640, 480, 16, 0, 1, { 31, 32, 58, 62, 0 } };
-
-#define CVPPC_BASE 0xe0000000
-#define CVPPC_SIZE 0x00800000
-static char* video_base; /* virtual address of board video memory */
-static unsigned long video_phys;/* physical address of board video memory */
-static u32 video_size; /* size of board video memory */
-
-struct cvppcfb_par { /* board parameters (sort of) */
- u32 xres;
- u32 yres;
- u32 vxres;
- u32 vyres;
- u32 vxoff;
- u32 vyoff;
- u32 bpp;
- u32 clock;
- u32 sflags;
- u32 left;
- u32 right;
- u32 top;
- u32 bottom;
- u32 hsynclen;
- u32 vsynclen;
-};
-
-struct cvppcfb_info {
- struct fb_info_gen gen;
- struct cvppcfb_par current_par;
- int current_par_valid;
- struct display disp;
- struct {
- u8 transp;
- u8 red;
- u8 green;
- u8 blue;
- } palette[256];
- union {
-#ifdef FBCON_HAS_CFB16
- u16 cmap16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cmap32[16];
-#endif
- } cmap;
-};
-static struct cvppcfb_info fb_info;
-
-/*
- * declaration of hw switch functions
- */
-static void cvppcfb_detect(void);
-static int cvppcfb_encode_fix(struct fb_fix_screeninfo* fix,
- const void* par, struct fb_info_gen* info);
-static int cvppcfb_decode_var(const struct fb_var_screeninfo* var,
- void* par, struct fb_info_gen* info);
-static int cvppcfb_encode_var(struct fb_var_screeninfo* var,
- const void* par, struct fb_info_gen* info);
-static void cvppcfb_get_par(void* par, struct fb_info_gen* info);
-static void cvppcfb_set_par(const void* par, struct fb_info_gen* info);
-static int cvppcfb_getcolreg(unsigned regno,
- unsigned* red, unsigned* green, unsigned* blue,
- unsigned* transp, struct fb_info* info);
-static int cvppcfb_setcolreg(unsigned regno,
- unsigned red, unsigned green, unsigned blue,
- unsigned transp, struct fb_info* info);
-static void cvppcfb_dispsw(const void* par, struct display* disp,
- struct fb_info_gen* info);
-
-static struct fbgen_hwswitch cvppcfb_hwswitch={
- cvppcfb_detect, cvppcfb_encode_fix, cvppcfb_decode_var,
- cvppcfb_encode_var, cvppcfb_get_par, cvppcfb_set_par,
- cvppcfb_getcolreg, cvppcfb_setcolreg, NULL /* pan_display() */,
- NULL /* blank() */, cvppcfb_dispsw
-};
-
-/*
- * declaration of ops switch functions
- */
-static int cvppcfb_open(struct fb_info* info, int user);
-static int cvppcfb_release(struct fb_info* info, int user);
-
-static struct fb_ops cvppcfb_ops={
- cvppcfb_open, cvppcfb_release, fbgen_get_fix, fbgen_get_var,
- fbgen_set_var, fbgen_get_cmap, fbgen_set_cmap, fbgen_pan_display,
- fbgen_ioctl, NULL /* fb_mmap() */
-};
-
-/*
- * the actual definition of the above mentioned functions follows
- */
-
-/*
- * private functions
- */
-
-static void cvppcfb_set_modename(struct cvppcfb_info* info,
- struct cvppcfb_startup* s) {
-
- strcpy(info->gen.info.modename, cvppcfb_name);
-}
-
-static void cvppcfb_decode_opt(struct cvppcfb_startup* s, void* par,
- struct cvppcfb_info* info) {
- struct cvppcfb_par* p=(struct cvppcfb_par* )par;
-
- memset(p, 0, sizeof(struct cvppcfb_par));
- p->xres=p->vxres=(s->xres+7)&~7;
- p->yres=p->vyres=s->yres;
- p->bpp=(s->bpp+7)&~7;
- if (p->bpp==24)
- p->bpp=32;
- if (p->bpp<32)
- p->clock=6666;
- else
- p->clock=10000;
-}
-
-static void cvppcfb_encode_mcap(char* options, struct fb_monspecs* mcap) {
- char* next;
- int i=0;
-
- while (i<4 && options) {
- if ((next=strchr(options, ';')))
- *(next++)='\0';
- switch (i++) {
- case 0: /* vmin */
- mcap->vfmin=(__u16 )
- simple_strtoul(options, NULL, 0);
- break;
- case 1: /* vmax */
- mcap->vfmax=(__u16 )
- simple_strtoul(options, NULL, 0);
- break;
- case 2: /* hmin */
- mcap->hfmin=(__u32 )
- simple_strtoul(options, NULL, 0);
- break;
- case 3: /* hmax */
- mcap->hfmax=(__u32 )
- simple_strtoul(options, NULL, 0);
- break;
- }
- options=next;
- }
-}
-
-static void cvppcfb_encode_mode(char* options, struct cvppcfb_startup* s) {
- char* next;
- int i=0;
-
- while (i<3 && options) {
- if ((next=strchr(options, ';')))
- *(next++)='\0';
- switch (i++) {
- case 0:
- s->xres=(u32 )
- simple_strtoul(options, NULL, 0);
- break;
- case 1:
- s->yres=(u32 )
- simple_strtoul(options, NULL, 0);
- break;
- case 2:
- s->bpp=(u32 )
- simple_strtoul(options, NULL, 0);
- break;
- }
- options=next;
- }
-}
-
-/*
- * protected functions
- */
-
-static void cvppcfb_detect(void) {
-
- FBEGIN;
- FEND;
-}
-
-static int cvppcfb_encode_fix(struct fb_fix_screeninfo* fix,
- const void* par, struct fb_info_gen* info) {
-
- FBEGIN;
- strcpy(fix->id, cvppcfb_name);
- fix->smem_start=(char* )video_phys;
- fix->smem_len=(__u32 )video_size;
- fix->type=FB_TYPE_PACKED_PIXELS;
- if (((struct cvppcfb_par* )par)->bpp==8)
- fix->visual=FB_VISUAL_PSEUDOCOLOR;
- else
- fix->visual=FB_VISUAL_TRUECOLOR;
- fix->xpanstep=fix->ypanstep=fix->ywrapstep=0;
- fix->line_length=0; /* computed by fbcon */
- fix->mmio_start=NULL;
- fix->mmio_len=0;
- fix->accel=FB_ACCEL_NONE;
- FEND;


- return 0;
-}
-

-static int cvppcfb_decode_var(const struct fb_var_screeninfo* var,
- void* par, struct fb_info_gen* info) {
- struct cvppcfb_par p;
-
- FBEGIN;
- memset(&p, 0, sizeof(struct cvppcfb_par));
- p.bpp=(var->bits_per_pixel+7)&~7;
- if (p.bpp==24)
- p.bpp=32;
- if (p.bpp>32) {
- DPRINTK("depth too big (%lu)\n", p.bpp);
- return -EINVAL;
- }
- p.xres=(var->xres+7)&~7;
- p.yres=var->yres;
- if (p.xres<320 || p.yres<200 || p.xres>2048 || p.yres>2048) {
- DPRINTK("bad resolution (%lux%lu)\n", p.xres, p.yres);
- return -EINVAL;
- }
- p.vxres=(var->xres_virtual+7)&~7;
- p.vxoff=(var->xoffset+7)&~7;
- p.vyres=var->yres_virtual;
- p.vyoff=var->yoffset;
- if (p.vxres<p.xres+p.vxoff)
- p.vxres=p.xres+p.vxoff;
- if (p.vyres<p.yres+p.vyoff)
- p.vyres=p.yres+p.vyoff;
- if (p.vxres*p.vyres*p.bpp/8>video_size) {
- DPRINTK("no memory for screen (%lux%lux%lu)\n",
- p.vxres, p.vyres, p.bpp);
- return -EINVAL;
- }
- p.sflags=var->sync&(FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT);
- p.clock=var->pixclock;
- if (p.clock<6666) {
- DPRINTK("pixclock too fast (%lu)\n", p.clock);
- return -EINVAL;
- }
- p.left=var->left_margin;
- p.top=var->upper_margin;
- p.right=var->right_margin;
- p.bottom=var->lower_margin;
- p.hsynclen=var->hsync_len;
- p.vsynclen=var->vsync_len;
- *((struct cvppcfb_par* )par)=p;
- FEND;


- return 0;
-}
-

-static int cvppcfb_encode_var(struct fb_var_screeninfo* var,
- const void* par, struct fb_info_gen* info) {
- struct cvppcfb_par* p=(struct cvppcfb_par* )par;
- struct fb_var_screeninfo v;
-
- FBEGIN;
- memset(&v, 0, sizeof(struct fb_var_screeninfo));
- v.xres=p->xres;
- v.yres=p->yres;
- v.xres_virtual=p->vxres;
- v.yres_virtual=p->vyres;
- v.xoffset=p->vxoff;
- v.yoffset=p->vyoff;
- v.bits_per_pixel=p->bpp;
- switch (p->bpp) {
- case 16:
- v.red.offset=11;
- v.red.length=5;
- v.green.offset=5;
- v.green.length=6;
- v.blue.length=5;
- break;
- case 32:
- v.transp.offset=24;
- v.red.offset=16;
- v.green.offset=8;
- v.transp.length=8;
- /* fallback */
- case 8:
- v.red.length=v.green.length=v.blue.length=8;
- break;
- }
- v.activate=FB_ACTIVATE_NOW;
- v.height=v.width=-1;
- v.pixclock=p->clock;
- v.left_margin=p->left;
- v.right_margin=p->right;
- v.upper_margin=p->top;
- v.lower_margin=p->bottom;
- v.hsync_len=p->hsynclen;
- v.vsync_len=p->vsynclen;
- v.sync=p->sflags;
- v.vmode=FB_VMODE_NONINTERLACED;
- *var=v;
- FEND;


- return 0;
-}
-

-static void cvppcfb_get_par(void* par, struct fb_info_gen* info) {
- struct cvppcfb_info* i=(struct cvppcfb_info* )info;
-
- FBEGIN;
- if (i->current_par_valid)
- *((struct cvppcfb_par* )par)=i->current_par;
- else
- cvppcfb_decode_opt(&usr_startup, par, i);
- FEND;
-}
-
-static void cvppcfb_set_par(const void* par, struct fb_info_gen* info) {
- struct cvppcfb_info* i=(struct cvppcfb_info* )info;
-
- FBEGIN;
- i->current_par=*((struct cvppcfb_par* )par);
- i->current_par_valid=1;
- FEND;
-}
-
-static int cvppcfb_getcolreg(unsigned regno,
- unsigned* red, unsigned* green, unsigned* blue,
- unsigned* transp, struct fb_info* info) {
- struct cvppcfb_info* i=(struct cvppcfb_info* )info;
-
- if (regno<256) {
- *red=i->palette[regno].red<<8|i->palette[regno].red;
- *green=i->palette[regno].green<<8|i->palette[regno].green;
- *blue=i->palette[regno].blue<<8|i->palette[regno].blue;
- *transp=i->palette[regno].transp<<8|i->palette[regno].transp;
- }
- return regno>255;
-}
-
-static int cvppcfb_setcolreg(unsigned regno,
- unsigned red, unsigned green, unsigned blue,


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 07'
echo 'File patch-2.2.0-pre9 is continued in part 08'
echo 08 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part08

#!/bin/sh
# this is part 08 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 08; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

- unsigned transp, struct fb_info* info) {


- struct cvppcfb_info* i=(struct cvppcfb_info* )info;
-

- if (regno<16) {
- switch (i->current_par.bpp) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- DPRINTK("8 bit depth not supported yet.\n");
- return 1;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- i->cmap.cmap16[regno]=
- ((u32 )red & 0xf800) |
- (((u32 )green & 0xfc00)>>5) |
- (((u32 )blue & 0xf800)>>11);
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- i->cmap.cmap32[regno]=
- (((u32 )transp & 0xff00) << 16) |
- (((u32 )red & 0xff00) << 8) |
- (((u32 )green & 0xff00)) |
- (((u32 )blue & 0xff00) >> 8);
- break;
-#endif
- }


- }
- if (regno<256) {

- i->palette[regno].red=red >> 8;
- i->palette[regno].green=green >> 8;
- i->palette[regno].blue=blue >> 8;
- i->palette[regno].transp=transp >> 8;


- }
- return regno>255;
-}
-

-static void cvppcfb_dispsw(const void* par, struct display* disp,
- struct fb_info_gen* info) {

- struct cvppcfb_info* i=(struct cvppcfb_info* )info;

- unsigned long flags;
-
- FBEGIN;
- save_flags(flags);
- cli();
- switch (((struct cvppcfb_par* )par)->bpp) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- disp->dispsw=&fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- disp->dispsw=&fbcon_cfb16;
- disp->dispsw_data=i->cmap.cmap16;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- disp->dispsw=&fbcon_cfb32;
- disp->dispsw_data=i->cmap.cmap32;
- break;
-#endif
- default:
- disp->dispsw=&fbcon_dummy;
- break;
- }
- restore_flags(flags);
- FEND;
-}
-
-static int cvppcfb_open(struct fb_info* info, int user) {
-
- MOD_INC_USE_COUNT;


- return 0;
-}
-

-static int cvppcfb_release(struct fb_info* info, int user) {
-

- MOD_DEC_USE_COUNT;


- return 0;
-}
-

-/*
- * public functions
- */
-
-void cvppcfb_cleanup(struct fb_info* info) {
-
- unregister_framebuffer(info);
-}
-
-__initfunc(void cvppcfb_init(void)) {
-
- FBEGIN;
-#ifdef CVPPCFB_MASTER_DEBUG
- printk("cvppcfb_init():\n");
- printk(" resolution %ldx%ldx%ld\n", usr_startup.xres,
- usr_startup.yres, usr_startup.bpp);
- printk(" debug: %ld, YANW: %ld\n", usr_startup.debug,
- usr_startup.YANW);
- printk(" monitorcap: %ld,%ld,%ld,%ld\n",
- usr_startup.monitor.vfmin, usr_startup.monitor.vfmax,
- usr_startup.monitor.hfmin, usr_startup.monitor.hfmax);
-#endif
- if (usr_startup.YANW) /* cannot probe yet */
- return;
- memset(&fb_info, 0, sizeof(struct cvppcfb_info));
- video_size=CVPPC_SIZE;
- video_phys=CVPPC_BASE;
-#ifdef CONFIG_APUS
- video_base=(char* )
- kernel_map(video_phys, video_size, KERNELMAP_NOCACHE_SER, NULL);
-#else
- video_base=ioremap(video_phys, video_size);
-#endif
- DPRINTK("video_phys=%08lx, video_base=%08lx\n", video_phys, video_base);
- DPRINTK("phys_to_virt(video_phys)=%08lx\n", phys_to_virt(video_phys));
- DPRINTK("virt_to_phys(video_base)=%08lx\n", virt_to_phys(video_base));
- fb_info.disp.scrollmode=SCROLL_YREDRAW;
- fb_info.gen.parsize=sizeof(struct cvppcfb_par);
- fb_info.gen.fbhw=&cvppcfb_hwswitch;
- cvppcfb_set_modename(&fb_info, &usr_startup);
- fb_info.gen.info.flags=FBINFO_FLAG_DEFAULT;
- fb_info.gen.info.fbops=&cvppcfb_ops;
- fb_info.gen.info.monspecs=usr_startup.monitor;
- fb_info.gen.info.disp=&fb_info.disp;
- strcpy(fb_info.gen.info.fontname, usr_startup.font);
- fb_info.gen.info.switch_con=&fbgen_switch;
- fb_info.gen.info.updatevar=&fbgen_update_var;
- fb_info.gen.info.blank=&fbgen_blank;
- fbgen_get_var(&fb_info.disp.var, -1, &fb_info.gen.info);
- if (fbgen_do_set_var(&fb_info.disp.var, 1, &fb_info.gen)<0) {
- printk( "cvppcfb: bad startup configuration: "
- "unable to register.\n");
- return;
- }
- fbgen_set_disp(-1, &fb_info.gen);
- fbgen_install_cmap(0, &fb_info.gen);
- if (register_framebuffer(&fb_info.gen.info)<0) {
- printk("cvppcfb: unable to register.\n");
- return;
- }
- printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
- GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename,
- (unsigned long )(video_size>>10));
- MOD_INC_USE_COUNT;
- FEND;
-}
-
-__initfunc(void cvppcfb_setup(char* options, int* ints)) {
- char* next;
-
- usr_startup.YANW=0;
- DPRINTK("options: '%s'\n", options);
- while (options) {
- if ((next=strchr(options, ',')))
- *(next++)='\0';
- if (!strncmp(options, "monitorcap:", 11))
- cvppcfb_encode_mcap(options+11, &usr_startup.monitor);
- else if (!strncmp(options, "debug:", 6)) {
- if (ISDIGIT(options[6]))
- usr_startup.debug=options[6]-'0';
- else
- usr_startup.debug=1;
- }
- else if (!strncmp(options, "mode:", 5))
- cvppcfb_encode_mode(options+5, &usr_startup);
- else if (!strncmp(options, "font:", 5))
- strcpy(usr_startup.font, options+5);
- else
- DPRINTK("unrecognized option '%s'\n", options);
- options=next;
- }
-#ifdef CVPPCFB_MASTER_DEBUG
- printk("cvppcfb_setup():\n");
- printk(" resolution %ldx%ldx%ld\n", usr_startup.xres,
- usr_startup.yres, usr_startup.bpp);
- printk(" debug: %ld, YANW: %ld\n", usr_startup.debug,
- usr_startup.YANW);
- printk(" monitorcap: %ld,%ld,%ld,%ld\n",
- usr_startup.monitor.vfmin, usr_startup.monitor.vfmax,
- usr_startup.monitor.hfmin, usr_startup.monitor.hfmax);
-#endif
-}
-
-/*
- * modularization
- */
-
-#ifdef MODULE
-int init_module(void) {
-
- cvppcfb_init();
-}
-
-void cleanup_module(void) {
-
- cvppcfb_cleanup();
-}
-#endif /* MODULE */
-
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/cyberfb.c linux/drivers/video/cyberfb.c
--- v2.2.0-pre8/linux/drivers/video/cyberfb.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/video/cyberfb.c Tue Jan 19 10:47:48 1999
@@ -1146,8 +1146,7 @@
X DPRINTK("board_addr=%08lx\n", board_addr);
X DPRINTK("board_size=%08lx\n", board_size);
X
- cv64_mem = kernel_map (board_addr, board_size, KERNELMAP_NOCACHE_SER,
- NULL);
+ cv64_mem = ioremap(board_addr, board_size);
X cv64_regs = (volatile char *)(cv64_mem + 0x02000000);
X cv64_fbmem = cv64_mem + 0x01400000;
X DPRINTK("cv64_mem=%08lx cv64_regs=%08lx cv64_fbmem=%08lx\n",
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/fbcon-iplan2p2.c linux/drivers/video/fbcon-iplan2p2.c
--- v2.2.0-pre8/linux/drivers/video/fbcon-iplan2p2.c Fri Nov 27 13:09:27 1998
+++ linux/drivers/video/fbcon-iplan2p2.c Tue Jan 19 10:47:48 1999
@@ -10,7 +10,6 @@
X * more details.


X */
X
-#include <linux/config.h>

X #include <linux/module.h>
X #include <linux/tty.h>
X #include <linux/console.h>
@@ -18,6 +17,7 @@
X #include <linux/fb.h>
X
X #include <asm/byteorder.h>
+#include <asm/setup.h>
X
X #include <video/fbcon.h>
X #include <video/fbcon-iplan2p2.h>
@@ -43,7 +43,7 @@
X /* Perform the m68k movepw operation. */
X static inline void movepw(u8 *d, u16 val)
X {
-#if defined __mc68000__ && !defined CONFIG_OPTIMIZE_060
+#if defined __mc68000__ && !defined CPU_M68060_ONLY
X asm volatile ("movepw %1,%0@(0)" : : "a" (d), "d" (val));
X #else
X d[0] = (val >> 16) & 0xff;
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/fbcon-iplan2p4.c linux/drivers/video/fbcon-iplan2p4.c
--- v2.2.0-pre8/linux/drivers/video/fbcon-iplan2p4.c Fri Nov 27 13:09:27 1998
+++ linux/drivers/video/fbcon-iplan2p4.c Tue Jan 19 10:47:48 1999
@@ -10,7 +10,6 @@
X * more details.


X */
X
-#include <linux/config.h>

X #include <linux/module.h>
X #include <linux/tty.h>
X #include <linux/console.h>
@@ -18,6 +17,7 @@
X #include <linux/fb.h>
X
X #include <asm/byteorder.h>
+#include <asm/setup.h>
X
X #include <video/fbcon.h>
X #include <video/fbcon-iplan2p4.h>
@@ -35,7 +35,7 @@
X /* Perform the m68k movepl operation. */
X static inline void movepl(u8 *d, u32 val)
X {
-#if defined __mc68000__ && !defined CONFIG_OPTIMIZE_060
+#if defined __mc68000__ && !defined CPU_M68060_ONLY
X asm volatile ("movepl %1,%0@(0)" : : "a" (d), "d" (val));
X #else
X d[0] = (val >> 24) & 0xff;
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/fbcon-iplan2p8.c linux/drivers/video/fbcon-iplan2p8.c
--- v2.2.0-pre8/linux/drivers/video/fbcon-iplan2p8.c Fri Nov 27 13:09:27 1998
+++ linux/drivers/video/fbcon-iplan2p8.c Tue Jan 19 10:47:48 1999
@@ -10,7 +10,6 @@
X * more details.


X */
X
-#include <linux/config.h>

X #include <linux/module.h>
X #include <linux/tty.h>
X #include <linux/console.h>
@@ -18,6 +17,7 @@
X #include <linux/fb.h>
X
X #include <asm/byteorder.h>
+#include <asm/setup.h>
X
X #include <video/fbcon.h>
X #include <video/fbcon-iplan2p8.h>
@@ -40,7 +40,7 @@
X /* Perform the m68k movepl operation extended to 64 bits. */
X static inline void movepl2(u8 *d, u32 val1, u32 val2)
X {
-#if defined __mc68000__ && !defined CONFIG_OPTIMIZE_060
+#if defined __mc68000__ && !defined CPU_M68060_ONLY
X asm volatile ("movepl %1,%0@(0); movepl %2,%0@(8)"
X : : "a" (d), "d" (val1), "d" (val2));
X #else
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
--- v2.2.0-pre8/linux/drivers/video/fbcon.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/video/fbcon.c Tue Jan 19 10:47:48 1999
@@ -536,13 +536,14 @@
X conp->vc_can_do_color = p->var.bits_per_pixel != 1;
X conp->vc_complement_mask = conp->vc_can_do_color ? 0x7700 : 0x0800;
X if (charcnt == 256) {
- p->conp->vc_hi_font_mask = 0;
+ conp->vc_hi_font_mask = 0;
X p->fgshift = 8;
X p->bgshift = 12;
X p->charmask = 0xff;
X } else {
- p->conp->vc_hi_font_mask = 0x100;
- p->conp->vc_complement_mask <<= 1;
+ conp->vc_hi_font_mask = 0x100;
+ if (conp->vc_can_do_color)
+ conp->vc_complement_mask <<= 1;
X p->fgshift = 9;
X p->bgshift = 13;
X p->charmask = 0x1ff;
@@ -1333,13 +1334,14 @@
X p->_fontheight = h;
X if (p->conp->vc_hi_font_mask && cnt == 256) {
X p->conp->vc_hi_font_mask = 0;
- p->conp->vc_complement_mask >>= 1;
+ if (p->conp->vc_can_do_color)
+ p->conp->vc_complement_mask >>= 1;
X p->fgshift--;
X p->bgshift--;
X p->charmask = 0xff;
X
X /* ++Edmund: reorder the attribute bits */
- {
+ if (p->conp->vc_can_do_color) {
X struct vc_data *conp = p->conp;
X unsigned short *cp = (unsigned short *) conp->vc_origin;
X int count = conp->vc_screenbuf_size/2;
@@ -1355,7 +1357,8 @@
X
X } else if (!p->conp->vc_hi_font_mask && cnt == 512) {
X p->conp->vc_hi_font_mask = 0x100;
- p->conp->vc_complement_mask <<= 1;
+ if (p->conp->vc_can_do_color)
+ p->conp->vc_complement_mask <<= 1;
X p->fgshift++;
X p->bgshift++;
X p->charmask = 0x1ff;
@@ -1367,12 +1370,20 @@
X int count = conp->vc_screenbuf_size/2;
X unsigned short c;
X for (; count > 0; count--, cp++) {
+ unsigned short newc;
X c = scr_readw(cp);
- scr_writew(((c & 0xff00) << 1) | (c & 0xff), cp);
+ if (conp->vc_can_do_color)
+ newc = ((c & 0xff00) << 1) | (c & 0xff);
+ else
+ newc = c & ~0x100;
+ scr_writew(newc, cp);
X }
X c = conp->vc_video_erase_char;
- conp->vc_video_erase_char = ((c & 0xff00) << 1) | (c & 0xff);
- conp->vc_attr <<= 1;
+ if (conp->vc_can_do_color) {
+ conp->vc_video_erase_char = ((c & 0xff00) << 1) | (c & 0xff);
+ conp->vc_attr <<= 1;
+ } else
+ conp->vc_video_erase_char = c & ~0x100;
X }
X
X }
@@ -1420,7 +1431,10 @@
X int w = op->width;
X int h = op->height;
X int size = h;
- int i, j, k;
+ int i, k;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ int j;
+#endif
X u8 *new_data, *data = op->data, *p;
X
X #ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
@@ -1837,7 +1851,7 @@
X int line_length = p->line_length;
X
X /* for support of Atari interleaved planes */
-#define MAP_X(x) (line_length ? x : (x & ~1)*depth + (x & 1))
+#define MAP_X(x) (line_length ? (x) : ((x) & ~1)*depth + ((x) & 1))
X #else
X #define MAP_X(x) (x)
X #endif
@@ -1848,7 +1862,7 @@
X src = logo;
X for( y1 = 0; y1 < LOGO_H; y1++ ) {
X for( x1 = 0; x1 < LOGO_LINE; x1++, src += logo_depth ) {
- dst = fb + y1*line + MAP_X(x1);
+ dst = fb + y1*line + MAP_X(x/8+x1);
X for( bit = 0; bit < logo_depth; bit++ ) {
X val = 0;
X for( mask = 0x80, i = 0; i < 8; mask >>= 1, i++ ) {
@@ -1867,7 +1881,7 @@
X if (depth > logo_depth) {
X for( y1 = 0; y1 < LOGO_H; y1++ ) {
X for( x1 = 0; x1 < LOGO_LINE; x1++ ) {
- dst = fb + y1*line + MAP_X(x1) + logo_depth*plane;
+ dst = fb + y1*line + MAP_X(x/8+x1) + logo_depth*plane;
X for( i = logo_depth; i < depth; i++, dst += plane )
X *dst = (i == logo_depth && logo_depth == 4)
X ? 0xff : 0x00;
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- v2.2.0-pre8/linux/drivers/video/fbmem.c Wed Jan 13 15:00:43 1999
+++ linux/drivers/video/fbmem.c Tue Jan 19 10:48:17 1999
@@ -54,8 +54,8 @@
X extern void macfb_setup(char *options, int *ints);
X extern void cyberfb_init(void);
X extern void cyberfb_setup(char *options, int *ints);
-extern void cvppcfb_init(void);
-extern void cvppcfb_setup(char *options, int *ints);
+extern void pm2fb_init(void);
+extern void pm2fb_setup(char *options, int *ints);
X extern void retz3fb_init(void);
X extern void retz3fb_setup(char *options, int *ints);
X extern void clgenfb_init(void);
@@ -112,8 +112,8 @@
X #ifdef CONFIG_FB_CYBER
X { "cyber", cyberfb_init, cyberfb_setup },
X #endif
-#ifdef CONFIG_FB_CVPPC
- { "cvppcfb", cvppcfb_init, cvppcfb_setup },
+#ifdef CONFIG_FB_PM2
+ { "pm2fb", pm2fb_init, pm2fb_setup },
X #endif
X #ifdef CONFIG_FB_CLGEN
X { "clgen", clgenfb_init, clgenfb_setup },
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/offb.c linux/drivers/video/offb.c
--- v2.2.0-pre8/linux/drivers/video/offb.c Thu Jan 7 15:11:38 1999
+++ linux/drivers/video/offb.c Tue Jan 19 10:48:41 1999
@@ -400,8 +400,10 @@
X }
X #endif /* CONFIG_FB_ATY */
X #ifdef CONFIG_FB_S3TRIO
- if (s3triofb_init_of(dp))
+ if (!strncmp(dp->name, "S3Trio", 6)) {
+ s3triofb_init_of(dp);
X return 1;
+ }
X #endif /* CONFIG_FB_S3TRIO */
X #ifdef CONFIG_FB_IMSTT
X if (!strncmp(dp->name, "IMS,tt", 6)) {
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/pm2fb.c linux/drivers/video/pm2fb.c
--- v2.2.0-pre8/linux/drivers/video/pm2fb.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/pm2fb.c Tue Jan 19 10:48:17 1999
@@ -0,0 +1,1494 @@
+/*
+ * Permedia2 framebuffer driver.


+ * Copyright (c) 1998-1999 Ilario Nardinocchi (nard...@CS.UniBO.IT)

+ * Based on linux/drivers/video/skeletonfb.c by Geert Uytterhoeven.
+ * --------------------------------------------------------------------------
+ * $Id: pm2fb.c,v 1.1.2.1 1999/01/12 19:53:02 geert Exp $


+ * --------------------------------------------------------------------------
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+

+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/selection.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "pm2fb.h"
+#ifdef CONFIG_FB_PM2_CVPPC
+#include "cvisionppc.h"
+#endif
+
+#if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
+#error "The endianness of the target host has not been defined."
+#endif
+
+#undef PM2FB_MASTER_DEBUG
+#ifdef PM2FB_MASTER_DEBUG
+#define DPRINTK(a,b...) printk("pm2fb: %s: " a, __FUNCTION__ , ## b)
+#else
+#define DPRINTK(a,b...)
+#endif
+
+#define PICOS2KHZ(a) (1000000000UL/(a))
+#define KHZ2PICOS(a) (1000000000UL/(a))
+
+#ifdef CONFIG_APUS
+#define MMAP(a,b) (unsigned char* )kernel_map((unsigned long )(a), \
+ b, KERNELMAP_NOCACHE_SER, NULL)
+#else
+#define MMAP(a,b) ioremap(a, b)
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
+#ifndef __powerpc__
+#define eieio()
+#endif
+
+struct pm2fb_par {
+ unsigned long pixclock; /* pixclock in KHz */
+ unsigned long width; /* width of virtual screen */
+ unsigned long height; /* height of virtual screen */
+ unsigned long hsstart; /* horiz. sync start */
+ unsigned long hsend; /* horiz. sync end */
+ unsigned long hbend; /* horiz. blank end (also gate end) */
+ unsigned long htotal; /* total width (w/ sync & blank) */
+ unsigned long vsstart; /* vert. sync start */
+ unsigned long vsend; /* vert. sync end */
+ unsigned long vbend; /* vert. blank end */
+ unsigned long vtotal; /* total height (w/ sync & blank) */
+ unsigned long stride; /* screen stride */
+ unsigned long base; /* screen base (xoffset+yoffset) */
+ unsigned long depth; /* screen depth (8, 16, 24 or 32) */
+ unsigned long video; /* video control (hsync,vsync) */
+};
+
+#define OPTF_OLD_MEM 0x00000001
+#define OPTF_YPAN 0x00000002
+static struct {
+ char font[40];
+ unsigned long flags;
+ struct pm2fb_par user_mode;
+} pm2fb_options;
+
+static const struct {
+ char name[16];
+ struct pm2fb_par par;
+} user_mode[] __initdata = {
+ {"640x480-60",
+ {25174,640,480,4,28,40,199,9,11,45,524,80,0,8,121}},
+ {"640x480-72",
+ {31199,640,480,6,16,48,207,8,10,39,518,80,0,8,121}},
+ {"640x480-75",
+ {31499,640,480,4,20,50,209,0,3,20,499,80,0,8,121}},
+ {"640x480-90",
+ {39909,640,480,8,18,48,207,24,38,53,532,80,0,8,121}},
+ {"640x480-100",
+ {44899,640,480,8,40,52,211,21,33,51,530,80,0,8,121}},
+ {"800x600-56",
+ {35999,800,600,6,24,56,255,0,2,25,624,100,0,8,41}},
+ {"800x600-60",
+ {40000,800,600,10,42,64,263,0,4,28,627,100,0,8,41}},
+ {"800x600-70",
+ {44899,800,600,6,42,52,251,8,20,36,635,100,0,8,105}},
+ {"800x600-72",
+ {50000,800,600,14,44,60,259,36,42,66,665,100,0,8,41}},
+ {"800x600-75",
+ {49497,800,600,4,24,64,263,0,3,25,624,100,0,8,41}},
+ {"800x600-90",
+ {56637,800,600,2,18,48,247,7,18,35,634,100,0,8,41}},
+ {"800x600-100",
+ {67499,800,600,0,16,70,269,6,10,25,624,100,0,8,41}},
+ {"1024x768-60",
+ {64998,1024,768,6,40,80,335,2,8,38,805,128,0,8,121}},
+ {"1024x768-70",
+ {74996,1024,768,6,40,76,331,2,8,38,805,128,0,8,121}},
+ {"1024x768-72",
+ {74996,1024,768,6,40,66,321,2,8,38,805,128,0,8,121}},
+ {"1024x768-75",
+ {78932,1024,768,4,28,72,327,0,3,32,799,128,0,8,41}},
+ {"1024x768-90",
+ {100000,1024,768,0,24,72,327,20,35,77,844,128,0,8,121}},
+ {"1024x768-100",
+ {109998,1024,768,0,22,92,347,0,7,24,791,128,0,8,121}},
+ {"1024x768-illo",
+ {120322,1024,768,12,48,120,375,3,7,32,799,128,0,8,41}},
+ {"1152x864-60",
+ {80000,1152,864,16,44,76,363,5,10,52,915,144,0,8,41}},
+ {"1152x864-70",
+ {100000,1152,864,10,48,90,377,12,23,81,944,144,0,8,41}},
+ {"1152x864-75",
+ {109998,1152,864,6,42,78,365,44,52,138,1001,144,0,8,41}},
+ {"1152x864-80",
+ {109998,1152,864,4,32,72,359,29,36,94,957,144,0,8,41}},
+ {"1280x1024-60",
+ {107991,1280,1024,12,40,102,421,0,3,42,1065,160,0,8,41}},
+ {"1280x1024-70",
+ {125992,1280,1024,20,48,102,421,0,5,42,1065,160,0,8,41}},
+ {"1280x1024-74",
+ {134989,1280,1024,8,44,108,427,0,29,40,1063,160,0,8,41}},
+ {"1280x1024-75",
+ {134989,1280,1024,4,40,102,421,0,3,42,1065,160,0,8,41}},
+ {"1600x1200-60",
+ {155981,1600,1200,8,48,112,511,9,17,70,1269,200,0,8,121}},
+ {"1600x1200-66",
+ {171998,1600,1200,10,44,120,519,2,5,53,1252,200,0,8,121}},
+ {"1600x1200-76",
+ {197980,1600,1200,10,44,120,519,2,7,50,1249,200,0,8,121}},
+ {"\0", },
+};
+
+static const char permedia2_name[16]="Permedia2";
+
+static struct pm2fb_info {
+ struct fb_info_gen gen;
+ int board; /* Permedia2 board index (see
+ board_table[] below) */
+ struct {
+ unsigned char* fb_base; /* framebuffer memory base */
+ unsigned long fb_size; /* framebuffer memory size */
+ unsigned char* rg_base; /* register memory base */
+ unsigned char* p_fb; /* physical address of frame buffer */
+ unsigned char* v_fb; /* virtual address of frame buffer */
+ unsigned char* p_regs; /* physical address of registers
+ region, must be rg_base or
+ rg_base+PM2_REGS_SIZE depending on
+ the host endianness */
+ unsigned char* v_regs; /* virtual address of p_regs */
+ } regions;
+ union { /* here, the per-board par structs */
+#ifdef CONFIG_FB_PM2_CVPPC
+ struct cvppc_par cvppc; /* CVisionPPC data */
+#endif
+ } board_par;
+ struct pm2fb_par current_par; /* displayed screen */
+ int current_par_valid;
+ unsigned long memclock; /* memclock (set by the per-board
+ init routine) */
+ struct display disp;
+ struct {
+ u8 transp;
+ u8 red;
+ u8 green;
+ u8 blue;
+ } palette[256];
+ union {
+#ifdef FBCON_HAS_CFB16
+ u16 cmap16[16];
+#endif
+#ifdef FBCON_HAS_CFB24
+ u32 cmap24[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+ u32 cmap32[16];
+#endif
+ } cmap;
+} fb_info;
+
+#ifdef CONFIG_FB_PM2_CVPPC
+static int cvppc_detect(struct pm2fb_info*);
+static void cvppc_init(struct pm2fb_info*);
+#endif
+
+/*
+ * Table of the supported Permedia2 based boards.
+ * Three hooks are defined for each board:
+ * detect(): should return 1 if the related board has been detected, 0
+ * otherwise. It should also fill the fields 'regions.fb_base',
+ * 'regions.fb_size', 'regions.rg_base' and 'memclock' in the
+ * passed pm2fb_info structure.
+ * init(): called immediately after the reset of the Permedia2 chip.
+ * It should reset the memory controller if needed (the MClk
+ * is set shortly afterwards by the caller).
+ * cleanup(): called after the driver has been unregistered.
+ *
+ * the init and cleanup pointers can be NULL.
+ */
+static const struct {
+ int (*detect)(struct pm2fb_info*);
+ void (*init)(struct pm2fb_info*);
+ void (*cleanup)(struct pm2fb_info*);
+ char name[32];
+} board_table[] = {
+#ifdef CONFIG_FB_PM2_CVPPC
+ { cvppc_detect, cvppc_init, NULL, "CVisionPPC/BVisionPPC" },
+#endif
+ { NULL, }
+};
+
+/*
+ * partial products for the supported horizontal resolutions.
+ */
+#define PACKPP(p0,p1,p2) (((p2)<<6)|((p1)<<3)|(p0))
+static const struct {
+ unsigned short width;
+ unsigned short pp;
+} pp_table[] = {
+ { 32, PACKPP(1, 0, 0) }, { 64, PACKPP(1, 1, 0) },
+ { 96, PACKPP(1, 1, 1) }, { 128, PACKPP(2, 1, 1) },
+ { 160, PACKPP(2, 2, 1) }, { 192, PACKPP(2, 2, 2) },
+ { 224, PACKPP(3, 2, 1) }, { 256, PACKPP(3, 2, 2) },
+ { 288, PACKPP(3, 3, 1) }, { 320, PACKPP(3, 3, 2) },
+ { 384, PACKPP(3, 3, 3) }, { 416, PACKPP(4, 3, 1) },
+ { 448, PACKPP(4, 3, 2) }, { 512, PACKPP(4, 3, 3) },
+ { 544, PACKPP(4, 4, 1) }, { 576, PACKPP(4, 4, 2) },
+ { 640, PACKPP(4, 4, 3) }, { 768, PACKPP(4, 4, 4) },
+ { 800, PACKPP(5, 4, 1) }, { 832, PACKPP(5, 4, 2) },
+ { 896, PACKPP(5, 4, 3) }, { 1024, PACKPP(5, 4, 4) },
+ { 1056, PACKPP(5, 5, 1) }, { 1088, PACKPP(5, 5, 2) },
+ { 1152, PACKPP(5, 5, 3) }, { 1280, PACKPP(5, 5, 4) },
+ { 1536, PACKPP(5, 5, 5) }, { 1568, PACKPP(6, 5, 1) },
+ { 1600, PACKPP(6, 5, 2) }, { 1664, PACKPP(6, 5, 3) },
+ { 1792, PACKPP(6, 5, 4) }, { 2048, PACKPP(6, 5, 5) },
+ { 0, 0 } };
+
+static void pm2fb_detect(void);
+static int pm2fb_encode_fix(struct fb_fix_screeninfo* fix,
+ const void* par, struct fb_info_gen* info);
+static int pm2fb_decode_var(const struct fb_var_screeninfo* var,
+ void* par, struct fb_info_gen* info);
+static int pm2fb_encode_var(struct fb_var_screeninfo* var,
+ const void* par, struct fb_info_gen* info);
+static void pm2fb_get_par(void* par, struct fb_info_gen* info);
+static void pm2fb_set_par(const void* par, struct fb_info_gen* info);
+static int pm2fb_getcolreg(unsigned regno,
+ unsigned* red, unsigned* green, unsigned* blue,
+ unsigned* transp, struct fb_info* info);
+static int pm2fb_setcolreg(unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info* info);
+static int pm2fb_blank(int blank_mode, struct fb_info_gen* info);
+static int pm2fb_pan_display(const struct fb_var_screeninfo* var,
+ struct fb_info_gen* info);
+static void pm2fb_dispsw(const void* par, struct display* disp,
+ struct fb_info_gen* info);
+
+static struct fbgen_hwswitch pm2fb_hwswitch={
+ pm2fb_detect, pm2fb_encode_fix, pm2fb_decode_var,
+ pm2fb_encode_var, pm2fb_get_par, pm2fb_set_par,
+ pm2fb_getcolreg, pm2fb_setcolreg, pm2fb_pan_display,
+ pm2fb_blank, pm2fb_dispsw
+};
+
+static int pm2fb_open(struct fb_info* info, int user);
+static int pm2fb_release(struct fb_info* info, int user);
+
+static struct fb_ops pm2fb_ops={
+ pm2fb_open, pm2fb_release, fbgen_get_fix, fbgen_get_var,
+ fbgen_set_var, fbgen_get_cmap, fbgen_set_cmap, fbgen_pan_display,
+ NULL /* fb_ioctl() */, NULL /* fb_mmap() */
+};
+
+/***************************************************************************
+ * Begin of Permedia2 specific functions
+ ***************************************************************************/
+
+inline static unsigned long RD32(unsigned char* base, long off) {
+
+ return *((volatile unsigned long* )(base+off));
+}
+
+inline static void WR32(unsigned char* base, long off, unsigned long v) {
+
+ *((volatile unsigned long* )(base+off))=v;
+}
+
+inline static unsigned long pm2_RD(struct pm2fb_info* p, long off) {
+
+ return RD32(p->regions.v_regs, off);
+}
+
+inline static void pm2_WR(struct pm2fb_info* p, long off, unsigned long v) {
+
+ WR32(p->regions.v_regs, off, v);
+}
+
+inline static unsigned long pm2_RDAC_RD(struct pm2fb_info* p, long idx) {
+
+ pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
+ eieio();
+ return pm2_RD(p, PM2R_RD_INDEXED_DATA);
+}
+
+inline static void pm2_RDAC_WR(struct pm2fb_info* p, long idx,
+ unsigned long v) {
+
+ pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
+ eieio();
+ pm2_WR(p, PM2R_RD_INDEXED_DATA, v);
+}
+
+#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
+#define WAIT_FIFO(p,a)
+#else
+inline static void WAIT_FIFO(struct pm2fb_info* p, unsigned long a) {
+
+ while(pm2_RD(p, PM2R_IN_FIFO_SPACE)<a);
+ eieio();
+}
+#endif
+
+static unsigned long partprod(unsigned long xres) {
+ int i;
+
+ for (i=0; pp_table[i].width && pp_table[i].width!=xres; i++);
+ if (!pp_table[i].width)
+ DPRINTK("invalid width %lu\n", xres);
+ return pp_table[i].pp;
+}
+
+static unsigned long to3264(unsigned long timing, int bpp, int is64) {
+
+ switch (bpp) {
+ case 8:
+ timing=timing>>(2+is64);
+ break;
+ case 16:
+ timing=timing>>(1+is64);
+ break;
+ case 24:
+ timing=(timing*3)>>(2+is64);
+ break;
+ case 32:
+ if (is64)
+ timing=timing>>1;
+ break;
+ }
+ return timing;
+}
+
+static unsigned long from3264(unsigned long timing, int bpp, int is64) {
+
+ switch (bpp) {
+ case 8:
+ timing=timing<<(2+is64);
+ break;
+ case 16:
+ timing=timing<<(1+is64);
+ break;
+ case 24:
+ timing=(timing<<(2+is64))/3;
+ break;
+ case 32:
+ if (is64)
+ timing=timing<<1;
+ break;
+ }
+ return timing;
+}
+
+static void mnp(unsigned long clk, unsigned char* mm, unsigned char* nn,
+ unsigned char* pp) {
+ unsigned char m;
+ unsigned char n;
+ unsigned char p;
+ unsigned long f;
+ long current;
+ long delta=100000;
+
+ *mm=*nn=*pp=0;
+ for (n=2; n<15; n++) {
+ for (m=2; m; m++) {
+ f=PM2_REFERENCE_CLOCK*m/n;
+ if (f>=150000 && f<=300000) {
+ for (p=0; p<5; p++, f>>=1) {
+ current=clk>f?clk-f:f-clk;
+ if (current<delta) {
+ delta=current;
+ *mm=m;
+ *nn=n;
+ *pp=p;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void wait_pm2(struct pm2fb_info* i) {
+
+ WAIT_FIFO(i, 1);
+ pm2_WR(i, PM2R_SYNC, 0);
+ eieio();
+ do {
+ while (pm2_RD(i, PM2R_OUT_FIFO_WORDS)==0);
+ eieio();
+ } while (pm2_RD(i, PM2R_OUT_FIFO)!=PM2TAG(PM2R_SYNC));
+}
+
+static void set_memclock(struct pm2fb_info* info, unsigned long clk) {
+ int i;
+ unsigned char m, n, p;
+
+ mnp(clk, &m, &n, &p);
+ WAIT_FIFO(info, 5);
+ pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_3, 6);
+ eieio();
+ pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_1, m);
+ pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_2, n);
+ eieio();
+ pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_3, 8|p);
+ eieio();
+ pm2_RDAC_RD(info, PM2I_RD_MEMORY_CLOCK_STATUS);
+ eieio();
+ for (i=256; i &&
+ !(pm2_RD(info, PM2R_RD_INDEXED_DATA)&PM2F_PLL_LOCKED); i--);
+}
+
+static void set_pixclock(struct pm2fb_info* info, unsigned long clk) {
+ int i;
+ unsigned char m, n, p;
+
+ mnp(clk, &m, &n, &p);
+ WAIT_FIFO(info, 5);
+ pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A3, 0);
+ eieio();
+ pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A1, m);
+ pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A2, n);
+ eieio();
+ pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
+ eieio();
+ pm2_RDAC_RD(info, PM2I_RD_PIXEL_CLOCK_STATUS);
+ eieio();
+ for (i=256; i &&
+ !(pm2_RD(info, PM2R_RD_INDEXED_DATA)&PM2F_PLL_LOCKED); i--);
+}
+
+static void set_color(struct pm2fb_info* p, unsigned char regno,
+ unsigned char r, unsigned char g, unsigned char b) {
+
+ WAIT_FIFO(p, 4);
+ eieio();
+ pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, regno);
+ eieio();
+ pm2_WR(p, PM2R_RD_PALETTE_DATA, r);
+ eieio();
+ pm2_WR(p, PM2R_RD_PALETTE_DATA, g);
+ eieio();
+ pm2_WR(p, PM2R_RD_PALETTE_DATA, b);
+}
+
+static void set_aperture(struct pm2fb_info* i, struct pm2fb_par* p) {
+
+ WAIT_FIFO(i, 2);
+#ifdef __LITTLE_ENDIAN
+ pm2_WR(i, PM2R_APERTURE_ONE, 0); /* FIXME */
+ pm2_WR(i, PM2R_APERTURE_TWO, 0);
+#else
+ switch (p->depth) {
+ case 8:
+ case 24:
+ pm2_WR(i, PM2R_APERTURE_ONE, 0);
+ pm2_WR(i, PM2R_APERTURE_TWO, 1);
+ break;
+ case 16:
+ pm2_WR(i, PM2R_APERTURE_ONE, 2);
+ pm2_WR(i, PM2R_APERTURE_TWO, 1);
+ break;
+ case 32:
+ pm2_WR(i, PM2R_APERTURE_ONE, 1);
+ pm2_WR(i, PM2R_APERTURE_TWO, 1);
+ break;
+ }
+#endif
+}
+
+static void set_screen(struct pm2fb_info* i, struct pm2fb_par* p) {
+ unsigned long clrmode=0;
+ unsigned long txtmap=0;
+ unsigned long xres;
+
+ xres=(p->width+31)&~31;
+ set_aperture(i, p);
+ WAIT_FIFO(i, 22);
+ pm2_RDAC_WR(i, PM2I_RD_COLOR_KEY_CONTROL, p->depth==8?0:
+ PM2F_COLOR_KEY_TEST_OFF);
+ switch (p->depth) {
+ case 8:
+ pm2_WR(i, PM2R_FB_READ_PIXEL, 0);
+ break;
+ case 16:
+ pm2_WR(i, PM2R_FB_READ_PIXEL, 1);
+ clrmode=PM2F_RD_TRUECOLOR|0x06;
+ txtmap=PM2F_TEXTEL_SIZE_16;
+ break;
+ case 32:
+ pm2_WR(i, PM2R_FB_READ_PIXEL, 2);
+ clrmode=PM2F_RD_TRUECOLOR|0x08;
+ txtmap=PM2F_TEXTEL_SIZE_32;
+ break;
+ case 24:
+ pm2_WR(i, PM2R_FB_READ_PIXEL, 4);
+ clrmode=PM2F_RD_TRUECOLOR|0x09;
+ txtmap=PM2F_TEXTEL_SIZE_24;
+ break;
+ }
+ pm2_WR(i, PM2R_SCREEN_SIZE, (p->height<<16)|p->width);
+ pm2_WR(i, PM2R_SCISSOR_MODE, PM2F_SCREEN_SCISSOR_ENABLE);
+ pm2_WR(i, PM2R_FB_WRITE_MODE, PM2F_FB_WRITE_ENABLE);
+ pm2_WR(i, PM2R_FB_READ_MODE, partprod(xres));
+ pm2_WR(i, PM2R_LB_READ_MODE, partprod(xres));
+ pm2_WR(i, PM2R_TEXTURE_MAP_FORMAT, txtmap|partprod(xres));
+ pm2_WR(i, PM2R_H_TOTAL, p->htotal);
+ pm2_WR(i, PM2R_HS_START, p->hsstart);
+ pm2_WR(i, PM2R_HS_END, p->hsend);
+ pm2_WR(i, PM2R_HG_END, p->hbend);
+ pm2_WR(i, PM2R_HB_END, p->hbend);
+ pm2_WR(i, PM2R_V_TOTAL, p->vtotal);
+ pm2_WR(i, PM2R_VS_START, p->vsstart);
+ pm2_WR(i, PM2R_VS_END, p->vsend);
+ pm2_WR(i, PM2R_VB_END, p->vbend);
+ pm2_WR(i, PM2R_SCREEN_STRIDE, p->stride);
+ eieio();
+ pm2_WR(i, PM2R_SCREEN_BASE, p->base);
+ pm2_RDAC_WR(i, PM2I_RD_COLOR_MODE, PM2F_RD_COLOR_MODE_RGB|
+ PM2F_RD_GUI_ACTIVE|clrmode);
+ pm2_WR(i, PM2R_VIDEO_CONTROL, p->video);
+ set_pixclock(i, p->pixclock);
+};
+
+/***************************************************************************
+ * Begin of generic initialization functions
+ ***************************************************************************/
+
+static void pm2fb_reset(struct pm2fb_info* p) {
+
+ pm2_WR(p, PM2R_RESET_STATUS, 0);
+ eieio();
+ while (pm2_RD(p, PM2R_RESET_STATUS)&PM2F_BEING_RESET);
+ eieio();
+#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
+ DPRINTK("FIFO disconnect enabled\n");
+ pm2_WR(p, PM2R_FIFO_DISCON, 1);
+#endif
+ eieio();
+ if (board_table[p->board].init)
+ board_table[p->board].init(p);
+ WAIT_FIFO(p, 48);
+ pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG)&
+ ~(PM2F_VGA_ENABLE|PM2F_VGA_FIXED));
+ pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L));
+ pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L));
+ pm2_WR(p, PM2R_FIFO_CONTROL, 0);
+ pm2_WR(p, PM2R_FILTER_MODE, PM2F_SYNCHRONIZATION);
+ pm2_WR(p, PM2R_APERTURE_ONE, 0);
+ pm2_WR(p, PM2R_APERTURE_TWO, 0);
+ pm2_WR(p, PM2R_LB_READ_FORMAT, 0);
+ pm2_WR(p, PM2R_LB_WRITE_FORMAT, 0);
+ pm2_WR(p, PM2R_LB_READ_MODE, 0);
+ pm2_WR(p, PM2R_LB_SOURCE_OFFSET, 0);
+ pm2_WR(p, PM2R_FB_SOURCE_OFFSET, 0);
+ pm2_WR(p, PM2R_FB_PIXEL_OFFSET, 0);
+ pm2_WR(p, PM2R_WINDOW_ORIGIN, 0);
+ pm2_WR(p, PM2R_FB_WINDOW_BASE, 0);
+ pm2_WR(p, PM2R_LB_WINDOW_BASE, 0);
+ pm2_WR(p, PM2R_FB_SOFT_WRITE_MASK, ~(0L));
+ pm2_WR(p, PM2R_FB_HARD_WRITE_MASK, ~(0L));
+ pm2_WR(p, PM2R_FB_READ_PIXEL, 0);
+ pm2_WR(p, PM2R_DITHER_MODE, 0);
+ pm2_WR(p, PM2R_AREA_STIPPLE_MODE, 0);
+ pm2_WR(p, PM2R_DEPTH_MODE, 0);
+ pm2_WR(p, PM2R_STENCIL_MODE, 0);
+ pm2_WR(p, PM2R_TEXTURE_ADDRESS_MODE, 0);
+ pm2_WR(p, PM2R_TEXTURE_READ_MODE, 0);
+ pm2_WR(p, PM2R_TEXEL_LUT_MODE, 0);
+ pm2_WR(p, PM2R_YUV_MODE, 0);
+ pm2_WR(p, PM2R_COLOR_DDA_MODE, 0);
+ pm2_WR(p, PM2R_TEXTURE_COLOR_MODE, 0);
+ pm2_WR(p, PM2R_FOG_MODE, 0);
+ pm2_WR(p, PM2R_ALPHA_BLEND_MODE, 0);
+ pm2_WR(p, PM2R_LOGICAL_OP_MODE, 0);
+ pm2_WR(p, PM2R_STATISTICS_MODE, 0);
+ pm2_WR(p, PM2R_SCISSOR_MODE, 0);
+ pm2_RDAC_WR(p, PM2I_RD_CURSOR_CONTROL, 0);
+ pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, PM2F_RD_PALETTE_WIDTH_8);
+ pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0);
+ pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0);
+ pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0);
+ pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0);
+ pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
+ eieio();
+ set_memclock(p, p->memclock);
+}
+
+__initfunc(static int pm2fb_conf(struct pm2fb_info* p)) {
+
+ for (p->board=0; board_table[p->board].detect &&
+ !(board_table[p->board].detect(p)); p->board++);
+ if (!board_table[p->board].detect) {
+ DPRINTK("no board found.\n");
+ return 0;
+ }
+ DPRINTK("found board: %s\n", board_table[p->board].name);
+ p->regions.p_fb=p->regions.fb_base;
+ p->regions.v_fb=MMAP(p->regions.p_fb, p->regions.fb_size);
+#ifdef __LITTLE_ENDIAN
+ p->regions.p_regs=p->regions.rg_base;
+#else
+ p->regions.p_regs=p->regions.rg_base+PM2_REGS_SIZE;
+#endif
+ p->regions.v_regs=MMAP(p->regions.p_regs, PM2_REGS_SIZE);


+ return 1;
+}
+

+/***************************************************************************
+ * Begin of per-board initialization functions
+ ***************************************************************************/
+
+#ifdef CONFIG_FB_PM2_CVPPC
+static int cvppc_PCI_init(struct cvppc_par* p) {
+ extern unsigned long powerup_PCI_present;
+
+ if (!powerup_PCI_present) {
+ DPRINTK("no PCI bridge detected\n");
+ return 0;
+ }
+ if (!(p->pci_config=MMAP(CVPPC_PCI_CONFIG, 256))) {
+ DPRINTK("unable to map PCI config region\n");
+ return 0;
+ }
+ if (RD32(p->pci_config, PCI_VENDOR_ID)!=
+ ((PCI_DEVICE_ID_TI_TVP4020<<16)|PCI_VENDOR_ID_TI)) {
+ DPRINTK("bad vendorID/deviceID\n");
+ return 0;
+ }
+ if (!(p->pci_bridge=MMAP(CSPPC_PCI_BRIDGE, 256))) {
+ DPRINTK("unable to map PCI bridge\n");
+ return 0;
+ }
+ WR32(p->pci_bridge, CSPPC_BRIDGE_ENDIAN, CSPPCF_BRIDGE_BIG_ENDIAN);
+ eieio();
+ if (pm2fb_options.flags & OPTF_OLD_MEM)
+ WR32(p->pci_config, PCI_CACHE_LINE_SIZE, 0xff00);
+ WR32(p->pci_config, PCI_BASE_ADDRESS_0, CVPPC_REGS_REGION);
+ WR32(p->pci_config, PCI_BASE_ADDRESS_1, CVPPC_FB_APERTURE_ONE);
+ WR32(p->pci_config, PCI_BASE_ADDRESS_2, CVPPC_FB_APERTURE_TWO);
+ WR32(p->pci_config, PCI_ROM_ADDRESS, CVPPC_ROM_ADDRESS);
+ eieio();
+ WR32(p->pci_config, PCI_COMMAND, 0xef000000 |
+ PCI_COMMAND_IO |
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER);


+ return 1;
+}
+

+static int cvppc_detect(struct pm2fb_info* p) {
+
+ if (!cvppc_PCI_init(&p->board_par.cvppc))
+ return 0;
+ p->regions.fb_base=(unsigned char* )CVPPC_FB_APERTURE_ONE;
+ p->regions.fb_size=CVPPC_FB_SIZE;
+ p->regions.rg_base=(unsigned char* )CVPPC_REGS_REGION;
+ p->memclock=CVPPC_MEMCLOCK;


+ return 1;
+}
+

+static void cvppc_init(struct pm2fb_info* p) {
+
+ WAIT_FIFO(p, 3);
+ pm2_WR(p, PM2R_MEM_CONTROL, 0);
+ pm2_WR(p, PM2R_BOOT_ADDRESS, 0x30);
+ eieio();
+ if (pm2fb_options.flags & OPTF_OLD_MEM)
+ pm2_WR(p, PM2R_MEM_CONFIG, CVPPC_MEM_CONFIG_OLD);
+ else
+ pm2_WR(p, PM2R_MEM_CONFIG, CVPPC_MEM_CONFIG_NEW);
+}
+#endif /* CONFIG_FB_PM2_CVPPC */
+
+/***************************************************************************
+ * Console hw acceleration
+ ***************************************************************************/
+
+/*
+ * copy with packed pixels (8/16bpp only).
+ */
+static void pm2fb_pp_copy(struct pm2fb_info* i, long xsrc, long ysrc,
+ long x, long y, long w, long h) {
+ long scale=i->current_par.depth==8?2:1;
+ long offset;
+
+ if (!w || !h)
+ return;
+ WAIT_FIFO(i, 7);
+ pm2_WR(i, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE|
+ PM2F_CONFIG_FB_PACKED_DATA|
+ PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
+ pm2_WR(i, PM2R_FB_PIXEL_OFFSET, 0);
+ pm2_WR(i, PM2R_FB_SOURCE_DELTA, ((ysrc-y)&0xfff)<<16|
+ ((xsrc-x)&0xfff));
+ offset=(x&0x3)-(xsrc&0x3);
+ pm2_WR(i, PM2R_RECTANGLE_ORIGIN, (y<<16)|(x>>scale));
+ pm2_WR(i, PM2R_RECTANGLE_SIZE, (h<<16)|((w+7)>>scale));
+ pm2_WR(i, PM2R_PACKED_DATA_LIMITS, (offset<<29)|(x<<16)|(x+w));
+ eieio();
+ pm2_WR(i, PM2R_RENDER, PM2F_RENDER_RECTANGLE|
+ (x<xsrc?PM2F_INCREASE_X:0)|
+ (y<ysrc?PM2F_INCREASE_Y:0));
+ wait_pm2(i);
+}
+
+/*
+ * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
+ */
+static void pm2fb_block_op(struct pm2fb_info* i, int copy,
+ long xsrc, long ysrc,
+ long x, long y, long w, long h,
+ unsigned long color) {
+
+ if (!w || !h)
+ return;
+ WAIT_FIFO(i, 6);
+ pm2_WR(i, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE|
+ PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
+ pm2_WR(i, PM2R_FB_PIXEL_OFFSET, 0);
+ if (copy)
+ pm2_WR(i, PM2R_FB_SOURCE_DELTA, ((ysrc-y)&0xfff)<<16|
+ ((xsrc-x)&0xfff));
+ else
+ pm2_WR(i, PM2R_FB_BLOCK_COLOR, color);
+ pm2_WR(i, PM2R_RECTANGLE_ORIGIN, (y<<16)|x);
+ pm2_WR(i, PM2R_RECTANGLE_SIZE, (h<<16)|w);
+ eieio();
+ pm2_WR(i, PM2R_RENDER, PM2F_RENDER_RECTANGLE|
+ (x<xsrc?PM2F_INCREASE_X:0)|
+ (y<ysrc?PM2F_INCREASE_Y:0)|
+ (copy?0:PM2F_RENDER_FASTFILL));
+ wait_pm2(i);
+}
+
+static int pm2fb_blank(int blank_mode, struct fb_info_gen* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+ unsigned long video;
+
+ if (!i->current_par_valid)
+ return 1;
+ video=i->current_par.video;
+ if (blank_mode>0) {
+ switch (blank_mode-1) {
+ case VESA_NO_BLANKING: /* FIXME */
+ video=video&~(PM2F_VIDEO_ENABLE);
+ break;
+ case VESA_HSYNC_SUSPEND:
+ video=video&~(PM2F_HSYNC_MASK|
+ PM2F_BLANK_LOW);
+ break;
+ case VESA_VSYNC_SUSPEND:
+ video=video&~(PM2F_VSYNC_MASK|
+ PM2F_BLANK_LOW);
+ break;
+ case VESA_POWERDOWN:
+ video=video&~(PM2F_VSYNC_MASK|
+ PM2F_HSYNC_MASK|
+ PM2F_BLANK_LOW);
+ break;
+ }
+ }
+ WAIT_FIFO(i, 1);
+ pm2_WR(i, PM2R_VIDEO_CONTROL, video);


+ return 0;
+}
+

+static int pm2fb_pan_display(const struct fb_var_screeninfo* var,
+ struct fb_info_gen* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+
+ if (!i->current_par_valid)
+ return -EINVAL;
+ i->current_par.base=to3264(var->yoffset*i->current_par.width+
+ var->xoffset, i->current_par.depth, 1);
+ WAIT_FIFO(i, 1);
+ pm2_WR(i, PM2R_SCREEN_BASE, i->current_par.base);


+ return 0;
+}
+

+static void pm2fb_pp_bmove(struct display* p, int sy, int sx,
+ int dy, int dx, int height, int width) {
+
+ if (fontwidthlog(p)) {
+ sx=sx<<fontwidthlog(p);
+ dx=dx<<fontwidthlog(p);
+ width=width<<fontwidthlog(p);
+ }
+ else {
+ sx=sx*fontwidth(p);
+ dx=dx*fontwidth(p);
+ width=width*fontwidth(p);
+ }
+ sy=sy*fontheight(p);
+ dy=dy*fontheight(p);
+ height=height*fontheight(p);
+ pm2fb_pp_copy((struct pm2fb_info* )p->fb_info, sx, sy, dx,
+ dy, width, height);
+}
+
+static void pm2fb_bmove(struct display* p, int sy, int sx,
+ int dy, int dx, int height, int width) {
+
+ if (fontwidthlog(p)) {
+ sx=sx<<fontwidthlog(p);
+ dx=dx<<fontwidthlog(p);
+ width=width<<fontwidthlog(p);
+ }
+ else {
+ sx=sx*fontwidth(p);
+ dx=dx*fontwidth(p);
+ width=width*fontwidth(p);
+ }
+ sy=sy*fontheight(p);
+ dy=dy*fontheight(p);
+ height=height*fontheight(p);
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 1, sx, sy, dx, dy,
+ width, height, 0);
+}
+
+#ifdef FBCON_HAS_CFB8
+static void pm2fb_clear8(struct vc_data* conp, struct display* p,
+ int sy, int sx, int height, int width) {
+ unsigned long c;
+
+ sx=sx*fontwidth(p);
+ width=width*fontwidth(p);
+ sy=sy*fontheight(p);
+ height=height*fontheight(p);
+ c=attr_bgcol_ec(p, conp);
+ c|=c<<8;
+ c|=c<<16;
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0, sx, sy,
+ width, height, c);
+}
+
+static void pm2fb_clear_margins8(struct vc_data* conp, struct display* p,
+ int bottom_only) {
+ unsigned long c;
+ unsigned long sx;
+ unsigned long sy;
+
+ c=attr_bgcol_ec(p, conp);
+ c|=c<<8;
+ c|=c<<16;
+ sx=conp->vc_cols*fontwidth(p);
+ sy=conp->vc_rows*fontheight(p);
+ if (!bottom_only)
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
+ sx, 0, (p->var.xres-sx), p->var.yres_virtual, c);
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
+ 0, p->var.yoffset+sy, sx, p->var.yres-sy, c);
+}
+
+static struct display_switch pm2_cfb8 = {
+ fbcon_cfb8_setup, pm2fb_pp_bmove, pm2fb_clear8,
+ fbcon_cfb8_putc, fbcon_cfb8_putcs, fbcon_cfb8_revc,
+ NULL /* cursor() */, NULL /* set_font() */,
+ pm2fb_clear_margins8,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) };
+#endif /* FBCON_HAS_CFB8 */
+
+#ifdef FBCON_HAS_CFB16
+static void pm2fb_clear16(struct vc_data* conp, struct display* p,
+ int sy, int sx, int height, int width) {
+ unsigned long c;
+
+ sx=sx*fontwidth(p);
+ width=width*fontwidth(p);
+ sy=sy*fontheight(p);
+ height=height*fontheight(p);
+ c=((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+ c|=c<<16;
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0, sx, sy,
+ width, height, c);
+}
+
+static void pm2fb_clear_margins16(struct vc_data* conp, struct display* p,
+ int bottom_only) {
+ unsigned long c;
+ unsigned long sx;
+ unsigned long sy;
+
+ c = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+ c|=c<<16;
+ sx=conp->vc_cols*fontwidth(p);
+ sy=conp->vc_rows*fontheight(p);
+ if (!bottom_only)
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
+ sx, 0, (p->var.xres-sx), p->var.yres_virtual, c);
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
+ 0, p->var.yoffset+sy, sx, p->var.yres-sy, c);
+}
+
+static struct display_switch pm2_cfb16 = {
+ fbcon_cfb16_setup, pm2fb_pp_bmove, pm2fb_clear16,
+ fbcon_cfb16_putc, fbcon_cfb16_putcs, fbcon_cfb16_revc,
+ NULL /* cursor() */, NULL /* set_font() */,
+ pm2fb_clear_margins16,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) };
+#endif /* FBCON_HAS_CFB16 */
+
+#ifdef FBCON_HAS_CFB24
+/*
+ * fast fill for 24bpp works only when red==green==blue
+ */
+static void pm2fb_clear24(struct vc_data* conp, struct display* p,
+ int sy, int sx, int height, int width) {
+ struct pm2fb_info* i=(struct pm2fb_info* )p->fb_info;
+ unsigned long c;
+
+ c=attr_bgcol_ec(p, conp);
+ if ( i->palette[c].red==i->palette[c].green &&
+ i->palette[c].green==i->palette[c].blue) {
+ c=((u32 *)p->dispsw_data)[c];
+ c|=(c&0xff0000)<<8;
+ sx=sx*fontwidth(p);
+ width=width*fontwidth(p);
+ sy=sy*fontheight(p);
+ height=height*fontheight(p);
+ pm2fb_block_op(i, 0, 0, 0, sx, sy, width, height, c);
+ }
+ else
+ fbcon_cfb24_clear(conp, p, sy, sx, height, width);
+
+}
+
+static void pm2fb_clear_margins24(struct vc_data* conp, struct display* p,
+ int bottom_only) {
+ struct pm2fb_info* i=(struct pm2fb_info* )p->fb_info;
+ unsigned long c;
+ unsigned long sx;
+ unsigned long sy;
+
+ c=attr_bgcol_ec(p, conp);
+ if ( i->palette[c].red==i->palette[c].green &&
+ i->palette[c].green==i->palette[c].blue) {
+ c=((u32 *)p->dispsw_data)[c];
+ c|=(c&0xff0000)<<8;
+ sx=conp->vc_cols*fontwidth(p);
+ sy=conp->vc_rows*fontheight(p);
+ if (!bottom_only)
+ pm2fb_block_op(i, 0, 0, 0, sx, 0, (p->var.xres-sx),
+ p->var.yres_virtual, c);
+ pm2fb_block_op(i, 0, 0, 0, 0, p->var.yoffset+sy,
+ sx, p->var.yres-sy, c);
+ }
+ else


+ fbcon_cfb24_clear_margins(conp, p, bottom_only);
+
+}

+
+static struct display_switch pm2_cfb24 = {
+ fbcon_cfb24_setup, pm2fb_bmove, pm2fb_clear24,
+ fbcon_cfb24_putc, fbcon_cfb24_putcs, fbcon_cfb24_revc,
+ NULL /* cursor() */, NULL /* set_font() */,
+ pm2fb_clear_margins24,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) };
+#endif /* FBCON_HAS_CFB24 */
+
+#ifdef FBCON_HAS_CFB32
+static void pm2fb_clear32(struct vc_data* conp, struct display* p,
+ int sy, int sx, int height, int width) {
+ unsigned long c;
+
+ sx=sx*fontwidth(p);
+ width=width*fontwidth(p);
+ sy=sy*fontheight(p);
+ height=height*fontheight(p);
+ c=((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0, sx, sy,
+ width, height, c);
+}
+
+static void pm2fb_clear_margins32(struct vc_data* conp, struct display* p,
+ int bottom_only) {
+ unsigned long c;
+ unsigned long sx;
+ unsigned long sy;
+
+ c = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
+ sx=conp->vc_cols*fontwidth(p);
+ sy=conp->vc_rows*fontheight(p);
+ if (!bottom_only)
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
+ sx, 0, (p->var.xres-sx), p->var.yres_virtual, c);
+ pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
+ 0, p->var.yoffset+sy, sx, p->var.yres-sy, c);
+}
+
+static struct display_switch pm2_cfb32 = {
+ fbcon_cfb32_setup, pm2fb_bmove, pm2fb_clear32,
+ fbcon_cfb32_putc, fbcon_cfb32_putcs, fbcon_cfb32_revc,
+ NULL /* cursor() */, NULL /* set_font() */,
+ pm2fb_clear_margins32,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) };
+#endif /* FBCON_HAS_CFB32 */
+
+/***************************************************************************
+ * Framebuffer functions
+ ***************************************************************************/
+
+static void pm2fb_detect(void) {}
+
+static int pm2fb_encode_fix(struct fb_fix_screeninfo* fix,
+ const void* par, struct fb_info_gen* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+ struct pm2fb_par* p=(struct pm2fb_par* )par;
+
+ strcpy(fix->id, permedia2_name);
+ fix->smem_start=i->regions.p_fb;
+ fix->smem_len=i->regions.fb_size;
+ fix->mmio_start=i->regions.p_regs;
+ fix->mmio_len=PM2_REGS_SIZE;
+ fix->accel=FB_ACCEL_3DLABS_PERMEDIA2;
+ fix->type=FB_TYPE_PACKED_PIXELS;
+ fix->visual=p->depth==8?FB_VISUAL_PSEUDOCOLOR:FB_VISUAL_TRUECOLOR;
+ fix->line_length=0;
+ fix->xpanstep=p->depth==24?8:64/p->depth;
+ fix->ypanstep=1;
+ fix->ywrapstep=0;


+ return 0;
+}
+

+static int pm2fb_decode_var(const struct fb_var_screeninfo* var,
+ void* par, struct fb_info_gen* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+ struct pm2fb_par p;
+ unsigned long xres;
+ int data64;
+
+ memset(&p, 0, sizeof(struct pm2fb_par));
+ p.width=(var->xres_virtual+7)&~7;
+ p.height=var->yres_virtual;
+ p.depth=(var->bits_per_pixel+7)&~7;
+ p.depth=p.depth>32?32:p.depth;
+ data64=p.depth>8;
+ xres=(var->xres+31)&~31;
+ if (p.width==~(0L))
+ p.width=xres;
+ if (p.height==~(0L))
+ p.height=var->yres;
+ if (p.width<xres+var->xoffset)
+ p.width=xres+var->xoffset;
+ if (p.height<var->yres+var->yoffset)
+ p.height=var->yres+var->yoffset;
+ if (!partprod(xres)) {
+ DPRINTK("width not supported: %lu\n", xres);
+ return -EINVAL;
+ }
+ if (p.width>2047) {
+ DPRINTK("virtual width not supported: %lu\n", p.width);
+ return -EINVAL;
+ }
+ if (var->yres<200) {
+ DPRINTK("height not supported: %lu\n",
+ (unsigned long )var->yres);
+ return -EINVAL;
+ }
+ if (p.height<200 || p.height>2047) {
+ DPRINTK("virtual height not supported: %lu\n", p.height);
+ return -EINVAL;
+ }
+ if (p.width*p.height*p.depth/8>i->regions.fb_size) {
+ DPRINTK("no memory for screen (%lux%lux%lu)\n",
+ xres, p.height, p.depth);
+ return -EINVAL;
+ }
+ p.pixclock=PICOS2KHZ(var->pixclock);
+ if (p.pixclock>PM2_MAX_PIXCLOCK) {
+ DPRINTK("pixclock too high (%luKHz)\n", p.pixclock);
+ return -EINVAL;
+ }
+ p.hsstart=to3264(var->right_margin, p.depth, data64);
+ p.hsend=p.hsstart+to3264(var->hsync_len, p.depth, data64);
+ p.hbend=p.hsend+to3264(var->left_margin, p.depth, data64);
+ p.htotal=to3264(xres, p.depth, data64)+p.hbend-1;
+ p.vsstart=var->lower_margin?var->lower_margin-1:0; /* FIXME! */
+ p.vsend=var->lower_margin+var->vsync_len-1;
+ p.vbend=var->lower_margin+var->vsync_len+var->upper_margin;
+ p.vtotal=var->yres+p.vbend-1;
+ p.stride=to3264(p.width, p.depth, 1);
+ p.base=to3264(var->yoffset*xres+var->xoffset, p.depth, 1);
+ if (data64)
+ p.video|=PM2F_DATA_64_ENABLE;
+ if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+ p.video|=PM2F_HSYNC_ACT_HIGH;
+ else
+ p.video|=PM2F_HSYNC_ACT_LOW;
+ if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+ p.video|=PM2F_VSYNC_ACT_HIGH;
+ else
+ p.video|=PM2F_VSYNC_ACT_LOW;
+ if ((var->vmode & FB_VMODE_MASK)==FB_VMODE_INTERLACED) {
+ DPRINTK("interlaced not supported\n");
+ return -EINVAL;
+ }
+ if ((var->vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE)
+ p.video|=PM2F_LINE_DOUBLE;
+ if (var->activate==FB_ACTIVATE_NOW)
+ p.video|=PM2F_VIDEO_ENABLE;
+ *((struct pm2fb_par* )par)=p;


+ return 0;
+}
+

+static int pm2fb_encode_var(struct fb_var_screeninfo* var,
+ const void* par, struct fb_info_gen* info) {
+ struct pm2fb_par* p=(struct pm2fb_par* )par;
+ struct fb_var_screeninfo v;
+ unsigned long base;
+
+ memset(&v, 0, sizeof(struct fb_var_screeninfo));
+ v.xres_virtual=p->width;
+ v.yres_virtual=p->height;
+ v.xres=(p->htotal+1)-p->hbend;
+ v.yres=(p->vtotal+1)-p->vbend;
+ v.right_margin=p->hsstart;
+ v.hsync_len=p->hsend-p->hsstart;
+ v.left_margin=p->hbend-p->hsend;
+ v.lower_margin=p->vsstart+1;
+ v.vsync_len=p->vsend-v.lower_margin+1;
+ v.upper_margin=p->vbend-v.lower_margin-v.vsync_len;
+ v.bits_per_pixel=p->depth;
+ if (p->video & PM2F_DATA_64_ENABLE) {
+ v.xres=v.xres<<1;
+ v.right_margin=v.right_margin<<1;
+ v.hsync_len=v.hsync_len<<1;
+ v.left_margin=v.left_margin<<1;
+ }
+ switch (p->depth) {
+ case 8:
+ v.red.length=v.green.length=v.blue.length=8;
+ v.xres=v.xres<<2;
+ v.right_margin=v.right_margin<<2;
+ v.hsync_len=v.hsync_len<<2;
+ v.left_margin=v.left_margin<<2;
+ break;
+ case 16:
+ v.red.offset=11;
+ v.red.length=5;
+ v.green.offset=5;
+ v.green.length=6;
+ v.blue.length=5;
+ v.xres=v.xres<<1;
+ v.right_margin=v.right_margin<<1;
+ v.hsync_len=v.hsync_len<<1;
+ v.left_margin=v.left_margin<<1;
+ break;
+ case 32:
+ v.transp.offset=24;
+ v.red.offset=16;
+ v.green.offset=8;
+ v.red.length=v.green.length=v.blue.length=
+ v.transp.length=8;
+ break;
+ case 24:
+ v.blue.offset=16;
+ v.green.offset=8;
+ v.red.length=v.green.length=v.blue.length=8;
+ v.xres=(v.xres<<2)/3;
+ v.right_margin=(v.right_margin<<2)/3;
+ v.hsync_len=(v.hsync_len<<2)/3;
+ v.left_margin=(v.left_margin<<2)/3;
+ break;
+ }
+ base=from3264(p->base, p->depth, 1);
+ v.xoffset=base%v.xres;
+ v.yoffset=base/v.xres;
+ v.height=v.width=-1;
+ v.pixclock=KHZ2PICOS(p->pixclock);
+ if ((p->video & PM2F_HSYNC_MASK)==PM2F_HSYNC_ACT_HIGH)
+ v.sync|=FB_SYNC_HOR_HIGH_ACT;
+ if ((p->video & PM2F_VSYNC_MASK)==PM2F_VSYNC_ACT_HIGH)
+ v.sync|=FB_SYNC_VERT_HIGH_ACT;
+ if (p->video & PM2F_LINE_DOUBLE)
+ v.vmode=FB_VMODE_DOUBLE;
+ *var=v;


+ return 0;
+}
+

+static void set_user_mode(struct pm2fb_info* i) {
+
+ memcpy(&i->current_par, &pm2fb_options.user_mode,
+ sizeof(i->current_par));
+ if (pm2fb_options.flags & OPTF_YPAN) {
+ i->current_par.height=i->regions.fb_size/
+ (i->current_par.width*i->current_par.depth/8);
+ i->current_par.height=MIN(i->current_par.height,2047);
+ i->current_par.height=MAX(i->current_par.height,
+ pm2fb_options.user_mode.height);
+ }
+}
+
+static void pm2fb_get_par(void* par, struct fb_info_gen* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+
+ if (!i->current_par_valid) {
+ set_user_mode(i);
+ pm2fb_reset(i);
+ set_screen(i, &i->current_par);
+ i->current_par_valid=1;
+ }
+ *((struct pm2fb_par* )par)=i->current_par;
+}
+
+static void pm2fb_set_par(const void* par, struct fb_info_gen* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+ struct pm2fb_par* p;
+
+ p=(struct pm2fb_par* )par;
+ if (i->current_par_valid) {
+ i->current_par.base=p->base;
+ if (!memcmp(p, &i->current_par, sizeof(struct pm2fb_par))) {
+ WAIT_FIFO(i, 1);
+ pm2_WR(i, PM2R_SCREEN_BASE, p->base);
+ return;
+ }
+ }
+ i->current_par=*p;
+ i->current_par_valid=1;
+ set_screen(i, &i->current_par);
+}
+
+static int pm2fb_getcolreg(unsigned regno,
+ unsigned* red, unsigned* green, unsigned* blue,
+ unsigned* transp, struct fb_info* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+
+ if (regno<256) {
+ *red=i->palette[regno].red<<8|i->palette[regno].red;
+ *green=i->palette[regno].green<<8|i->palette[regno].green;
+ *blue=i->palette[regno].blue<<8|i->palette[regno].blue;
+ *transp=i->palette[regno].transp<<8|i->palette[regno].transp;
+ }
+ return regno>255;
+}
+
+static int pm2fb_setcolreg(unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+
+ if (regno<16) {
+ switch (i->current_par.depth) {
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ i->cmap.cmap16[regno]=
+ ((u32 )red & 0xf800) |
+ (((u32 )green & 0xfc00)>>5) |
+ (((u32 )blue & 0xf800)>>11);
+ break;
+#endif
+#ifdef FBCON_HAS_CFB24
+ case 24:
+ i->cmap.cmap24[regno]=
+ (((u32 )blue & 0xff00) << 8) |
+ ((u32 )green & 0xff00) |
+ (((u32 )red & 0xff00) >> 8);
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ i->cmap.cmap32[regno]=
+ (((u32 )transp & 0xff00) << 16) |
+ (((u32 )red & 0xff00) << 8) |
+ (((u32 )green & 0xff00)) |
+ (((u32 )blue & 0xff00) >> 8);
+ break;
+#endif
+ default:
+ DPRINTK("bad depth %lu\n",
+ i->current_par.depth);
+ break;
+ }
+ }
+ if (regno<256) {
+ i->palette[regno].red=red >> 8;
+ i->palette[regno].green=green >> 8;
+ i->palette[regno].blue=blue >> 8;
+ i->palette[regno].transp=transp >> 8;
+ if (i->current_par.depth==8)
+ set_color(i, regno, red>>8, green>>8, blue>>8);
+ }
+ return regno>255;
+}
+
+static void pm2fb_dispsw(const void* par, struct display* disp,
+ struct fb_info_gen* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+ unsigned long flags;
+ unsigned long depth;
+
+ save_flags(flags);
+ cli();
+ switch (depth=((struct pm2fb_par* )par)->depth) {
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ disp->dispsw=&pm2_cfb8;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ disp->dispsw=&pm2_cfb16;
+ disp->dispsw_data=i->cmap.cmap16;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB24
+ case 24:
+ disp->dispsw=&pm2_cfb24;
+ disp->dispsw_data=i->cmap.cmap24;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ disp->dispsw=&pm2_cfb32;
+ disp->dispsw_data=i->cmap.cmap32;
+ break;
+#endif
+ default:
+ disp->dispsw=&fbcon_dummy;
+ break;
+ }
+ restore_flags(flags);
+}
+
+static int pm2fb_open(struct fb_info* info, int user) {
+
+ MOD_INC_USE_COUNT;


+ return 0;
+}
+

+static int pm2fb_release(struct fb_info* info, int user) {
+
+ MOD_DEC_USE_COUNT;


+ return 0;
+}
+

+/***************************************************************************
+ * Begin of public functions
+ ***************************************************************************/
+
+void pm2fb_cleanup(struct fb_info* info) {
+ struct pm2fb_info* i=(struct pm2fb_info* )info;
+
+ unregister_framebuffer(info);
+ pm2fb_reset(i);
+ /* FIXME UNMAP()??? */
+ if (board_table[i->board].cleanup)
+ board_table[i->board].cleanup(i);
+}
+
+__initfunc(void pm2fb_init(void)) {
+
+ memset(&fb_info, 0, sizeof(fb_info));
+ if (!pm2fb_conf(&fb_info))
+ return;
+ fb_info.disp.scrollmode=SCROLL_YNOMOVE;
+ fb_info.gen.parsize=sizeof(struct pm2fb_par);
+ fb_info.gen.fbhw=&pm2fb_hwswitch;
+ strcpy(fb_info.gen.info.modename, permedia2_name);
+ fb_info.gen.info.flags=FBINFO_FLAG_DEFAULT;
+ fb_info.gen.info.fbops=&pm2fb_ops;
+ fb_info.gen.info.disp=&fb_info.disp;
+ strcpy(fb_info.gen.info.fontname, pm2fb_options.font);
+ fb_info.gen.info.switch_con=&fbgen_switch;
+ fb_info.gen.info.updatevar=&fbgen_update_var;
+ fb_info.gen.info.blank=&fbgen_blank;
+ fbgen_get_var(&fb_info.disp.var, -1, &fb_info.gen.info);
+ if (fbgen_do_set_var(&fb_info.disp.var, 1, &fb_info.gen)<0)
+ return;
+ fbgen_set_disp(-1, &fb_info.gen);
+ fbgen_install_cmap(0, &fb_info.gen);
+ if (register_framebuffer(&fb_info.gen.info)<0) {
+ printk("pm2fb: unable to register.\n");
+ return;
+ }
+ printk("fb%d: %s (%s), using %ldK of video memory.\n",
+ GET_FB_IDX(fb_info.gen.info.node),
+ board_table[fb_info.board].name,
+ permedia2_name,
+ (unsigned long )(fb_info.regions.fb_size>>10));
+ MOD_INC_USE_COUNT;
+}
+
+__initfunc(void pm2fb_mode_setup(char* options)) {
+ int i;
+
+ for (i=0; user_mode[i].name[0] &&
+ strcmp(options, user_mode[i].name); i++);
+ if (user_mode[i].name[0])
+ memcpy(&pm2fb_options.user_mode, &user_mode[i].par,
+ sizeof(pm2fb_options.user_mode));
+}
+
+__initfunc(void pm2fb_font_setup(char* options)) {
+
+ strncpy(pm2fb_options.font, options, sizeof(pm2fb_options.font));
+ pm2fb_options.font[sizeof(pm2fb_options.font)-1]='\0';
+}
+
+__initfunc(void pm2fb_setup(char* options, int* ints)) {
+ char* next;
+
+ memset(&pm2fb_options, 0, sizeof(pm2fb_options));
+ memcpy(&pm2fb_options.user_mode, &user_mode[0].par,
+ sizeof(pm2fb_options.user_mode));
+ while (options) {
+ if ((next=strchr(options, ',')))
+ *(next++)='\0';
+ if (!strncmp(options, "font:", 5))
+ pm2fb_font_setup(options+5);


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 08'
echo 'File patch-2.2.0-pre9 is continued in part 09'
echo 09 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part09

#!/bin/sh
# this is part 09 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 09; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

+ else if (!strncmp(options, "mode:", 5))
+ pm2fb_mode_setup(options+5);
+ else if (!strcmp(options, "ypan"))
+ pm2fb_options.flags |= OPTF_YPAN;
+ else if (!strcmp(options, "oldmem"))
+ pm2fb_options.flags |= OPTF_OLD_MEM;
+ options=next;
+ }
+}
+
+/***************************************************************************
+ * Begin of module functions
+ ***************************************************************************/
+
+#ifdef MODULE
+int init_module(void) {
+
+ pm2fb_init();
+}
+
+void cleanup_module(void) {
+
+ pm2fb_cleanup();
+}
+#endif /* MODULE */
+
+/***************************************************************************


+ * That's all folks!

+ ***************************************************************************/
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/pm2fb.h linux/drivers/video/pm2fb.h
--- v2.2.0-pre8/linux/drivers/video/pm2fb.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/pm2fb.h Tue Jan 19 10:48:17 1999
@@ -0,0 +1,181 @@
+/*
+ * Permedia2 framebuffer driver definitions.


+ * Copyright (c) 1998-1999 Ilario Nardinocchi (nard...@CS.UniBO.IT)

+ * --------------------------------------------------------------------------
+ * $Id: pm2fb.h,v 1.1.2.1 1999/01/12 19:53:02 geert Exp $


+ * --------------------------------------------------------------------------
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+

+#ifndef PM2FB_H
+#define PM2FB_H
+
+#define PM2_REFERENCE_CLOCK 14318 /* in KHz */
+#define PM2_MAX_PIXCLOCK 230000 /* in KHz */
+#define PM2_REGS_SIZE 0x10000
+
+#define PM2TAG(r) (unsigned long )(((r)-0x8000)>>3)
+
+/*****************************************************************************
+ * Permedia2 registers used in the framebuffer
+ *****************************************************************************/
+
+#define PM2R_RESET_STATUS 0x0000
+#define PM2R_IN_FIFO_SPACE 0x0018
+#define PM2R_OUT_FIFO_WORDS 0x0020
+#define PM2R_APERTURE_ONE 0x0050
+#define PM2R_APERTURE_TWO 0x0058
+#define PM2R_FIFO_DISCON 0x0068
+#define PM2R_CHIP_CONFIG 0x0070
+
+#define PM2R_REBOOT 0x1000
+#define PM2R_MEM_CONTROL 0x1040
+#define PM2R_BOOT_ADDRESS 0x1080
+#define PM2R_MEM_CONFIG 0x10c0
+#define PM2R_BYPASS_WRITE_MASK 0x1100
+#define PM2R_FRAMEBUFFER_WRITE_MASK 0x1140
+
+#define PM2R_OUT_FIFO 0x2000
+
+#define PM2R_SCREEN_BASE 0x3000
+#define PM2R_SCREEN_STRIDE 0x3008
+#define PM2R_H_TOTAL 0x3010
+#define PM2R_HG_END 0x3018
+#define PM2R_HB_END 0x3020
+#define PM2R_HS_START 0x3028
+#define PM2R_HS_END 0x3030
+#define PM2R_V_TOTAL 0x3038
+#define PM2R_VB_END 0x3040
+#define PM2R_VS_START 0x3048
+#define PM2R_VS_END 0x3050
+#define PM2R_VIDEO_CONTROL 0x3058
+#define PM2R_LINE_COUNT 0x3070
+#define PM2R_FIFO_CONTROL 0x3078
+
+#define PM2R_RD_PALETTE_WRITE_ADDRESS 0x4000
+#define PM2R_RD_PALETTE_DATA 0x4008
+#define PM2R_RD_PALETTE_READ_ADDRESS 0x4018
+#define PM2R_RD_INDEXED_DATA 0x4050
+
+#define PM2R_START_X_DOM 0x8000
+#define PM2R_D_X_DOM 0x8008
+#define PM2R_START_X_SUB 0x8010
+#define PM2R_D_X_SUB 0x8018
+#define PM2R_START_Y 0x8020
+#define PM2R_D_Y 0x8028
+#define PM2R_COUNT 0x8030
+#define PM2R_RENDER 0x8038
+#define PM2R_RECTANGLE_ORIGIN 0x80d0
+#define PM2R_RECTANGLE_SIZE 0x80d8
+#define PM2R_PACKED_DATA_LIMITS 0x8150
+#define PM2R_SCISSOR_MODE 0x8180
+#define PM2R_SCREEN_SIZE 0x8198
+#define PM2R_AREA_STIPPLE_MODE 0x81a0
+#define PM2R_WINDOW_ORIGIN 0x81c8
+#define PM2R_TEXTURE_ADDRESS_MODE 0x8380
+#define PM2R_TEXTURE_MAP_FORMAT 0x8588
+#define PM2R_TEXTURE_DATA_FORMAT 0x8590
+#define PM2R_TEXTURE_READ_MODE 0x8670
+#define PM2R_TEXEL_LUT_MODE 0x8678
+#define PM2R_TEXTURE_COLOR_MODE 0x8680
+#define PM2R_FOG_MODE 0x8690
+#define PM2R_COLOR_DDA_MODE 0x87e0
+#define PM2R_ALPHA_BLEND_MODE 0x8810
+#define PM2R_DITHER_MODE 0x8818
+#define PM2R_FB_SOFT_WRITE_MASK 0x8820
+#define PM2R_LOGICAL_OP_MODE 0x8828
+#define PM2R_LB_READ_MODE 0x8880
+#define PM2R_LB_READ_FORMAT 0x8888
+#define PM2R_LB_SOURCE_OFFSET 0x8890
+#define PM2R_LB_WINDOW_BASE 0x88b8
+#define PM2R_LB_WRITE_FORMAT 0x88c8
+#define PM2R_STENCIL_MODE 0x8988
+#define PM2R_DEPTH_MODE 0x89a0
+#define PM2R_FB_READ_MODE 0x8a80
+#define PM2R_FB_SOURCE_OFFSET 0x8a88
+#define PM2R_FB_PIXEL_OFFSET 0x8a90
+#define PM2R_FB_WINDOW_BASE 0x8ab0
+#define PM2R_FB_WRITE_MODE 0x8ab8
+#define PM2R_FB_HARD_WRITE_MASK 0x8ac0
+#define PM2R_FB_BLOCK_COLOR 0x8ac8
+#define PM2R_FB_READ_PIXEL 0x8ad0
+#define PM2R_FILTER_MODE 0x8c00
+#define PM2R_SYNC 0x8c40
+#define PM2R_YUV_MODE 0x8f00
+#define PM2R_STATISTICS_MODE 0x8c08
+#define PM2R_FB_SOURCE_DELTA 0x8d88
+#define PM2R_CONFIG 0x8d90
+
+/* Permedia2 RAMDAC indexed registers */
+#define PM2I_RD_CURSOR_CONTROL 0x06
+#define PM2I_RD_COLOR_MODE 0x18
+#define PM2I_RD_MODE_CONTROL 0x19
+#define PM2I_RD_MISC_CONTROL 0x1e
+#define PM2I_RD_PIXEL_CLOCK_A1 0x20
+#define PM2I_RD_PIXEL_CLOCK_A2 0x21
+#define PM2I_RD_PIXEL_CLOCK_A3 0x22
+#define PM2I_RD_PIXEL_CLOCK_STATUS 0x29
+#define PM2I_RD_MEMORY_CLOCK_1 0x30
+#define PM2I_RD_MEMORY_CLOCK_2 0x31
+#define PM2I_RD_MEMORY_CLOCK_3 0x32
+#define PM2I_RD_MEMORY_CLOCK_STATUS 0x33
+#define PM2I_RD_COLOR_KEY_CONTROL 0x40
+#define PM2I_RD_OVERLAY_KEY 0x41
+#define PM2I_RD_RED_KEY 0x42
+#define PM2I_RD_GREEN_KEY 0x43
+#define PM2I_RD_BLUE_KEY 0x44
+
+/* Fields and flags */
+#define PM2F_RENDER_AREASTIPPLE (1<<0)
+#define PM2F_RENDER_FASTFILL (1<<3)
+#define PM2F_RENDER_PRIMITIVE_MASK (0x3<<6)
+#define PM2F_RENDER_LINE 0
+#define PM2F_RENDER_TRAPEZOID (1<<6)
+#define PM2F_RENDER_POINT (2<<6)
+#define PM2F_RENDER_RECTANGLE (3<<6)
+#define PM2F_SYNCHRONIZATION (1<<10)
+#define PM2F_PLL_LOCKED 0x10
+#define PM2F_BEING_RESET (1<<31)
+#define PM2F_DATATYPE_COLOR 0x8000
+#define PM2F_VGA_ENABLE 0x02
+#define PM2F_VGA_FIXED 0x04
+#define PM2F_FB_WRITE_ENABLE 0x01
+#define PM2F_FB_READ_SOURCE_ENABLE 0x0200
+#define PM2F_RD_PALETTE_WIDTH_8 0x02
+#define PM2F_PART_PROD_MASK 0x01ff
+#define PM2F_SCREEN_SCISSOR_ENABLE 0x02
+#define PM2F_DATA_64_ENABLE 0x00010000
+#define PM2F_BLANK_LOW 0x02
+#define PM2F_HSYNC_MASK 0x18
+#define PM2F_VSYNC_MASK 0x60
+#define PM2F_HSYNC_ACT_HIGH 0x08
+#define PM2F_HSYNC_FORCED_LOW 0x10
+#define PM2F_HSYNC_ACT_LOW 0x18
+#define PM2F_VSYNC_ACT_HIGH 0x20
+#define PM2F_VSYNC_FORCED_LOW 0x40
+#define PM2F_VSYNC_ACT_LOW 0x60
+#define PM2F_LINE_DOUBLE 0x04
+#define PM2F_VIDEO_ENABLE 0x01
+#define PM2F_RD_GUI_ACTIVE 0x10
+#define PM2F_RD_COLOR_MODE_RGB 0x20
+#define PM2F_RD_TRUECOLOR 0x80
+#define PM2F_NO_ALPHA_BUFFER 0x10
+#define PM2F_TEXTEL_SIZE_16 0x00080000
+#define PM2F_TEXTEL_SIZE_32 0x00100000
+#define PM2F_TEXTEL_SIZE_4 0x00180000
+#define PM2F_TEXTEL_SIZE_24 0x00200000
+#define PM2F_INCREASE_X (1<<21)
+#define PM2F_INCREASE_Y (1<<22)
+#define PM2F_CONFIG_FB_WRITE_ENABLE (1<<3)
+#define PM2F_CONFIG_FB_PACKED_DATA (1<<2)
+#define PM2F_CONFIG_FB_READ_DEST_ENABLE (1<<1)
+#define PM2F_CONFIG_FB_READ_SOURCE_ENABLE (1<<0)
+#define PM2F_COLOR_KEY_TEST_OFF (1<<4)
+
+#endif /* PM2FB_H */


+
+/*****************************************************************************
+ * That's all folks!
+ *****************************************************************************/

diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/retz3fb.c linux/drivers/video/retz3fb.c
--- v2.2.0-pre8/linux/drivers/video/retz3fb.c Wed Jan 13 15:00:43 1999
+++ linux/drivers/video/retz3fb.c Tue Jan 19 10:47:48 1999
@@ -1455,8 +1455,7 @@
X board_addr = (unsigned long)cd->cd_BoardAddr;
X board_size = (unsigned long)cd->cd_BoardSize;
X
- zinfo->base = kernel_map (board_addr, board_size,
- KERNELMAP_NOCACHE_SER, NULL);
+ zinfo->base = ioremap(board_addr, board_size);
X zinfo->regs = (unsigned char *)(zinfo->base);
X zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET;
X /* Get memory size - for now we asume its a 4MB board */
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/sbusfb.c linux/drivers/video/sbusfb.c
--- v2.2.0-pre8/linux/drivers/video/sbusfb.c Tue Dec 22 14:16:57 1998
+++ linux/drivers/video/sbusfb.c Tue Jan 19 10:48:41 1999
@@ -46,6 +46,9 @@
X
X #define DEFAULT_CURSOR_BLINK_RATE (2*HZ/5)
X
+#define CURSOR_SHAPE 1
+#define CURSOR_BLINK 2
+
X /*
X * Interface used by the world
X */
@@ -457,7 +460,7 @@
X
X if (!fb->setcursor) return;
X
- if (fb->cursor.mode != 2) {
+ if (fb->cursor.mode & CURSOR_BLINK) {
X fb->cursor.enable ^= 1;
X fb->setcursor(fb);
X }
@@ -472,14 +475,14 @@
X
X switch (mode) {
X case CM_ERASE:
- fb->cursor.mode = 2;
+ fb->cursor.mode &= ~CURSOR_BLINK;
X fb->cursor.enable = 0;
X (*fb->setcursor)(fb);
X break;
X
X case CM_MOVE:
X case CM_DRAW:
- if (fb->cursor.mode) {
+ if (fb->cursor.mode & CURSOR_SHAPE) {
X fb->cursor.size.fbx = fontwidth(p);
X fb->cursor.size.fby = fontheight(p);
X fb->cursor.chot.fbx = 0;
@@ -492,8 +495,8 @@
X fb->cursor.bits[1][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p)));
X (*fb->setcursormap) (fb, hw_cursor_cmap, hw_cursor_cmap, hw_cursor_cmap);
X (*fb->setcurshape) (fb);
- fb->cursor.mode = 0;
X }
+ fb->cursor.mode = CURSOR_BLINK;
X if (fontwidthlog(p))
X fb->cursor.cpos.fbx = (x << fontwidthlog(p)) + fb->x_margin;
X else
@@ -684,7 +687,7 @@
X lastconsole = info->display_fg->vc_num;
X if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
X return -EINVAL; /* Don't let graphics programs hide our nice text cursor */
- fb->cursor.mode = 2; /* Forget state of our text cursor */
+ fb->cursor.mode = CURSOR_SHAPE; /* Forget state of our text cursor */
X }
X return sbus_hw_scursor ((struct fbcursor *) arg, fb);
X
@@ -761,7 +764,7 @@
X if (lastconsole != con &&
X (fontwidth(&fb_display[lastconsole]) != fontwidth(&fb_display[con]) ||
X fontheight(&fb_display[lastconsole]) != fontheight(&fb_display[con])))
- fb->cursor.mode = 1;
+ fb->cursor.mode |= CURSOR_SHAPE;
X }
X x_margin = (fb_display[con].var.xres_virtual - fb_display[con].var.xres) / 2;
X y_margin = (fb_display[con].var.yres_virtual - fb_display[con].var.yres) / 2;
@@ -889,7 +892,7 @@
X p->var.xres = w - 2*x_margin;
X p->var.yres = h - 2*y_margin;
X
- fb->cursor.mode = 1;
+ fb->cursor.mode |= CURSOR_SHAPE;
X
X if (fb->margins)
X fb->margins(fb, p, x_margin, y_margin);
@@ -1076,6 +1079,7 @@
X add_timer(&fb->cursor.timer);
X }
X }
+ fb->cursor.mode = CURSOR_SHAPE;
X fb->dispsw.set_font = sbusfb_set_font;
X fb->setup = fb->dispsw.setup;
X fb->dispsw.setup = sbusfb_disp_setup;
diff -u --recursive --new-file v2.2.0-pre8/linux/drivers/video/virgefb.c linux/drivers/video/virgefb.c
--- v2.2.0-pre8/linux/drivers/video/virgefb.c Tue Dec 22 14:16:57 1998
+++ linux/drivers/video/virgefb.c Tue Jan 19 10:47:48 1999
@@ -50,7 +50,15 @@
X
X #if 1
X #define vgawb_3d(reg,dat) \
- (*((unsigned char *)(CyberVGARegs + (reg ^ 3))) = dat)
+ if (cv3d_on_zorro2) { \
+ *((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x04)) = \
+ (0x01 & 0xffff); asm volatile ("nop"); \
+ } \
+ (*((unsigned char *)(CyberVGARegs + (reg ^ 3))) = dat); \
+ if (cv3d_on_zorro2) { \
+ *((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x04)) = \
+ (0x02 & 0xffff); asm volatile ("nop"); \
+ }
X #define vgaww_3d(reg,dat) \
X (*((unsigned word *)(CyberVGARegs + (reg ^ 2))) = swab16(dat))
X #define vgawl_3d(reg,dat) \
@@ -155,6 +163,9 @@
X static volatile unsigned long CyberVGARegs; /* ++Andre: for CV64/3D, see macros at the beginning */
X static unsigned long CyberMem_phys;
X static unsigned long CyberRegs_phys;
+static unsigned long Cyber_register_base;
+static unsigned long Cyber_vcode_switch_base;
+static unsigned char cv3d_on_zorro2;
X
X
X /*
@@ -345,7 +356,11 @@
X memset ((char*)CyberMem, 0, 1600 * 1200);
X
X /* Disable hardware cursor */
- CyberSize = 0x00400000; /* 4 MB */
+ if (cv3d_on_zorro2) {
+ CyberSize = 0x00380000; /* 3.5 MB , we need some space for the registers? */
+ } else {
+ CyberSize = 0x00400000; /* 4 MB */
+ }
X
X vgawb_3d(0x3c8, 255);
X vgawb_3d(0x3c9, 56);
@@ -1045,21 +1060,26 @@
X
X CyberMem_phys = board_addr;
X CyberMem = ZTWO_VADDR(CyberMem_phys);
- printk("CV3D detected running in Z2 mode ... not yet supported!\n");
- return;
+ CyberVGARegs = (unsigned long) \
+ ZTWO_VADDR(board_addr + 0x003c0000);
+ CyberRegs_phys = (unsigned long)(board_addr + 0x003e0000);
+ CyberRegs = (unsigned char *)ZTWO_VADDR(CyberRegs_phys);
+ Cyber_register_base = (unsigned long) \
+ ZTWO_VADDR(board_addr + 0x003c8000);
+ Cyber_vcode_switch_base = (unsigned long) \
+ ZTWO_VADDR(board_addr + 0x003a0000);
+ cv3d_on_zorro2 = 1;
+ printk("CV3D detected running in Z2 mode.\n");
X }
X else
X {
- CyberVGARegs = kernel_map(board_addr +0x0c000000, 0x00010000,
- KERNELMAP_NOCACHE_SER, NULL);
+ CyberVGARegs = ioremap(board_addr +0x0c000000, 0x00010000);
X
X CyberRegs_phys = board_addr + 0x05000000;
X CyberMem_phys = board_addr + 0x04800000;
- CyberRegs = (char *)kernel_map(CyberRegs_phys,
- 0x00010000,
- KERNELMAP_NOCACHE_SER, NULL);
- CyberMem = kernel_map(CyberMem_phys, 0x00400000,
- KERNELMAP_NOCACHE_SER, NULL);
+ CyberRegs = ioremap(CyberRegs_phys, 0x00010000);
+ CyberMem = ioremap(CyberMem_phys, 0x00400000);
+ cv3d_on_zorro2 = 0;
X printk("CV3D detected running in Z3 mode\n");
X }
X
@@ -1084,8 +1104,10 @@
X virgefb_set_disp(-1, &fb_info);
X do_install_cmap(0, &fb_info);
X
- if (register_framebuffer(&fb_info) < 0)
+ if (register_framebuffer(&fb_info) < 0) {
+ printk("virgefb.c: register_framebuffer failed\n");
X return;
+ }
X
X printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
X GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10);
diff -u --recursive --new-file v2.2.0-pre8/linux/fs/Config.in linux/fs/Config.in
--- v2.2.0-pre8/linux/fs/Config.in Tue Jan 19 11:32:52 1999
+++ linux/fs/Config.in Tue Jan 19 11:07:53 1999
@@ -35,7 +35,11 @@
X tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS
X bool '/proc filesystem support' CONFIG_PROC_FS
X if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
- tristate '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS
+ # It compiles as a module for testing only. It should not be used
+ # as a module in general. If we make this "tristate", a bunch of people
+ # who don't know what they are doing turn it on and complain when it
+ # breaks.
+ bool '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS
X fi


X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then

X tristate 'QNX filesystem support (EXPERIMENTAL)' CONFIG_QNX4FS_FS
diff -u --recursive --new-file v2.2.0-pre8/linux/fs/namei.c linux/fs/namei.c
--- v2.2.0-pre8/linux/fs/namei.c Tue Jan 19 11:32:52 1999
+++ linux/fs/namei.c Tue Jan 19 10:26:33 1999
@@ -882,8 +882,16 @@
X if (IS_ERR(dentry))
X goto exit;
X
+ /*
+ * EEXIST is kind of a strange error code to
+ * return, but basically if the dentry was moved
+ * or unlinked while we locked the parent, we
+ * do know that it _did_ exist before, and as
+ * such it makes perfect sense.. In contrast,
+ * ENOENT doesn't make sense for mkdir.
+ */
X dir = lock_parent(dentry);
- error = -ENOENT;
+ error = -EEXIST;
X if (!check_parent(dir, dentry))
X goto exit_lock;
X
diff -u --recursive --new-file v2.2.0-pre8/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.2.0-pre8/linux/fs/proc/array.c Tue Jan 19 11:32:52 1999
+++ linux/fs/proc/array.c Wed Jan 20 10:23:58 1999
@@ -1085,8 +1085,7 @@
X vma = vma->vm_next;
X }
X release_mm(mm);
- } else
- return 0;
+ }
X return sprintf(buffer,"%d %d %d %d %d %d %d\n",
X size, resident, share, trs, lrs, drs, dt);
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/fs/select.c linux/fs/select.c
--- v2.2.0-pre8/linux/fs/select.c Tue Jan 19 11:32:52 1999
+++ linux/fs/select.c Tue Jan 19 10:43:08 1999
@@ -58,6 +58,37 @@
X }
X }
X
+void __pollwait(struct file * filp, struct wait_queue ** wait_address, poll_table *p)
+{
+ for (;;) {
+ if (p->nr < __MAX_POLL_TABLE_ENTRIES) {
+ struct poll_table_entry * entry;
+ok_table:
+ entry = p->entry + p->nr;
+ entry->filp = filp;
+ filp->f_count++;
+ entry->wait_address = wait_address;
+ entry->wait.task = current;
+ entry->wait.next = NULL;
+ add_wait_queue(wait_address,&entry->wait);
+ p->nr++;
+ return;
+ }
+ if (p->next == NULL) {
+ poll_table *tmp = (poll_table *) __get_free_page(GFP_KERNEL);
+ if (!tmp)
+ return;
+ tmp->nr = 0;
+ tmp->entry = (struct poll_table_entry *)(tmp + 1);
+ tmp->next = NULL;
+ p->next = tmp;
+ p = tmp;
+ goto ok_table;
+ }
+ p = p->next;
+ }
+}
+
X #define __IN(fds, n) (fds->in + n)
X #define __OUT(fds, n) (fds->out + n)
X #define __EX(fds, n) (fds->ex + n)
diff -u --recursive --new-file v2.2.0-pre8/linux/fs/vfat/namei.c linux/fs/vfat/namei.c
--- v2.2.0-pre8/linux/fs/vfat/namei.c Tue Jan 19 11:32:52 1999
+++ linux/fs/vfat/namei.c Wed Jan 20 12:57:57 1999
@@ -1656,8 +1656,8 @@
X } else {
X drop_aliases(new_dentry);
X }
+ res = vfat_remove_entry(new_dir,&sinfo,new_inode);
X }
- res = vfat_remove_entry(new_dir,&sinfo,new_inode);
X if (res)
X goto rename_done;
X
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-alpha/semaphore.h linux/include/asm-alpha/semaphore.h
--- v2.2.0-pre8/linux/include/asm-alpha/semaphore.h Tue Jan 19 11:32:52 1999
+++ linux/include/asm-alpha/semaphore.h Wed Jan 20 16:06:34 1999
@@ -72,13 +72,13 @@
X * count = -1, waking = 0, depth = 2;
X * up(&sem)
X * dec depth
- * count = -1, waking = 0, depth = 0;
+ * count = -1, waking = 0, depth = 1;
X * atomic inc and test sends us to slow path
- * count = 0, waking = 0, depth = 0;
+ * count = 0, waking = 0, depth = 1;
X * notice !(depth < 0) and don't call __up.
X * up(&sem)
X * dec depth
- * count = 0, waking = 0, depth = -1;
+ * count = 0, waking = 0, depth = 0;
X * atomic inc and test succeeds.
X * count = 1, waking = 0, depth = 0;
X */
@@ -227,7 +227,7 @@
X ".section .text2,\"ax\"\n"
X "2: br 1b\n"
X "3: lda $24,%1\n"
- " bge %2,4b\n"
+ " bgt %2,4b\n"
X " jsr $28,__up_wakeup\n"
X " ldgp $29,0($28)\n"
X " br 4b\n"
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-i386/cobalt.h linux/include/asm-i386/cobalt.h
--- v2.2.0-pre8/linux/include/asm-i386/cobalt.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-i386/cobalt.h Wed Jan 20 10:18:53 1999
@@ -0,0 +1,116 @@
+#ifndef __I386_COBALT_H
+#define __I386_COBALT_H
+
+/*
+ * Cobalt is the system ASIC on the SGI 320 and 540 Visual Workstations
+ */
+
+#define CO_CPU_PHYS 0xc2000000
+#define CO_APIC_PHYS 0xc4000000
+
+/* see set_fixmap() and asm/fixmap.h */
+#define CO_CPU_VADDR (fix_to_virt(FIX_CO_CPU))
+#define CO_APIC_VADDR (fix_to_virt(FIX_CO_APIC))
+
+/* Cobalt CPU registers -- relative to CO_CPU_VADDR, use co_cpu_*() */
+#define CO_CPU_REV 0x08
+#define CO_CPU_CTRL 0x10
+#define CO_CPU_STAT 0x20
+#define CO_CPU_TIMEVAL 0x30
+
+/* CO_CPU_CTRL bits */
+#define CO_CTRL_TIMERUN 0x04 /* 0 == disabled */
+#define CO_CTRL_TIMEMASK 0x08 /* 0 == unmasked */
+
+/* CO_CPU_STATUS bits */
+#define CO_STAT_TIMEINTR 0x02 /* (r) 1 == int pend, (w) 0 == clear */
+
+/* CO_CPU_TIMEVAL value */
+#define CO_TIME_HZ 100000000 /* Cobalt core rate */
+
+/* Cobalt APIC registers -- relative to CO_APIC_VADDR, use co_apic_*() */
+#define CO_APIC_HI(n) (((n) * 0x10) + 4)
+#define CO_APIC_LO(n) ((n) * 0x10)
+#define CO_APIC_ID 0x0ffc
+
+/* CO_APIC_ID bits */
+#define CO_APIC_ENABLE 0x00000100
+
+/* CO_APIC_LO bits */
+#define CO_APIC_LEVEL 0x08000 /* 0 = edge */
+
+/*
+ * Where things are physically wired to Cobalt
+ * #defines with no board _<type>_<rev>_ are common to all (thus far)
+ */
+#define CO_APIC_0_5_IDE0 5
+#define CO_APIC_0_5_SERIAL 13 /* XXX not really...h/w bug! */
+#define CO_APIC_0_5_PARLL 4
+#define CO_APIC_0_5_FLOPPY 6
+
+#define CO_APIC_0_6_IDE0 4
+#define CO_APIC_0_6_USB 7 /* PIIX4 USB */
+
+#define CO_APIC_1_2_IDE0 4
+
+#define CO_APIC_0_5_IDE1 2
+#define CO_APIC_0_6_IDE1 2
+
+/* XXX */
+#define CO_APIC_IDE0 CO_APIC_0_5_IDE0
+#define CO_APIC_IDE1 CO_APIC_0_5_IDE1
+#define CO_APIC_SERIAL CO_APIC_0_5_SERIAL
+/* XXX */
+
+#define CO_APIC_ENET 3 /* Lithium PCI Bridge A, Device 3 */
+#define CO_APIC_8259 12 /* serial, floppy, par-l-l, audio */
+
+#define CO_APIC_VIDOUT0 16
+#define CO_APIC_VIDOUT1 17
+#define CO_APIC_VIDIN0 18
+#define CO_APIC_VIDIN1 19
+
+#define CO_APIC_CPU 28 /* Timer and Cache interrupt */
+
+/*
+ * This is the "irq" arg to request_irq(), just a unique cookie.
+ */
+#define CO_IRQ_TIMER 0
+#define CO_IRQ_ENET 3
+#define CO_IRQ_SERIAL 4
+#define CO_IRQ_FLOPPY 6 /* Same as drivers/block/floppy.c:FLOPPY_IRQ */
+#define CO_IRQ_PARLL 7
+#define CO_IRQ_POWER 9
+#define CO_IRQ_IDE 14
+#define CO_IRQ_8259 12
+
+#ifdef CONFIG_X86_VISWS_APIC
+extern __inline void co_cpu_write(unsigned long reg, unsigned long v)
+{
+ *((volatile unsigned long *)(CO_CPU_VADDR+reg))=v;
+}
+
+extern __inline unsigned long co_cpu_read(unsigned long reg)
+{
+ return *((volatile unsigned long *)(CO_CPU_VADDR+reg));
+}
+
+extern __inline void co_apic_write(unsigned long reg, unsigned long v)
+{
+ *((volatile unsigned long *)(CO_APIC_VADDR+reg))=v;
+}
+
+extern __inline unsigned long co_apic_read(unsigned long reg)
+{
+ return *((volatile unsigned long *)(CO_APIC_VADDR+reg));
+}
+#endif
+
+extern char visws_board_type;
+
+#define VISWS_320 0
+#define VISWS_540 1
+
+extern char visws_board_rev;
+
+#endif
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-i386/fixmap.h linux/include/asm-i386/fixmap.h
--- v2.2.0-pre8/linux/include/asm-i386/fixmap.h Mon Oct 5 13:13:42 1998
+++ linux/include/asm-i386/fixmap.h Wed Jan 20 16:21:43 1999
@@ -11,8 +11,9 @@
X #ifndef _ASM_FIXMAP_H
X #define _ASM_FIXMAP_H
X
-#include <asm/page.h>
+#include <linux/config.h>
X #include <linux/kernel.h>
+#include <asm/page.h>
X
X /*
X * Here we define all the compile-time 'special' virtual
@@ -40,9 +41,17 @@
X * fix-mapped?
X */
X enum fixed_addresses {
-#ifdef __SMP__
- FIX_APIC_BASE,
+#ifdef CONFIG_X86_LOCAL_APIC
+ FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */
+#endif
+#ifdef CONFIG_X86_IO_APIC
X FIX_IO_APIC_BASE,
+#endif
+#ifdef CONFIG_X86_VISWS_APIC
+ FIX_CO_CPU, /* Cobalt timer */
+ FIX_CO_APIC, /* Cobalt APIC Redirection Table */
+ FIX_LI_PCIA, /* Lithium PCI Bridge A */
+ FIX_LI_PCIB, /* Lithium PCI Bridge B */
X #endif
X __end_of_fixed_addresses
X };
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-i386/i82489.h linux/include/asm-i386/i82489.h
--- v2.2.0-pre8/linux/include/asm-i386/i82489.h Mon Sep 11 10:15:45 1995
+++ linux/include/asm-i386/i82489.h Wed Jan 20 10:18:53 1999
@@ -6,6 +6,7 @@
X *
X * Alan Cox <Alan...@linux.org>, 1995.
X */
+#define APIC_PHYS_BASE 0xfee00000 /* IA s/w dev Vol 3, Section 7.4 */
X
X #define APIC_ID 0x20
X #define GET_APIC_ID(x) (((x)>>24)&0x0F)
@@ -84,5 +85,17 @@
X #define APIC_TDR_DIV_32 0x8
X #define APIC_TDR_DIV_64 0x9
X #define APIC_TDR_DIV_128 0xA
+
+#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
+
+extern __inline void apic_write(unsigned long reg, unsigned long v)
+{
+ *((volatile unsigned long *)(APIC_BASE+reg))=v;
+}
+
+extern __inline unsigned long apic_read(unsigned long reg)
+{
+ return *((volatile unsigned long *)(APIC_BASE+reg));
+}
X
X #endif
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-i386/lithium.h linux/include/asm-i386/lithium.h
--- v2.2.0-pre8/linux/include/asm-i386/lithium.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-i386/lithium.h Wed Jan 20 10:18:53 1999
@@ -0,0 +1,40 @@
+#ifndef __I386_LITHIUM_H
+#define __I386_LITHIUM_H
+
+/*
+ * Lithium is the I/O ASIC on the SGI 320 and 540 Visual Workstations
+ */
+
+#define LI_PCI_A_PHYS 0xfc000000 /* Enet is dev 3 */
+#define LI_PCI_B_PHYS 0xfd000000 /* PIIX4 is here */
+
+/* see set_fixmap() and asm/fixmap.h */
+#define LI_PCIA_VADDR (fix_to_virt(FIX_LI_PCIA))
+#define LI_PCIB_VADDR (fix_to_virt(FIX_LI_PCIB))
+
+/* Not a standard PCI? (not in linux/pci.h) */
+#define LI_PCI_BUSNUM 0x44 /* lo8: primary, hi8: sub */
+#define LI_PCI_INTEN 0x46
+
+/* More special purpose macros... */
+extern __inline void li_pcia_write16(unsigned long reg, unsigned short v)
+{
+ *((volatile unsigned short *)(LI_PCIA_VADDR+reg))=v;
+}
+
+extern __inline unsigned short li_pcia_read16(unsigned long reg)
+{
+ return *((volatile unsigned short *)(LI_PCIA_VADDR+reg));
+}
+
+extern __inline void li_pcib_write16(unsigned long reg, unsigned short v)
+{
+ *((volatile unsigned short *)(LI_PCIB_VADDR+reg))=v;
+}
+
+extern __inline unsigned short li_pcib_read16(unsigned long reg)
+{
+ return *((volatile unsigned short *)(LI_PCIB_VADDR+reg));
+}
+
+#endif
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v2.2.0-pre8/linux/include/asm-i386/smp.h Thu Dec 31 10:29:02 1998
+++ linux/include/asm-i386/smp.h Wed Jan 20 16:21:43 1999
@@ -1,12 +1,20 @@
X #ifndef __ASM_SMP_H
X #define __ASM_SMP_H
X
-#ifdef __SMP__
+/*
+ * We need the APIC definitions automatically as part of 'smp.h'
+ */
+#include <linux/config.h>
+#ifdef CONFIG_X86_LOCAL_APIC
X #ifndef ASSEMBLY
-
+#include <asm/fixmap.h>
X #include <asm/i82489.h>
X #include <asm/bitops.h>
-#include <asm/fixmap.h>
+#endif
+#endif
+
+#ifdef __SMP__
+#ifndef ASSEMBLY
X
X #include <linux/tasks.h>
X #include <linux/ptrace.h>
@@ -186,25 +194,6 @@
X extern void smp_callin(void);
X extern void smp_boot_cpus(void);
X extern void smp_store_cpu_info(int id); /* Store per CPU info (like the initial udelay numbers */
-
-/*
- * APIC handlers: Note according to the Intel specification update
- * you should put reads between APIC writes.
- * Intel Pentium processor specification update [11AP, pg 64]
- * "Back to Back Assertions of HOLD May Cause Lost APIC Write Cycle"
- */
-
-#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
-
-extern __inline void apic_write(unsigned long reg, unsigned long v)
-{
- *((volatile unsigned long *)(APIC_BASE+reg))=v;
-}
-
-extern __inline unsigned long apic_read(unsigned long reg)
-{
- return *((volatile unsigned long *)(APIC_BASE+reg));
-}
X
X /*
X * This function is needed by all SMP systems. It must _always_ be valid
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-i386/string.h linux/include/asm-i386/string.h
--- v2.2.0-pre8/linux/include/asm-i386/string.h Tue Jan 19 11:32:53 1999
+++ linux/include/asm-i386/string.h Tue Jan 19 11:03:29 1999
@@ -188,35 +188,6 @@
X return __res;
X }
X
-#define __HAVE_ARCH_STRSTR
-extern inline char * strstr(const char * cs,const char * ct)
-{
-int d0, d1, d2, d3, d4;
-register char * __res;
-__asm__ __volatile__(
- "cld\n\t" \
- "movl %8,%%edi\n\t"
- "repne\n\t"
- "scasb\n\t"
- "notl %%ecx\n\t"
- "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
- "movl %%ecx,%%edx\n"
- "1:\tmovl %8,%%edi\n\t"
- "movl %%esi,%%eax\n\t"
- "movl %%edx,%%ecx\n\t"
- "repe\n\t"
- "cmpsb\n\t"
- "je 2f\n\t" /* also works for empty string, see above */
- "xchgl %%eax,%%esi\n\t"
- "incl %%esi\n\t"
- "cmpb $0,-1(%%eax)\n\t"
- "jne 1b\n\t"
- "xorl %%eax,%%eax\n\t"
- "2:"
- :"=a" (__res), "=&c" (d0), "=&S" (d1), "=&d" (d2), "=&D" (d3), "=&g" (d4) : "0" (0),"1" (0xffffffff),"2" (cs),"4" (ct));
-return __res;
-}
-
X #define __HAVE_ARCH_STRLEN
X extern inline size_t strlen(const char * s)
X {
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v2.2.0-pre8/linux/include/asm-i386/unistd.h Fri Jan 8 22:36:23 1999
+++ linux/include/asm-i386/unistd.h Wed Jan 20 11:06:24 1999
@@ -194,7 +194,7 @@
X #define __NR_sendfile 187
X #define __NR_getpmsg 188 /* some people actually want streams */
X #define __NR_putpmsg 189 /* some people actually want streams */
-#define __NR_vfork 190
+#define __NR_vfork 190
X
X /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
X
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/bootinfo.h linux/include/asm-m68k/bootinfo.h
--- v2.2.0-pre8/linux/include/asm-m68k/bootinfo.h Tue Aug 18 22:02:07 1998
+++ linux/include/asm-m68k/bootinfo.h Tue Jan 19 10:58:34 1999
@@ -46,12 +46,6 @@
X unsigned long data[0]; /* data */
X };
X
-#else /* __ASSEMBLY__ */
-
-BIR_tag = 0
-BIR_size = BIR_tag+2
-BIR_data = BIR_size+2
-
X #endif /* __ASSEMBLY__ */
X
X
@@ -287,14 +281,6 @@
X unsigned long adbdelay;
X unsigned long timedbra;
X };
-#else
-
-#define BI_videoaddr BI_un
-#define BI_videorow BI_videoaddr+4
-#define BI_videodepth BI_videorow+4
-#define BI_dimensions BI_videodepth+4
-#define BI_args BI_dimensions+4
-#define BI_cpuid BI_args+56
X
X #endif
X
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/entry.h linux/include/asm-m68k/entry.h
--- v2.2.0-pre8/linux/include/asm-m68k/entry.h Mon Aug 3 12:45:47 1998
+++ linux/include/asm-m68k/entry.h Tue Jan 19 10:58:34 1999
@@ -37,25 +37,8 @@
X
X #define curptr a2
X
-/*
- * these are offsets into the task-struct
- */
-LTASK_STATE = 0
-LTASK_FLAGS = 4
-LTASK_SIGPENDING = 8
-LTASK_ADDRLIMIT = 12
-LTASK_EXECDOMAIN = 16
-LTASK_NEEDRESCHED = 20
-
-LTSS_KSP = 0
-LTSS_USP = 4
-LTSS_SR = 8
-LTSS_FS = 10
-LTSS_CRP = 12
-LTSS_FPCTXT = 24
-
X /* the following macro is used when enabling interrupts */
-#if defined(CONFIG_ATARI_ONLY) && !defined(CONFIG_HADES)
+#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
X /* block out HSYNC on the atari */
X #define ALLOWINT 0xfbff
X #define MAX_NOINT_IPL 3
@@ -65,22 +48,20 @@
X #define MAX_NOINT_IPL 0


X #endif /* machine compilation types */

X
-LPT_OFF_D0 = 0x20
-LPT_OFF_ORIG_D0 = 0x24
-LPT_OFF_SR = 0x2C
-LPT_OFF_FORMATVEC = 0x32
-
X LFLUSH_I_AND_D = 0x00000808
-LENOSYS = 38
X LSIGTRAP = 5
X
-LPF_TRACESYS_OFF = 3
-LPF_TRACESYS_BIT = 5
-LPF_PTRACED_OFF = 3
-LPF_PTRACED_BIT = 4
-LPF_DTRACE_OFF = 1
-LPF_DTRACE_BIT = 5
-
+/* process bits for task_struct.flags */
+PF_TRACESYS_OFF = 3
+PF_TRACESYS_BIT = 5
+PF_PTRACED_OFF = 3
+PF_PTRACED_BIT = 4
+PF_DTRACE_OFF = 1
+PF_DTRACE_BIT = 5
+
+#define SAVE_ALL_INT save_all_int
+#define SAVE_ALL_SYS save_all_sys
+#define RESTORE_ALL restore_all
X /*
X * This defines the normal kernel pt-regs layout.
X *
@@ -92,56 +73,68 @@
X * a -1 in the orig_d0 field signifies
X * that the stack frame is NOT for syscall
X */
-#define SAVE_ALL_INT \
- clrl %sp@-; /* stk_adj */ \
- pea -1:w; /* orig d0 */ \
- movel %d0,%sp@-; /* d0 */ \
+.macro save_all_int
+ clrl %sp@- | stk_adj
+ pea -1:w | orig d0
+ movel %d0,%sp@- | d0
X moveml %d1-%d5/%a0-%a1/%curptr,%sp@-
+.endm
X
-#define SAVE_ALL_SYS \
- clrl %sp@-; /* stk_adj */ \
- movel %d0,%sp@-; /* orig d0 */ \
- movel %d0,%sp@-; /* d0 */ \
- moveml %d1-%d5/%a0-%a1/%curptr,%sp@-
+.macro save_all_sys
+ clrl %sp@- | stk_adj
+ movel %d0,%sp@- | orig d0
+ movel %d0,%sp@- | d0
+ moveml %d1-%d5/%a0-%a1/%curptr,%sp@-
+.endm
X #else
X /* Need to save the "missing" registers for kgdb...
X */
-#define SAVE_ALL_INT \
- clrl %sp@-; /* stk_adj */ \
- pea -1:w; /* orig d0 */ \
- movel %d0,%sp@-; /* d0 */ \
- moveml %d1-%d5/%a0-%a1/%curptr,%sp@-; \
- moveml %d6-%d7,kgdb_registers+GDBOFFA_D6; \
+.macro save_all_int
+ clrl %sp@- | stk_adj
+ pea -1:w | orig d0
+ movel %d0,%sp@- | d0
+ moveml %d1-%d5/%a0-%a1/%curptr,%sp@-
+ moveml %d6-%d7,kgdb_registers+GDBOFFA_D6
X moveml %a3-%a6,kgdb_registers+GDBOFFA_A3
+.endm
X
-#define SAVE_ALL_SYS \
- clrl %sp@-; /* stk_adj */ \
- movel %d0,%sp@-; /* orig d0 */ \
- movel %d0,%sp@-; /* d0 */ \
- moveml %d1-%d5/%a0-%a1/%curptr,%sp@-; \
- moveml %d6-%d7,kgdb_registers+GDBOFFA_D6; \
+.macro save_all_sys
+ clrl %sp@- | stk_adj
+ movel %d0,%sp@- | orig d0
+ movel %d0,%sp@- | d0
+ moveml %d1-%d5/%a0-%a1/%curptr,%sp@-
+ moveml %d6-%d7,kgdb_registers+GDBOFFA_D6
X moveml %a3-%a6,kgdb_registers+GDBOFFA_A3
+.endm
X #endif
X
-#define RESTORE_ALL \
- moveml %sp@+,%a0-%a1/%curptr/%d1-%d5; \
- movel %sp@+,%d0; \
- addql #4,%sp; /* orig d0 */ \
- addl %sp@+,%sp; /* stk adj */ \
+.macro restore_all
+ moveml %sp@+,%a0-%a1/%curptr/%d1-%d5
+ movel %sp@+,%d0
+ addql #4,%sp | orig d0
+ addl %sp@+,%sp | stk adj
X rte
+.endm
X
X #define SWITCH_STACK_SIZE (6*4+4) /* includes return address */
X
-#define SAVE_SWITCH_STACK \
+#define SAVE_SWITCH_STACK save_switch_stack
+#define RESTORE_SWITCH_STACK restore_switch_stack
+#define GET_CURRENT(tmp) get_current tmp
+
+.macro save_switch_stack
X moveml %a3-%a6/%d6-%d7,%sp@-
+.endm
X
-#define RESTORE_SWITCH_STACK \
+.macro restore_switch_stack
X moveml %sp@+,%a3-%a6/%d6-%d7
+.endm
X
-#define GET_CURRENT(tmp) \
- movel %sp,tmp; \
- andw &-8192,tmp; \
- movel tmp,%curptr;
+.macro get_current reg=%d0
+ movel %sp,\reg
+ andw #-8192,\reg
+ movel \reg,%curptr
+.endm
X
X #else /* C source */
X
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/ide.h linux/include/asm-m68k/ide.h
--- v2.2.0-pre8/linux/include/asm-m68k/ide.h Thu Nov 12 16:21:24 1998
+++ linux/include/asm-m68k/ide.h Tue Jan 19 10:58:34 1999
@@ -449,7 +449,7 @@
X * an interrupt, and in that case it does nothing. Hope that is reasonable and
X * works. (Roman)
X */
-#ifdef CONFIG_ATARI_ONLY
+#ifdef MACH_ATARI_ONLY
X #define ide__sti() \
X do { \
X if (!in_interrupt()) __sti(); \
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/init.h linux/include/asm-m68k/init.h
--- v2.2.0-pre8/linux/include/asm-m68k/init.h Thu Jan 7 15:11:40 1999
+++ linux/include/asm-m68k/init.h Tue Jan 19 10:58:34 1999
@@ -16,7 +16,7 @@
X #define __INITDATA .section ".data.init",#alloc,#write
X
X #define __cacheline_aligned __attribute__ \
- ((__section__ (".data.cacheline_aligned")))
+ ((__aligned__(16), __section__ (".data.cacheline_aligned")))
X
X #else
X
@@ -30,8 +30,8 @@
X #define __INIT
X #define __FINIT
X #define __INITDATA
-#define __cacheline_aligned
+#define __cacheline_aligned __attribute__ ((__aligned__(16)))
X
X #endif /* CONFIG_KGDB */
-
+
X #endif
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/io.h linux/include/asm-m68k/io.h
--- v2.2.0-pre8/linux/include/asm-m68k/io.h Sat Sep 5 16:46:41 1998
+++ linux/include/asm-m68k/io.h Tue Jan 19 10:58:34 1999
@@ -43,6 +43,35 @@
X #define outb(x,addr) ((void) writeb(x,addr))
X #define outb_p(x,addr) outb(x,addr)
X
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING 0
+#define IOMAP_NOCACHE_SER 1
+#define IOMAP_NOCACHE_NONSER 2
+#define IOMAP_WRITETHROUGH 3
+
+extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+extern void __iounmap(void *addr, unsigned long size);
+
+extern inline void *ioremap(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+extern inline void *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+extern inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+extern void iounmap(void *addr);
+
X #endif /* __KERNEL__ */
X
X #endif /* _M68K_IO_H */
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/keyboard.h linux/include/asm-m68k/keyboard.h
--- v2.2.0-pre8/linux/include/asm-m68k/keyboard.h Tue Aug 18 22:02:07 1998
+++ linux/include/asm-m68k/keyboard.h Tue Jan 19 10:58:34 1999
@@ -52,9 +52,9 @@
X
X #ifdef CONFIG_MAGIC_SYSRQ
X #define kbd_is_sysrq(keycode) ((keycode) == mach_sysrq_key && \
- (up_flag || \
- (shift_state & mach_sysrq_shift_mask) == \
- mach_sysrq_shift_state))
+ (up_flag || \
+ (shift_state & mach_sysrq_shift_mask) == \
+ mach_sysrq_shift_state))
X #define kbd_sysrq_xlate mach_sysrq_xlate
X #endif
X
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/machdep.h linux/include/asm-m68k/machdep.h
--- v2.2.0-pre8/linux/include/asm-m68k/machdep.h Fri Oct 9 13:27:15 1998
+++ linux/include/asm-m68k/machdep.h Tue Jan 19 10:58:34 1999
@@ -13,7 +13,6 @@
X extern int (*mach_keyb_init) (void);
X extern int (*mach_kbdrate) (struct kbd_repeat *);
X extern void (*mach_kbd_leds) (unsigned int);
-extern void (*kbd_reset_setup) (char *, int);


X /* machine dependent irq functions */

X extern void (*mach_init_IRQ) (void);
X extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/machw.h linux/include/asm-m68k/machw.h
--- v2.2.0-pre8/linux/include/asm-m68k/machw.h Tue Aug 18 22:02:07 1998
+++ linux/include/asm-m68k/machw.h Tue Jan 19 10:58:34 1999
@@ -13,6 +13,16 @@
X #ifndef _ASM_MACHW_H_
X #define _ASM_MACHW_H_
X
+/*
+ * head.S maps the videomem to VIDEOMEMBASE
+ */
+
+#define VIDEOMEMBASE 0xf0000000
+#define VIDEOMEMSIZE (4096*1024)
+#define VIDEOMEMMASK (-4096*1024)
+
+#ifndef __ASSEMBLY__
+
X #include <linux/types.h>
X
X /* Mac SCSI Controller 5380 */
@@ -142,5 +152,7 @@
X } mac_hw_present;
X
X /* extern struct mac_hw_present mac_hw_present; */
+
+#endif /* __ASSEMBLY__ */
X
X #endif /* linux/machw.h */
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/page.h linux/include/asm-m68k/page.h
--- v2.2.0-pre8/linux/include/asm-m68k/page.h Fri May 8 23:14:55 1998
+++ linux/include/asm-m68k/page.h Tue Jan 19 10:58:34 1999
@@ -8,7 +8,7 @@
X
X #ifdef __KERNEL__
X
-#include<linux/config.h>
+#include <asm/setup.h>
X
X #define STRICT_MM_TYPECHECKS
X
@@ -18,7 +18,7 @@
X /*
X * We don't need to check for alignment etc.
X */
-#if defined(CONFIG_OPTIMIZE_040) || defined(CONFIG_OPTIMIZE_060)
+#ifdef CPU_M68040_OR_M68060_ONLY
X static inline void copy_page(unsigned long to, unsigned long from)
X {
X unsigned long tmp;
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/pgtable.h linux/include/asm-m68k/pgtable.h
--- v2.2.0-pre8/linux/include/asm-m68k/pgtable.h Tue Dec 22 14:16:58 1998
+++ linux/include/asm-m68k/pgtable.h Tue Jan 19 10:58:34 1999
@@ -13,14 +13,7 @@
X * the m68k page table tree.
X */
X
-/* For virtual address to physical address conversion */
-extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
-extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
-
-#include<asm/virtconvert.h>
-
-#define VTOP(addr) (mm_vtop((unsigned long)(addr)))
-#define PTOV(addr) (mm_ptov((unsigned long)(addr)))
+#include <asm/virtconvert.h>
X
X /*
X * Cache handling functions
@@ -436,34 +429,24 @@
X extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
X {
X int i;
-
- ptep = (pte_t *) virt_to_phys(ptep);
- for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16)
- pmdp->pmd[i] = _PAGE_TABLE | _PAGE_ACCESSED | (unsigned long)ptep;
-}
-
-/* early termination version of the above */
-extern inline void pmd_set_et(pmd_t * pmdp, pte_t * ptep)
-{
- int i;
-
- ptep = (pte_t *) virt_to_phys(ptep);
- for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16)
- pmdp->pmd[i] = _PAGE_PRESENT | _PAGE_ACCESSED | (unsigned long)ptep;
+ unsigned long ptbl;
+ ptbl = virt_to_phys(ptep);
+ for (i = 0; i < 16; i++, ptbl += sizeof(pte_table)/16)
+ pmdp->pmd[i] = _PAGE_TABLE | _PAGE_ACCESSED | ptbl;
X }
X
X extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
X { pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | virt_to_phys(pmdp); }
X
X extern inline unsigned long pte_page(pte_t pte)
-{ return (unsigned long)phys_to_virt((unsigned long)(pte_val(pte) & PAGE_MASK)); }
+{ return (unsigned long)phys_to_virt(pte_val(pte) & PAGE_MASK); }
X
X extern inline unsigned long pmd_page2(pmd_t *pmd)
-{ return (unsigned long)phys_to_virt((unsigned long)(pmd_val(*pmd) & _TABLE_MASK)); }
+{ return (unsigned long)phys_to_virt(pmd_val(*pmd) & _TABLE_MASK); }
X #define pmd_page(pmd) pmd_page2(&(pmd))
X
X extern inline unsigned long pgd_page(pgd_t pgd)
-{ return (unsigned long)phys_to_virt((unsigned long)(pgd_val(pgd) & _TABLE_MASK)); }
+{ return (unsigned long)phys_to_virt(pgd_val(pgd) & _TABLE_MASK); }
X
X extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
X extern inline int pte_present(pte_t pte) { return pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER); }
@@ -547,7 +530,7 @@
X return mm->pgd + (address >> PGDIR_SHIFT);
X }
X
-extern pgd_t swapper_pg_dir[128];
+#define swapper_pg_dir kernel_pg_dir
X extern pgd_t kernel_pg_dir[128];
X
X extern inline pgd_t * pgd_offset_k(unsigned long address)
@@ -625,8 +608,6 @@
X
X extern pmd_t *get_pointer_table(void);
X extern int free_pointer_table(pmd_t *);
-extern pmd_t *get_kpointer_table(void);
-extern void free_kpointer_table(pmd_t *);
X
X extern __inline__ pte_t *get_pte_fast(void)
X {
@@ -754,29 +735,12 @@
X
X extern inline void pmd_free_kernel(pmd_t * pmd)
X {
- free_kpointer_table(pmd);
+ free_pmd_fast(pmd);
X }
X
X extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
X {
- address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
- if (pgd_none(*pgd)) {
- pmd_t *page = get_kpointer_table();
- if (pgd_none(*pgd)) {
- if (page) {
- pgd_set(pgd, page);


- return page + address;
- }

- pgd_set(pgd, (pmd_t *)BAD_PAGETABLE);
- return NULL;
- }
- free_kpointer_table(page);
- }
- if (pgd_bad(*pgd)) {
- __bad_pmd(pgd);
- return NULL;
- }
- return (pmd_t *) pgd_page(*pgd) + address;
+ return pmd_alloc(pgd, address);
X }
X
X extern inline void pgd_free(pgd_t * pgd)
@@ -815,26 +779,7 @@
X int mm_end_of_chunk (unsigned long addr, int len);
X #endif
X
-/*
- * Map some physical address range into the kernel address space.
- */
-extern unsigned long kernel_map(unsigned long paddr, unsigned long size,
- int nocacheflag, unsigned long *memavailp );
-/*
- * Unmap a region alloced by kernel_map().
- */
-extern void kernel_unmap( unsigned long addr );
-/*
- * Change the cache mode of some kernel address range.
- */
-extern void kernel_set_cachemode( unsigned long address, unsigned long size,
- unsigned cmode );
-
-/* Values for nocacheflag and cmode */
-#define KERNELMAP_FULL_CACHING 0
-#define KERNELMAP_NOCACHE_SER 1
-#define KERNELMAP_NOCACHE_NONSER 2
-#define KERNELMAP_NO_COPYBACK 3
+extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode);
X
X /*
X * The m68k doesn't have any external MMU info: the kernel page
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h
--- v2.2.0-pre8/linux/include/asm-m68k/processor.h Tue Jan 19 11:32:53 1999
+++ linux/include/asm-m68k/processor.h Tue Jan 19 10:58:34 1999
@@ -72,6 +72,8 @@
X {
X }
X
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
X #define copy_segments(nr, tsk, mm) do { } while (0)
X #define release_segments(mm) do { } while (0)
X #define forget_segments() do { } while (0)
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/semaphore.h linux/include/asm-m68k/semaphore.h
--- v2.2.0-pre8/linux/include/asm-m68k/semaphore.h Tue Jan 19 11:32:53 1999
+++ linux/include/asm-m68k/semaphore.h Tue Jan 19 10:58:34 1999
@@ -3,6 +3,7 @@
X
X #include <linux/config.h>
X #include <linux/linkage.h>
+#include <asm/current.h>
X #include <asm/system.h>
X #include <asm/atomic.h>
X
@@ -16,12 +17,23 @@
X
X struct semaphore {
X atomic_t count;
+ unsigned long owner, owner_depth;
X atomic_t waking;
X struct wait_queue * wait;
X };
X
-#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL })
-#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL })
+/*
+ * Because we want the non-contention case to be
+ * fast, we save the stack pointer into the "owner"
+ * field, and to get the true task pointer we have
+ * to do the bit masking. That moves the masking
+ * operation into the slow path.
+ */
+#define semaphore_owner(sem) \
+ ((struct task_struct *)((2*PAGE_MASK) & (sem)->owner))
+
+#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, 0, ATOMIC_INIT(0), NULL })
+#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, 1, ATOMIC_INIT(0), NULL })
X
X asmlinkage void __down_failed(void /* special register calling convention */);
X asmlinkage int __down_failed_interruptible(void /* params in registers */);
@@ -46,7 +58,9 @@
X
X save_flags(flags);
X cli();
- if (atomic_read(&sem->waking) > 0) {
+ if (atomic_read(&sem->waking) > 0 || (owner_depth && semaphore_owner(sem) == tsk)) {
+ sem->owner = (unsigned long)tsk;
+ sem->owner_depth++;
X atomic_dec(&sem->waking);
X ret = 1;
X }
@@ -56,7 +70,7 @@
X
X __asm__ __volatile__
X ("1: movel %2,%0\n"
- " jeq 3f\n"
+ " jeq 3f\n"
X "2: movel %0,%1\n"
X " subql #1,%1\n"
X " casl %0,%1,%2\n"
@@ -65,6 +79,13 @@
X " jne 2b\n"
X "3:"
X : "=d" (ret), "=d" (tmp), "=m" (sem->waking));
+
+ ret |= ((sem->owner_depth != 0) && (semaphore_owner(sem) == tsk));
+ if (ret) {
+ sem->owner = (unsigned long)tsk;
+ sem->owner_depth++;
+ }
+
X #endif
X return ret;
X }
@@ -80,7 +101,9 @@
X __asm__ __volatile__(
X "| atomic down operation\n\t"
X "subql #1,%0@\n\t"
- "jmi 2f\n"
+ "jmi 2f\n\t"
+ "movel %%sp,4(%0)\n"
+ "movel #1,8(%0)\n\t"
X "1:\n"
X ".section .text.lock,\"ax\"\n"
X ".even\n"
@@ -101,6 +124,9 @@
X "| atomic interruptible down operation\n\t"
X "subql #1,%1@\n\t"
X "jmi 2f\n\t"
+ "movel %%sp,4(%1)\n"
+ "moveql #1,%0\n"
+ "movel %0,8(%1)\n"
X "clrl %0\n"
X "1:\n"
X ".section .text.lock,\"ax\"\n"
@@ -125,6 +151,7 @@
X register struct semaphore *sem1 __asm__ ("%a1") = sem;
X __asm__ __volatile__(
X "| atomic up operation\n\t"
+ "subql #1,8(%0)\n\t"
X "addql #1,%0@\n\t"
X "jle 2f\n"
X "1:\n"
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/setup.h linux/include/asm-m68k/setup.h
--- v2.2.0-pre8/linux/include/asm-m68k/setup.h Sat Sep 5 16:46:41 1998
+++ linux/include/asm-m68k/setup.h Tue Jan 19 10:58:34 1999
@@ -52,7 +52,7 @@
X || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) || defined(CONFIG_HP300)
X # define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA)
X #else
-# define CONFIG_AMIGA_ONLY
+# define MACH_AMIGA_ONLY
X # define MACH_IS_AMIGA (1)
X # define MACH_TYPE (MACH_AMIGA)
X #endif
@@ -63,7 +63,7 @@
X || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) || defined(CONFIG_HP300)
X # define MACH_IS_ATARI (m68k_machtype == MACH_ATARI)
X #else
-# define CONFIG_ATARI_ONLY
+# define MACH_ATARI_ONLY
X # define MACH_IS_ATARI (1)
X # define MACH_TYPE (MACH_ATARI)
X #endif
@@ -74,7 +74,7 @@
X || defined(CONFIG_HP300) || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)
X # define MACH_IS_MAC (m68k_machtype == MACH_MAC)
X #else
-# define CONFIG_MAC_ONLY
+# define MACH_MAC_ONLY
X # define MACH_IS_MAC (1)
X # define MACH_TYPE (MACH_MAC)
X #endif
@@ -91,7 +91,7 @@
X || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) || defined(CONFIG_HP300)
X # define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO)
X #else
-# define CONFIG_APOLLO_ONLY
+# define MACH_APOLLO_ONLY
X # define MACH_IS_APOLLO (1)
X # define MACH_TYPE (MACH_APOLLO)
X #endif
@@ -102,7 +102,7 @@
X || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) || defined(CONFIG_HP300)
X # define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x)
X #else
-# define CONFIG_MVME16x_ONLY
+# define MACH_MVME16x_ONLY
X # define MACH_IS_MVME16x (1)
X # define MACH_TYPE (MACH_MVME16x)
X #endif
@@ -113,7 +113,7 @@
X || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) || defined(CONFIG_HP300)
X # define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000)
X #else
-# define CONFIG_BVME6000_ONLY
+# define MACH_BVME6000_ONLY
X # define MACH_IS_BVME6000 (1)
X # define MACH_TYPE (MACH_BVME6000)
X #endif
@@ -124,7 +124,7 @@
X || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000)
X # define MAC_IS_HP300 (m68k_machtype == MACH_HP300)
X #else
-# define CONFIG_HP300_ONLY
+# define MACH_HP300_ONLY
X # define MACH_IS_HP300 (1)
X # define MACH_TYPE (MACH_HP300)
X #endif
@@ -260,6 +260,7 @@
X
X #define CPU_TYPE (m68k_cputype)
X
+
X /*
X * Miscellaneous
X */
@@ -268,7 +269,8 @@
X #define CL_SIZE 256
X
X #ifndef __ASSEMBLY__
-extern int m68k_num_memory; /* # of memory blocks found */
+extern int m68k_num_memory; /* # of memory blocks found (and used) */
+extern int m68k_realnum_memory; /* real # of memory blocks found */
X extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */
X
X struct mem_info {
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/system.h linux/include/asm-m68k/system.h
--- v2.2.0-pre8/linux/include/asm-m68k/system.h Tue Jun 23 10:01:28 1998
+++ linux/include/asm-m68k/system.h Tue Jan 19 10:58:34 1999
@@ -46,11 +46,8 @@
X #define switch_to(prev,next) { \
X register void *_prev __asm__ ("a0") = (prev); \
X register void *_next __asm__ ("a1") = (next); \
- register int _tssoff __asm__ ("d1") = (int)&((struct task_struct *)0)->tss; \
- register char _shared __asm__ ("d2") = ((prev)->mm == (next)->mm); \
- __asm__ __volatile__("jbsr " SYMBOL_NAME_STR(resume) "\n\t" \
- : : "a" (_prev), "a" (_next), "d" (_tssoff), \
- "d" (_shared) \
+ __asm__ __volatile__("jbsr " SYMBOL_NAME_STR(resume) \
+ : : "a" (_prev), "a" (_next) \
X : "d0", "d1", "d2", "d3", "d4", "d5", "a0", "a1"); \
X }
X
@@ -60,7 +57,7 @@
X struct __xchg_dummy { unsigned long a[100]; };
X #define __xg(x) ((volatile struct __xchg_dummy *)(x))
X
-#if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC) && !defined(CONFIG_HADES) && !defined(CONFIG_VME) && !defined(CONFIG_APOLLO)
+#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
X /* block out HSYNC on the atari */
X #define __sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory")
X #else /* portable version */
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/traps.h linux/include/asm-m68k/traps.h
--- v2.2.0-pre8/linux/include/asm-m68k/traps.h Sun May 19 21:54:29 1996
+++ linux/include/asm-m68k/traps.h Tue Jan 19 10:58:34 1999
@@ -11,10 +11,14 @@
X #ifndef _M68K_TRAPS_H
X #define _M68K_TRAPS_H
X
+#ifndef __ASSEMBLY__
+
X typedef void (*e_vector)(void);
X
X extern e_vector vectors[];
X
+#endif
+
X #define VEC_BUSERR (2)
X #define VEC_ADDRERR (3)
X #define VEC_ILLEGAL (4)
@@ -63,9 +67,12 @@
X #define VEC_FPUNSUP (55)
X #define VEC_UNIMPEA (60)
X #define VEC_UNIMPII (61)
+#define VEC_USER (64)
X
X #define VECOFF(vec) ((vec)<<2)
X
+#ifndef __ASSEMBLY__
+
X /* Status register bits */
X #define PS_T (0x8000)
X #define PS_S (0x2000)
@@ -237,5 +244,7 @@
X } fmtb;
X } un;
X };
+
+#endif /* __ASSEMBLY__ */
X
X #endif /* _M68K_TRAPS_H */
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/unistd.h linux/include/asm-m68k/unistd.h
--- v2.2.0-pre8/linux/include/asm-m68k/unistd.h Fri Oct 9 13:27:15 1998
+++ linux/include/asm-m68k/unistd.h Tue Jan 19 10:58:34 1999
@@ -193,6 +193,7 @@
X #define __NR_sendfile 187
X #define __NR_getpmsg 188 /* some people actually want streams */
X #define __NR_putpmsg 189 /* some people actually want streams */
+#define __NR_vfork 190
X
X /* user-visible error numbers are in the range -1 - -122: see
X <asm-m68k/errno.h> */
@@ -322,49 +323,6 @@
X static inline _syscall1(int,_exit,int,exitcode)
X static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
X static inline _syscall1(int,delete_module,const char *,name)
-
-/*
- * This is the mechanism for creating a new kernel thread.
- *
- * NOTE! Only a kernel-only process(ie the swapper or direct descendants
- * who haven't done an "execve()") should use this: it will work within
- * a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
- */
-static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- pid_t pid;
- mm_segment_t fs;
-
- fs = get_fs();
- set_fs (KERNEL_DS);
-
- {
- register long retval __asm__ ("d0");
- register long clone_arg __asm__ ("d1") = flags | CLONE_VM;
-
- __asm__ __volatile__
- ("clrl %%d2\n\t"
- "trap #0\n\t" /* Linux/m68k system call */
- "tstl %0\n\t" /* child or parent */
- "jne 1f\n\t" /* parent - jump */
- "lea %%sp@(-8192),%6\n\t" /* reload current */
- "movel %3,%%sp@-\n\t" /* push argument */
- "jsr %4@\n\t" /* call fn */
- "movel %0,%%d1\n\t" /* pass exit value */
- "movel %2,%0\n\t" /* exit */
- "trap #0\n"
- "1:"
- : "=d" (retval)
- : "0" (__NR_clone), "i" (__NR_exit),
- "r" (arg), "a" (fn), "d" (clone_arg), "r" (current)
- : "d0", "d2");
- pid = retval;
- }
-
- set_fs (fs);
- return pid;
-}
X
X static inline pid_t wait(int * wait_stat)
X {
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-m68k/virtconvert.h linux/include/asm-m68k/virtconvert.h
--- v2.2.0-pre8/linux/include/asm-m68k/virtconvert.h Sat Sep 5 16:46:41 1998
+++ linux/include/asm-m68k/virtconvert.h Tue Jan 19 10:58:34 1999
@@ -18,7 +18,7 @@
X * Change virtual addresses to physical addresses and vv.
X */
X extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
-extern unsigned long mm_vtop_fallback (unsigned long);
+extern unsigned long mm_vtop_fallback (unsigned long) __attribute__ ((const));
X extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
X
X #ifdef CONFIG_SINGLE_MEMORY_CHUNK
diff -u --recursive --new-file v2.2.0-pre8/linux/include/asm-sparc64/pgtable.h linux/include/asm-sparc64/pgtable.h
--- v2.2.0-pre8/linux/include/asm-sparc64/pgtable.h Thu Nov 19 09:56:29 1998
+++ linux/include/asm-sparc64/pgtable.h Wed Jan 20 13:40:48 1999
@@ -371,7 +371,7 @@
X (unsigned long)ret->pprev_hash = mask;
X if (!mask)


X pgd_quicklist = (unsigned long *)ret->next_hash;
- ret = (struct page *)(PAGE_OFFSET + (ret->map_nr << PAGE_SHIFT) + off);

+ ret = (struct page *) (page_address(ret) + off);
X pgd_cache_size--;
X } else {
X ret = (struct page *) __get_free_page(GFP_KERNEL);
diff -u --recursive --new-file v2.2.0-pre8/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.2.0-pre8/linux/include/linux/fs.h Tue Jan 19 11:32:53 1999
+++ linux/include/linux/fs.h Wed Jan 20 16:23:30 1999
@@ -420,7 +420,7 @@
X struct file_operations *f_op;
X mode_t f_mode;
X loff_t f_pos;
- unsigned short f_count, f_flags;
+ unsigned int f_count, f_flags;
X unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;
X struct fown_struct f_owner;
X
diff -u --recursive --new-file v2.2.0-pre8/linux/include/linux/isdn.h linux/include/linux/isdn.h
--- v2.2.0-pre8/linux/include/linux/isdn.h Wed Apr 1 20:11:54 1998
+++ linux/include/linux/isdn.h Tue Jan 19 11:06:52 1999
@@ -1,9 +1,3 @@
-/* Changes for X.25 support:
- Added ISDN_NET_ENCAP_X25IFACE macro.
- Additional field in isdn_net_dev_s and isdn_net_local to support
- generic encapsulation protocols.
-*/
-
X /* $Id: isdn.h,v 1.37 1998/02/22 19:45:24 fritz Exp $
X *
X * Main header for the Linux ISDN subsystem (linklevel).
@@ -26,6 +20,10 @@


X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
+ * Note: This file differs from the corresponding revision as present in the
+ * isdn4linux CVS repository because some later bug fixes have been extracted
+ * from the repository and merged into this file. -- Henner Eisen
+ *

X * $Log: isdn.h,v $
X * Revision 1.37 1998/02/22 19:45:24 fritz
X * Some changes regarding V.110
@@ -800,6 +798,7 @@
X int v110emu[ISDN_MAX_CHANNELS];/* V.110 emulator-mode 0=none */
X atomic_t v110use[ISDN_MAX_CHANNELS];/* Usage-Semaphore for stream */
X isdn_v110_stream *v110[ISDN_MAX_CHANNELS]; /* V.110 private data */
+ struct semaphore sem; /* serialize list access*/
X } isdn_dev;
X
X extern isdn_dev *dev;
diff -u --recursive --new-file v2.2.0-pre8/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.2.0-pre8/linux/include/linux/mm.h Tue Jan 19 11:32:53 1999
+++ linux/include/linux/mm.h Wed Jan 20 16:23:32 1999
@@ -125,12 +125,10 @@
X unsigned long offset;
X struct page *next_hash;
X atomic_t count;
- unsigned int unused;
X unsigned long flags; /* atomic flags, some possibly updated asynchronously */
X struct wait_queue *wait;
X struct page **pprev_hash;
X struct buffer_head * buffers;
- unsigned long map_nr; /* page->map_nr == page - mem_map */
X } mem_map_t;
X
X /* Page flag bit values */
@@ -263,6 +261,8 @@
X clear_page(page);
X return page;
X }
+
+extern int low_on_memory;
X
X /* memory.c & swap.c*/
X
diff -u --recursive --new-file v2.2.0-pre8/linux/include/linux/pagemap.h linux/include/linux/pagemap.h
--- v2.2.0-pre8/linux/include/linux/pagemap.h Thu Nov 19 09:56:29 1998
+++ linux/include/linux/pagemap.h Wed Jan 20 16:23:33 1999
@@ -14,7 +14,7 @@
X
X static inline unsigned long page_address(struct page * page)
X {
- return PAGE_OFFSET + PAGE_SIZE * page->map_nr;
+ return PAGE_OFFSET + PAGE_SIZE * (page - mem_map);
X }
X
X #define PAGE_HASH_BITS 11
diff -u --recursive --new-file v2.2.0-pre8/linux/include/linux/poll.h linux/include/linux/poll.h
--- v2.2.0-pre8/linux/include/linux/poll.h Tue Jan 19 11:32:53 1999
+++ linux/include/linux/poll.h Wed Jan 20 16:23:35 1999
@@ -25,35 +25,14 @@
X

SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 09'
echo 'File patch-2.2.0-pre9 is continued in part 10'
echo 10 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part10

#!/bin/sh
# this is part 10 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 10; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

X #define __MAX_POLL_TABLE_ENTRIES ((PAGE_SIZE - sizeof (poll_table)) / sizeof (struct poll_table_entry))
X
+extern void __pollwait(struct file * filp, struct wait_queue ** wait_address, poll_table *p);
+
X extern inline void poll_wait(struct file * filp, struct wait_queue ** wait_address, poll_table *p)
X {
- struct poll_table_entry * entry;
-
- if (!p || !wait_address)
- return;
- while (p->nr >= __MAX_POLL_TABLE_ENTRIES && p->next != NULL)
- p = p->next;
- if (p->nr >= __MAX_POLL_TABLE_ENTRIES) {
- poll_table *tmp = (poll_table *) __get_free_page(GFP_KERNEL);
- if (!tmp)
- return;
- tmp->nr = 0;
- tmp->entry = (struct poll_table_entry *)(tmp + 1);
- tmp->next = NULL;
- p->next = tmp;
- p = tmp;
- }
- entry = p->entry + p->nr;
- entry->filp = filp;
- filp->f_count++;
- entry->wait_address = wait_address;
- entry->wait.task = current;
- entry->wait.next = NULL;
- add_wait_queue(wait_address,&entry->wait);
- p->nr++;
+ if (p && wait_address)
+ __pollwait(filp, wait_address, p);


X }
X
-
X /*

X * For the kernel fd_set we use a fixed set-size for allocation purposes.
X * This set-size doesn't necessarily bear any relation to the size the user
@@ -70,15 +49,6 @@
X #define KFDS_64BLOCK ((PAGE_SIZE/(6*64))*64)
X #define KFDS_NR (KFDS_64BLOCK*8 > NR_OPEN ? NR_OPEN : KFDS_64BLOCK*8)
X typedef unsigned long kernel_fd_set[KFDS_NR/__NFDBITS];
-
-/*
- * XXX - still used by alpha osf and sparc32 compatiblity.
- */
-
-typedef struct {
- kernel_fd_set in, out, ex;
- kernel_fd_set res_in, res_out, res_ex;
-} fd_set_buffer;
X
X /*
X * Scaleable version of the fd_set.
diff -u --recursive --new-file v2.2.0-pre8/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.2.0-pre8/linux/include/linux/swap.h Wed Jan 13 15:00:44 1999
+++ linux/include/linux/swap.h Wed Jan 20 16:21:45 1999
@@ -1,6 +1,8 @@
X #ifndef _LINUX_SWAP_H
X #define _LINUX_SWAP_H
X
+#include <asm/page.h>
+
X #define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */
X #define SWAP_FLAG_PRIO_MASK 0x7fff
X #define SWAP_FLAG_PRIO_SHIFT 0
@@ -25,6 +27,13 @@
X };
X
X #ifdef __KERNEL__
+
+/*
+ * Max bad pages in the new format..
+ */
+#define __swapoffset(x) ((unsigned long)&((union swap_header *)0)->x)
+#define MAX_SWAP_BADPAGES \
+ ((__swapoffset(magic.magic) - __swapoffset(info.badpages)) / sizeof(int))
X
X #undef DEBUG_SWAP
X
diff -u --recursive --new-file v2.2.0-pre8/linux/include/linux/timex.h linux/include/linux/timex.h
--- v2.2.0-pre8/linux/include/linux/timex.h Fri May 8 23:14:57 1998
+++ linux/include/linux/timex.h Wed Jan 20 16:21:43 1999
@@ -45,6 +45,8 @@
X * Derived linux/timex.h
X * 1995-08-13 Torsten Duwe
X * kernel PLL updated to 1994-12-13 specs (rfc-1589)
+ * 1997-08-30 Ulrich Windl
+ * Added new constant NTP_PHASE_LIMIT
X */
X #ifndef _LINUX_TIMEX_H
X #define _LINUX_TIMEX_H
@@ -102,6 +104,7 @@
X #define MAXTIME (200L << PPS_AVG) /* max PPS error (jitter) (200 us) */
X #define MINSEC 16L /* min interval between updates (s) */
X #define MAXSEC 1200L /* max interval between updates (s) */
+#define NTP_PHASE_LIMIT (MAXPHASE << 5) /* beyond max. dispersion */
X
X /*
X * The following defines are used only if a pulse-per-second (PPS)
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/crc.h linux/include/net/irda/crc.h
--- v2.2.0-pre8/linux/include/net/irda/crc.h Tue Dec 22 14:16:58 1998
+++ linux/include/net/irda/crc.h Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Mon Aug 4 20:40:53 1997
- * Modified at: Sat Dec 12 23:09:29 1998
+ * Modified at: Tue Dec 15 22:18:53 1998


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X ********************************************************************/
@@ -20,7 +20,7 @@
X #define GOOD_FCS 0xf0b8 /* Good final FCS value */
X
X /* Recompute the FCS with one more character appended. */
-#define IR_FCS(fcs, byte) (((fcs)>>8)^irda_crc16_table[((fcs)^(byte)) & 0xff])
+#define IR_FCS(fcs, c) (((fcs) >> 8) ^ irda_crc16_table[((fcs) ^ (c)) & 0xff])
X
X /* Recompute the FCS with len bytes appended. */
X unsigned short crc_calc( __u16 fcs, __u8 const *buf, size_t len);
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irda.h linux/include/net/irda/irda.h
--- v2.2.0-pre8/linux/include/net/irda/irda.h Tue Dec 22 14:16:58 1998
+++ linux/include/net/irda/irda.h Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Tue Dec 9 21:13:12 1997
- * Modified at: Mon Nov 2 14:49:11 1998
+ * Modified at: Sat Jan 16 01:23:15 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X *

X * Copyright (c) 1998 Dag Brattli, All Rights Reserved.

@@ -39,21 +39,22 @@
X #define PACK __attribute__((packed))


X
X /* use 0 for production, 1 for verification, >2 for debug */

-#ifndef NET_DEBUG
-#define NET_DEBUG 3
-static unsigned int net_debug = NET_DEBUG;
+#ifdef CONFIG_IRDA_DEBUG
X
-#define DEBUG(n, args...) if (net_debug >= (n)) printk( KERN_DEBUG args)
+extern __u32 irda_debug;
+
+#define IRDA_DEBUG 3
+
+#define DEBUG(n, args...) if (irda_debug >= (n)) printk( KERN_DEBUG args)
X #define ASSERT(expr, func) \
X if(!(expr)) { \
X printk( "Assertion failed! %s,%s,%s,line=%d\n",\
X #expr,__FILE__,__FUNCTION__,__LINE__); \
X ##func}
X #else
-#error
X #define DEBUG(n, args...)
X #define ASSERT(expr, func)
-#endif /* NET_DEBUG */
+#endif /* CONFIG_IRDA_DEBUG */
X
X #ifdef CHECK_SKB
X static unsigned int check_skb = CHECK_SKB;
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irda_device.h linux/include/net/irda/irda_device.h
--- v2.2.0-pre8/linux/include/net/irda/irda_device.h Tue Dec 22 14:16:58 1998
+++ linux/include/net/irda/irda_device.h Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.

X * Author: Haris Zukanovic <ha...@stud.cs.uit.no>
X * Created at: Tue Apr 14 12:41:42 1998
- * Modified at: Thu Dec 10 21:18:25 1998
+ * Modified at: Mon Jan 18 10:52:10 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X *
X * Copyright (c) 1998 Haris Zukanovic, <ha...@stud.cs.uit.no>
@@ -85,8 +85,9 @@
X struct irda_device {
X QUEUE q; /* Must be first */
X
- int magic; /* our magic bullet */
- char name[16];
+ int magic; /* Our magic bullet */
+ char name[16]; /* Name of device "irda0" */
+ char description[32]; /* Something like "irda0 <-> ttyS0" */
X
X struct irlap_cb *irlap; /* The link layer we are connected to */
X struct device netdev; /* Yes! we are some kind of netdevice */
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irlap_event.h linux/include/net/irda/irlap_event.h
--- v2.2.0-pre8/linux/include/net/irda/irlap_event.h Tue Dec 22 14:16:58 1998
+++ linux/include/net/irda/irlap_event.h Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sat Aug 16 00:59:29 1997
- * Modified at: Mon Dec 14 13:58:27 1998
+ * Modified at: Thu Dec 17 11:58:10 1998


X * Modified by: Dag Brattli <da...@cs.uit.no>

X *
X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -45,6 +45,7 @@
X LAP_NRM_S, /* Normal response mode as secondary */
X LAP_XMIT_S,
X LAP_SCLOSE,
+ LAP_RESET_CHECK,
X } IRLAP_STATE;
X
X /* IrLAP Events */
@@ -56,6 +57,7 @@
X DISCONNECT_REQUEST,
X DATA_REQUEST,
X RESET_REQUEST,
+ RESET_RESPONSE,
X
X /* Send events */
X SEND_I_CMD,
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irlpt_cli.h linux/include/net/irda/irlpt_cli.h
--- v2.2.0-pre8/linux/include/net/irda/irlpt_cli.h Wed Dec 31 16:00:00 1969
+++ linux/include/net/irda/irlpt_cli.h Wed Jan 20 11:05:33 1999
@@ -0,0 +1,47 @@
+/*********************************************************************
+ *
+ * Filename: irlpt_client.h


+ * Version: 0.1
+ * Description:

+ * Status: Experimental.
+ * Author: Dag Brattli <da...@cs.uit.no>

+ * Created at: Sat Feb 21 18:54:38 1998
+ * Modified at: Mon Jan 11 15:58:16 1999


+ * Modified by: Dag Brattli <da...@cs.uit.no>

+ *
+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>
+ * Copyright (c) 1998, Dag Brattli,
+ * All Rights Reserved
+ *

+ * 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.
+ *

+ * I, Thomas Davis, provide no warranty for any of this software. This
+ * material is provided "AS-IS" and at no charge.
+ *
+ ********************************************************************/
+
+#ifndef IRLPT_CLIENT_H
+#define IRLPT_CLIENT_H
+
+/* Debug function */
+
+/* int client_init( struct device *dev); */
+
+/*
+ * if it's static, it doesn't go in here.
+ */
+
+void irlpt_client_get_value_confirm(__u16 obj_id,
+ struct ias_value *value, void *priv);
+void irlpt_client_connect_indication( void *instance, void *sap,
+ struct qos_info *qos,
+ int max_seg_size,
+ struct sk_buff *skb);
+void irlpt_client_connect_request( struct irlpt_cb *self);
+
+extern hashbin_t *irlpt_clients;
+
+#endif
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irlpt_cli_fsm.h linux/include/net/irda/irlpt_cli_fsm.h
--- v2.2.0-pre8/linux/include/net/irda/irlpt_cli_fsm.h Wed Dec 31 16:00:00 1969
+++ linux/include/net/irda/irlpt_cli_fsm.h Wed Jan 20 11:05:33 1999
@@ -0,0 +1,34 @@
+/*********************************************************************
+ *
+ * Filename: irlpt_client_fsm.h
+ * Version: 0.1
+ * Sources: irlan_event.h
+ *
+ * Copyright (c) 1997 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>, All Rights Reserved.
+ *

+ * 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.
+ *

+ * I, Thomas Davis, provide no warranty for any of this software. This material is

+ * provided "AS-IS" and at no charge.
+ *

+ ********************************************************************/
+
+#ifndef IRLPT_EVENT_H
+#define IRLPT_EVENT_H
+
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+
+extern void irlpt_client_do_event( struct irlpt_cb *self,
+ IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
+extern void irlpt_client_next_state( struct irlpt_cb *self,
+ IRLPT_CLIENT_STATE state);
+
+#endif
+
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irlpt_common.h linux/include/net/irda/irlpt_common.h
--- v2.2.0-pre8/linux/include/net/irda/irlpt_common.h Wed Dec 31 16:00:00 1969
+++ linux/include/net/irda/irlpt_common.h Wed Jan 20 11:05:33 1999
@@ -0,0 +1,184 @@
+/*********************************************************************
+ *
+ * Filename: irlpt.c
+ * Version:
+ * Description:
+ * Status: Experimental.
+ * Author: Thomas Davis, <rat...@radiks.net>
+ * Created at: Sat Feb 21 18:54:38 1998
+ * Modified at: Sun Mar 8 23:44:19 1998


+ * Modified by: Dag Brattli <da...@cs.uit.no>

+ * Sources: irlan.c
+ *
+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>,
+ * Dag Brattli, <da...@cs.uit.no>
+ * All Rights Reserved.
+ *


+ * 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.
+ *

+ * I, Thomas Davis, provide no warranty for any of this software.
+ * This material is provided "AS-IS" and at no charge.
+ *
+ ********************************************************************/
+
+#ifndef IRLPT_COMMON_H
+#define IRLPT_COMMON_H
+
+#include <net/irda/qos.h>
+#include <net/irda/irmod.h>


+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>

+#include <linux/miscdevice.h>
+
+#include <linux/poll.h>
+
+extern char *irlpt_service_type[];
+extern char *irlpt_port_type[];
+extern char *irlpt_connected[];
+extern char *irlpt_reasons[];
+extern char *irlpt_client_fsm_state[];
+extern char *irlpt_server_fsm_state[];
+extern char *irlpt_fsm_event[];
+
+extern struct wait_queue *lpt_wait;
+
+extern struct irlpt_cb *irlpt_find_handle(unsigned int minor);
+extern void irlpt_flow_control(struct sk_buff *skb);
+
+extern ssize_t irlpt_read( struct file *file, char *buffer,
+ size_t count, loff_t *noidea);
+extern ssize_t irlpt_write(struct file *file, const char *buffer,
+ size_t count, loff_t *noidea);
+extern loff_t irlpt_seek(struct file *, loff_t, int);
+extern int irlpt_open(struct inode * inode, struct file *file);
+extern int irlpt_close(struct inode *inode, struct file *file);
+extern u_int irlpt_poll(struct file *file, poll_table *wait);
+
+/* FSM definitions */
+
+typedef enum {
+ IRLPT_CLIENT_IDLE,
+ IRLPT_CLIENT_QUERY,
+ IRLPT_CLIENT_READY,
+ IRLPT_CLIENT_WAITI,
+ IRLPT_CLIENT_WAITR,
+ IRLPT_CLIENT_CONN,
+} IRLPT_CLIENT_STATE;
+
+typedef enum {
+ IRLPT_SERVER_IDLE,
+ IRLPT_SERVER_CONN,
+} IRLPT_SERVER_STATE;
+
+/* IrLPT Events */
+
+typedef enum {
+ QUERY_REMOTE_IAS,
+ IAS_PROVIDER_AVAIL,
+ IAS_PROVIDER_NOT_AVAIL,
+ LAP_DISCONNECT,
+ LMP_CONNECT,
+ LMP_DISCONNECT,
+ LMP_CONNECT_INDICATION,
+ LMP_DISCONNECT_INDICATION,
+#if 0
+ TTP_CONNECT_INDICATION,
+ TTP_DISCONNECT_INDICATION,
+#endif
+ IRLPT_DISCOVERY_INDICATION,
+ IRLPT_CONNECT_REQUEST,
+ IRLPT_DISCONNECT_REQUEST,
+ CLIENT_DATA_INDICATION,
+} IRLPT_EVENT;
+
+struct irlpt_info {
+ struct lsap_cb *lsap;
+ __u8 dlsap_sel;
+ __u32 daddr;
+};
+
+/* Command packet types */
+
+#define IRLPT_MAX_PACKET 1024
+#define IRLPT_MAX_HEADER LMP_MAX_HEADER
+#define IRLPT_MAX_DEVICES 3
+#define IRLPT_MAGIC 0x0755
+
+typedef enum {
+ IRLPT_DISCONNECTED,
+ IRLPT_WAITING,
+ IRLPT_CONNECTED,
+ IRLPT_FLUSHED,
+} IRLPT_SERVER_STATUS;
+
+#define IRLPT_LSAP 0x09
+
+#define PI_SERVICE_TYPE 0x00
+
+#define IRLPT_UNKNOWN 0x00 /* not defined yet. */
+#define IRLPT_THREE_WIRE_RAW 0x01 /* bit 0 */
+#define IRLPT_THREE_WIRE 0x02 /* bit 1 */
+#define IRLPT_NINE_WIRE 0x04 /* bit 2 */
+#define IRLPT_CENTRONICS 0x08 /* bit 3 */
+#define IRLPT_SERVER_MODE 0xFF /* our own flag */
+
+#define PI_PORT_TYPE 0x01
+
+#define IRLPT_SERIAL 0x01 /* bit 0 */
+#define IRLPT_PARALLEL 0x02 /* bit 1 */
+
+#define PI_PORT_NAME 0x02
+
+#define PI_CRITICAL 0x80
+
+struct irlpt_cb {
+ QUEUE queue; /* must be first. */
+
+ int magic; /* magic used to detect corruption of
+ the struct */
+ __u32 daddr; /* my local address. */
+
+ struct timer_list retry_timer;
+
+ int volatile state; /* Current state of IrCOMM layer */
+ int open_retries;
+ int in_use; /* flag to prevent re-use */
+ char ifname[16]; /* name of the allocated instance,
+ and registered device. */
+ struct lsap_cb *lsap; /* lmp handle */
+
+ __u8 dlsap_sel; /* remote LSAP selector address */
+ __u8 slsap_sel; /* local LSAP selectoraddress */
+ __u8 servicetype; /* Type of remote service, ie THREE_WIRE_RAW */
+ __u8 porttype; /* type of remote port. */
+
+ struct miscdevice ir_dev; /* used to register the misc device. */
+
+ int count; /* open count */
+ int irlap_data_size; /* max frame size we can send */
+ int pkt_count; /* how many packets are queued up */
+
+ struct wait_queue *read_wait; /* wait queues */
+ struct wait_queue *write_wait;
+ struct wait_queue *ex_wait;
+
+ /* this is used by the server side of the system */
+
+ IRLPT_SERVER_STATE connected;
+
+ int eof;
+ int service_LSAP;
+
+ struct sk_buff_head rx_queue; /* read buffer queue */
+};
+
+/* Debug function */
+void irlpt_dump_buffer(struct sk_buff *);
+
+#endif
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irlpt_server.h linux/include/net/irda/irlpt_server.h
--- v2.2.0-pre8/linux/include/net/irda/irlpt_server.h Wed Dec 31 16:00:00 1969
+++ linux/include/net/irda/irlpt_server.h Wed Jan 20 11:05:33 1999
@@ -0,0 +1,42 @@
+/*********************************************************************
+ *
+ * Filename: server.h


+ * Version: 0.1
+ * Description:

+ * Status: Experimental.
+ * Author: Dag Brattli <da...@cs.uit.no>

+ * Created at: Sat Feb 21 18:54:38 1998
+ * Modified at: Tue Sep 22 11:41:42 1998
+ * Modified by: Dag Brattli <da...@cs.uit.no>
+ *
+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>
+ * Copyright (c) 1998, Dag Brattli,
+ * All Rights Reserved
+ *

+ * 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.
+ *

+ * I, Thomas Davis, provide no warranty for any of this software. This
+ * material is provided "AS-IS" and at no charge.
+ *
+ ********************************************************************/
+
+#ifndef IRLPT_SERVER_H
+#define IRLPT_SERVER_H
+
+#include "qos.h"
+#include "irmod.h"


+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>

+#include <linux/miscdevice.h>
+
+/* int server_init( struct device *dev); */
+
+extern struct irlpt_cb *irlpt_server;
+
+#endif
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irlpt_server_fsm.h linux/include/net/irda/irlpt_server_fsm.h
--- v2.2.0-pre8/linux/include/net/irda/irlpt_server_fsm.h Wed Dec 31 16:00:00 1969
+++ linux/include/net/irda/irlpt_server_fsm.h Wed Jan 20 11:05:33 1999
@@ -0,0 +1,30 @@
+/*********************************************************************
+ *
+ * Filename: server_fsm.h<2>
+ * Version: 0.1
+ * Sources: irlan_event.h
+ *
+ * Copyright (c) 1997 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>, All Rights Reserved.
+ *

+ * 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.
+ *

+ * I, Thomas Davis, provide no warranty for any of this software. This material is

+ * provided "AS-IS" and at no charge.
+ *

+ ********************************************************************/
+
+#ifndef IRLPT_EVENT_H
+#define IRLPT_EVENT_H
+
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+
+void irlpt_server_do_event( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb, struct irlpt_info *info);
+void irlpt_server_next_state( struct irlpt_cb *self, IRLPT_SERVER_STATE state);
+
+#endif
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irmod.h linux/include/net/irda/irmod.h
--- v2.2.0-pre8/linux/include/net/irda/irmod.h Tue Dec 22 14:16:58 1998
+++ linux/include/net/irda/irmod.h Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Mon Dec 15 13:58:52 1997
- * Modified at: Mon Dec 7 01:40:35 1998
+ * Modified at: Tue Jan 12 14:56:11 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X *


X * Copyright (c) 1998 Dag Brattli, All Rights Reserved.

@@ -89,9 +89,11 @@
X /*
X * Main structure for the IrDA device (not much here :-)
X */
-struct irda {
+struct irda_cb {
X struct miscdevice dev;
X struct wait_queue *wait_queue;
+
+ int in_use;
X
X QUEUE *event_queue; /* Events queued for the irmanager */
X QUEUE *todo_queue; /* Todo list */
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irobex.h linux/include/net/irda/irobex.h
--- v2.2.0-pre8/linux/include/net/irda/irobex.h Tue Dec 22 14:16:58 1998
+++ linux/include/net/irda/irobex.h Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sat Jul 4 22:43:57 1998
- * Modified at: Mon Oct 19 12:32:33 1998
+ * Modified at: Wed Jan 13 15:55:28 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X *

X * Copyright (c) 1998 Dag Brattli, All Rights Reserved.

@@ -50,21 +50,29 @@
X #define IROBEX_IOCSDISCONNECT _IOW(IROBEX_IOC_MAGIC, 2, 4)
X #define IROBEX_IOC_MAXNR 2
X
-
X #define IROBEX_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_HEADER)
X
+typedef enum {
+ OBEX_IDLE, /* Doing nothing */
+ OBEX_DISCOVER, /* Trying to discovery remote device */
+ OBEX_QUERY, /* Querying remote LM-IAS */
+ OBEX_CONN, /* Trying to connect to remote device */
+ OBEX_DATA, /* Data transfer ready */
+} OBEX_STATE;
+
X struct irobex_cb {
X QUEUE queue; /* Must be first! */
X
X int magic; /* magic used to detect corruption of the struct */
X
+ OBEX_STATE state; /* Current state */
+
X __u32 saddr; /* my local address */
X __u32 daddr; /* peer address */
X unsigned long time_discovered;
X
X char devname[9]; /* name of the registered device */
X struct tsap_cb *tsap;
- int connected;
X int eof;
X
X __u8 dtsap_sel; /* remote TSAP address */
@@ -81,11 +89,6 @@
X struct wait_queue *read_wait;
X struct wait_queue *write_wait;
X
- /* These wait queues are used for setting up a connections */
- struct wait_queue *connect_wait;
- struct wait_queue *discover_wait;
- struct wait_queue *ias_wait;
-
X struct fasync_struct *async;
X
X struct timer_list watchdog_timer;
@@ -121,13 +124,11 @@
X
X void irobex_watchdog_timer_expired( unsigned long data);
X
-inline void irobex_start_watchdog_timer( struct irobex_cb *self,
- int timeout)
+inline void irobex_start_watchdog_timer( struct irobex_cb *self, int timeout)
X {
X irda_start_timer( &self->watchdog_timer, timeout, (unsigned long) self,
X irobex_watchdog_timer_expired);
X }
-
X
X extern struct irobex_cb *irobex;
X
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/irport.h linux/include/net/irda/irport.h
--- v2.2.0-pre8/linux/include/net/irda/irport.h Tue Dec 22 14:16:58 1998
+++ linux/include/net/irda/irport.h Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun Aug 3 13:49:59 1997

- * Modified at: Wed Nov 4 15:10:41 1998
+ * Modified at: Thu Jan 7 14:17:31 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X *
X * Copyright (c) 1997, 1998 Dag Brattli <da...@cs.uit.no>
@@ -30,7 +30,7 @@
X #include <linux/skbuff.h>
X #include <linux/types.h>
X
-#include <irda_device.h>
+#include <net/irda/irda_device.h>
X
X #define SPEED_DEFAULT 9600
X #define SPEED_MAX 115200
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/irda/uircc.h linux/include/net/irda/uircc.h
--- v2.2.0-pre8/linux/include/net/irda/uircc.h Wed Dec 31 16:00:00 1969
+++ linux/include/net/irda/uircc.h Wed Jan 20 11:05:33 1999
@@ -0,0 +1,121 @@
+/*********************************************************************
+ *
+ * Filename: uircc.h


+ * Version: 0.1
+ * Description: Driver for the Sharp Universal Infrared
+ * Communications Controller (UIRCC)
+ * Status: Experimental.
+ * Author: Dag Brattli <da...@cs.uit.no>

+ * Created at: Sat Dec 26 11:00:49 1998
+ * Modified at: Tue Jan 19 23:52:46 1999


+ * Modified by: Dag Brattli <da...@cs.uit.no>

+ *
+ * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ *

+ * 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.
+ *
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
+ * provide warranty for any of this software. This material is
+ * provided "AS-IS" and at no charge.
+ *

+ ********************************************************************/
+
+#ifndef UIRCC_H
+#define UIRCC_H
+
+/* Control registers (write only) */
+#define UIRCC_CR0 0x00 /* Control register 0 */
+#define UIRCC_CR0_XMIT_RST 0x20 /* Transmit reset */
+#define UIRCC_CR0_RECV_RST 0x10 /* Receive reset */
+#define UIRCC_CR0_TMR_RST 0x08 /* Timer reset */
+#define UIRCC_CR0_SYS_RST 0x04 /* System reset */
+#define UIRCC_CR0_CARR_RST 0x02 /* Carrier latch reset */
+#define UIRCC_CR0_CNT_SWT 0x01 /* Transmit/receive length counter reset */
+
+#define UIRCC_CR1 0x01 /* Transmit/receive mode setting register */
+#define UIRCC_CR1_RX_DMA 0x80 /* Rx DMA mode */
+#define UIRCC_CR1_TX_DMA 0x20 /* Tx DMA mode */
+#define UIRCC_CR1_DMA_BRST 0x10 /* DMA burst mode */
+#define UIRCC_CR1_MUST_SET 0x0c /* Must be set */
+
+#define UIRCC_CR2 0x02 /* Interrupt mask register */
+#define UIRCC_CR2_RECV_OVR 0x40 /* Receive overrun error */
+#define UIRCC_CR2_RECV_FRM 0x20 /* Receive frame error */
+#define UIRCC_CR2_RECV_END 0x10 /* Receive end */
+#define UIRCC_CR2_TMR_OUT 0x08 /* Timer time-out */
+#define UIRCC_CR2_XMIT_UNR 0x04 /* Transmit under-run error */
+#define UIRCC_CR2_XMIT_END 0x01 /* Transmit end */
+#define UIRCC_CR2_RECV_MASK 0x70
+#define UIRCC_CR2_XMIT_MASK 0x05
+
+#define UIRCC_CR3 0x03 /* Transmit/receive control */
+#define UIRCC_CR3_XMIT_EN 0x80 /* Transmit enable */
+#define UIRCC_CR3_TX_CRC_EN 0x40 /* Transmit UIRCC_CRC enable */
+#define UIRCC_CR3_RECV_EN 0x20 /* Receive enable */
+#define UIRCC_CR3_RX_CRC_EN 0x10 /* Receive CRC enable */
+#define UIRCC_CR3_ADDR_CMP 0x08 /* Address comparison enable */
+#define UIRCC_CR3_MCAST_EN 0x04 /* Multicast enable */
+
+#define UIRCC_CR4 0x04 /* Transmit data length low byte */
+#define UIRCC_CR5 0x05 /* Transmit data length high byte */
+#define UIRCC_CR6 0x06 /* Transmit data writing low byte */
+#define UIRCC_CR7 0x07 /* Transmit data writing high byte */
+
+#define UIRCC_CR8 0x08 /* Self pole address */
+
+#define UIRCC_CR9 0x09 /* System control 1 */
+
+#define UIRCC_CR10 0x0a /* Modem selection */
+#define UIRCC_CR10_SIR 0x22 /* Set SIR mode */
+#define UIRCC_CR10_FIR 0x88 /* Set FIR mode */
+
+#define UIRCC_CR11 0x0b /* System control 2 (same as SR11) */
+#define UIRCC_CR11_TMR_EN 0x08
+
+#define UIRCC_CR12 0x0c /* Timer counter initial value (low byte) */
+#define UIRCC_CR13 0x0d /* Timer counter initial value (high byte) */
+
+/* Status registers (read only) */
+#define UIRCC_SR0 0x00 /* Transmit/receive status register */
+#define UIRCC_SR0_RX_RDY 0x80 /* Received data ready */
+#define UIRCC_SR0_RX_OVR 0x40 /* Receive overrun error */
+#define UIRCC_SR0_RX_CRCFRM 0x20 /* Receive CRC or framing error */
+
+#define UIRCC_SR2 0x02 /* Interrupt mask status */
+
+#define UIRCC_SR3 0x03 /* Interrupt factor register */
+#define UIRCC_SR3_RX_OVR_ER 0x40 /* Receive overrun error */
+#define UIRCC_SR3_RX_FRM_ER 0x20 /* Receive frameing error */
+#define UIRCC_SR3_RX_EOF 0x10 /* Receive end of frame */
+#define UIRCC_SR3_TMR_OUT 0x08 /* Timer timeout */
+#define UIRCC_SR3_TXUR 0x04 /* Transmit underrun */
+#define UIRCC_SR3_TX_DONE 0x01 /* Transmit all sent */
+
+#define UIRCC_SR4 0x04 /* TX/RX data length counter low byte */
+#define UIRCC_SR5 0x05 /* TX/RX data length counter high byte */
+
+#define UIRCC_SR8 0x08 /* Chip version */
+
+#define UIRCC_SR9 0x09 /* System status 1 */
+
+#define UIRCC_SR10 0x0a /* Modem select status */
+
+#define UIRCC_SR12 0x0c /* Timer counter status (low byte) */
+#define UIRCC_SR13 0x0d /* Timer counter status (high byte) */
+
+/* Private data for each instance */
+struct uircc_cb {
+ struct irda_device idev;
+
+ __u8 cr3; /* Copy of register sr3 */
+};
+
+#define CR3_SET
+
+#endif
+
+
+
diff -u --recursive --new-file v2.2.0-pre8/linux/include/net/sock.h linux/include/net/sock.h
--- v2.2.0-pre8/linux/include/net/sock.h Mon Dec 28 15:00:53 1998
+++ linux/include/net/sock.h Wed Jan 20 16:23:35 1999
@@ -278,6 +278,7 @@
X char saw_tstamp; /* Saw TIMESTAMP on last packet */
X __u8 snd_wscale; /* Window scaling received from sender */
X __u8 rcv_wscale; /* Window scaling to send to receiver */
+ __u8 rexmt_done; /* Retransmitted up to send head? */
X __u32 rcv_tsval; /* Time stamp value */
X __u32 rcv_tsecr; /* Time stamp echo reply */
X __u32 ts_recent; /* Time stamp to echo next */
@@ -910,7 +911,7 @@
X * Enable debug/info messages
X */
X
-#if 0
+#if 1
X #define NETDEBUG(x) do { } while (0)
X #else
X #define NETDEBUG(x) do { x; } while (0)
diff -u --recursive --new-file v2.2.0-pre8/linux/include/video/font.h linux/include/video/font.h
--- v2.2.0-pre8/linux/include/video/font.h Mon Oct 5 13:13:47 1998
+++ linux/include/video/font.h Tue Jan 19 10:47:48 1999
@@ -11,19 +11,6 @@
X #ifndef _VIDEO_FONT_H
X #define _VIDEO_FONT_H
X
-#ifdef __ASSEMBLY__
-
-#ifdef __mc68000__
-#define FBCON_FONT_DESC_idx 0
-#define FBCON_FONT_DESC_name (FBCON_FONT_DESC_idx +4)
-#define FBCON_FONT_DESC_width (FBCON_FONT_DESC_name +4)
-#define FBCON_FONT_DESC_height (FBCON_FONT_DESC_width +4)
-#define FBCON_FONT_DESC_data (FBCON_FONT_DESC_height+4)
-#define FBCON_FONT_DESC_pref (FBCON_FONT_DESC_data +4)
-#endif
-


-#else /* __ASSEMBLY__ */
-

X #include <linux/types.h>
X
X struct fbcon_font_desc {
@@ -60,7 +47,5 @@
X
X /* Max. length for the name of a predefined font */
X #define MAX_FONT_NAME 32
-
-#endif /* __ASSEMBLY__ */
X
X #endif /* _VIDEO_FONT_H */
diff -u --recursive --new-file v2.2.0-pre8/linux/init/main.c linux/init/main.c
--- v2.2.0-pre8/linux/init/main.c Mon Dec 28 15:00:53 1998
+++ linux/init/main.c Wed Jan 20 10:18:53 1999
@@ -541,7 +541,7 @@
X #ifdef __SMP__
X { "nosmp", smp_setup },
X { "maxcpus=", smp_setup },
-#ifdef __i386__
+#ifdef CONFIG_X86_IO_APIC
X { "noapic", ioapic_setup },
X { "pirq=", ioapic_pirq_setup },
X #endif
diff -u --recursive --new-file v2.2.0-pre8/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.2.0-pre8/linux/kernel/ksyms.c Tue Jan 19 11:32:53 1999
+++ linux/kernel/ksyms.c Tue Jan 19 10:37:44 1999
@@ -36,6 +36,7 @@
X #include <linux/ctype.h>
X #include <linux/file.h>
X #include <linux/console.h>
+#include <linux/poll.h>
X
X #if defined(CONFIG_PROC_FS)
X #include <linux/proc_fs.h>
@@ -178,6 +179,7 @@
X EXPORT_SYMBOL(vfs_rmdir);
X EXPORT_SYMBOL(vfs_unlink);
X EXPORT_SYMBOL(vfs_rename);
+EXPORT_SYMBOL(__pollwait);
X
X #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
X EXPORT_SYMBOL(do_nfsservctl);
diff -u --recursive --new-file v2.2.0-pre8/linux/kernel/sched.c linux/kernel/sched.c
--- v2.2.0-pre8/linux/kernel/sched.c Tue Jan 19 11:32:53 1999
+++ linux/kernel/sched.c Tue Jan 19 10:19:58 1999
@@ -7,6 +7,8 @@
X * 1996-12-23 Modified by Dave Grothe to fix bugs in semaphores and
X * make semaphores SMP safe
X * 1997-01-28 Modified by Finn Arne Gangstad to make timers scale better.


+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills

X * 1998-11-19 Implemented schedule_timeout() and related stuff
X * by Andrea Arcangeli
X * 1998-12-24 Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
@@ -65,8 +67,8 @@
X long time_constant = 2; /* pll time constant */
X long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */
X long time_precision = 1; /* clock precision (us) */
-long time_maxerror = MAXPHASE; /* maximum error (us) */
-long time_esterror = MAXPHASE; /* estimated error (us) */
+long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */
+long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */
X long time_phase = 0; /* phase offset (scaled us) */
X long time_freq = ((1000000 + HZ/2) % HZ - HZ/2) << SHIFT_USEC; /* frequency offset (scaled ppm) */
X long time_adj = 0; /* tick adjust (scaled 1 / HZ) */
@@ -1116,8 +1118,11 @@
X
X /* Bump the maxerror field */
X time_maxerror += time_tolerance >> SHIFT_USEC;
- if ( time_maxerror > MAXPHASE )
- time_maxerror = MAXPHASE;
+ if ( time_maxerror > NTP_PHASE_LIMIT ) {
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_state = TIME_ERROR; /* p. 17, sect. 4.3, (b) */


+ time_status |= STA_UNSYNC;
+ }

X
X /*
X * Leap second processing. If in leap-insert state at
@@ -1141,7 +1146,7 @@
X if (xtime.tv_sec % 86400 == 0) {
X xtime.tv_sec--;
X time_state = TIME_OOP;
- printk("Clock: inserting leap second 23:59:60 UTC\n");
+ printk(KERN_NOTICE "Clock: inserting leap second 23:59:60 UTC\n");
X }
X break;
X
@@ -1149,7 +1154,7 @@
X if ((xtime.tv_sec + 1) % 86400 == 0) {
X xtime.tv_sec++;
X time_state = TIME_WAIT;
- printk("Clock: deleting leap second 23:59:59 UTC\n");
+ printk(KERN_NOTICE "Clock: deleting leap second 23:59:59 UTC\n");
X }
X break;
X
@@ -1197,7 +1202,7 @@
X * the pll and the PPS signal.
X */
X pps_valid++;
- if (pps_valid == PPS_VALID) {
+ if (pps_valid == PPS_VALID) { /* PPS signal lost */
X pps_jitter = MAXTIME;
X pps_stabil = MAXFREQ;
X time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
@@ -1212,17 +1217,38 @@
X (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
X
X #if HZ == 100
- /* compensate for (HZ==100) != 128. Add 25% to get 125; => only 3% error */
+ /* Compensate for (HZ==100) != (1 << SHIFT_HZ).
+ * Add 25% and 3.125% to get 128.125; => only 0.125% error (p. 14)
+ */
X if (time_adj < 0)
- time_adj -= -time_adj >> 2;
+ time_adj -= (-time_adj >> 2) + (-time_adj >> 5);
X else
- time_adj += time_adj >> 2;
+ time_adj += (time_adj >> 2) + (time_adj >> 5);
X #endif
X }
X
X /* in the NTP reference this is called "hardclock()" */
X static void update_wall_time_one_tick(void)
X {
+ if ( (time_adjust_step = time_adjust) != 0 ) {
+ /* We are doing an adjtime thing.
+ *
+ * Prepare time_adjust_step to be within bounds.
+ * Note that a positive time_adjust means we want the clock
+ * to run faster.
+ *
+ * Limit the amount of the step to be in the range
+ * -tickadj .. +tickadj
+ */
+ if (time_adjust > tickadj)
+ time_adjust_step = tickadj;
+ else if (time_adjust < -tickadj)
+ time_adjust_step = -tickadj;
+
+ /* Reduce by this step the amount of time left */
+ time_adjust -= time_adjust_step;
+ }
+ xtime.tv_usec += tick + time_adjust_step;
X /*
X * Advance the phase, once it gets to one microsecond, then
X * advance the tick more.
@@ -1231,37 +1257,13 @@
X if (time_phase <= -FINEUSEC) {
X long ltemp = -time_phase >> SHIFT_SCALE;
X time_phase += ltemp << SHIFT_SCALE;
- xtime.tv_usec += tick + time_adjust_step - ltemp;
+ xtime.tv_usec -= ltemp;
X }
X else if (time_phase >= FINEUSEC) {
X long ltemp = time_phase >> SHIFT_SCALE;
X time_phase -= ltemp << SHIFT_SCALE;
- xtime.tv_usec += tick + time_adjust_step + ltemp;
- } else
- xtime.tv_usec += tick + time_adjust_step;
-
- if (time_adjust) {
- /* We are doing an adjtime thing.
- *
- * Modify the value of the tick for next time.
- * Note that a positive delta means we want the clock
- * to run fast. This means that the tick should be bigger
- *
- * Limit the amount of the step for *next* tick to be
- * in the range -tickadj .. +tickadj
- */
- if (time_adjust > tickadj)
- time_adjust_step = tickadj;
- else if (time_adjust < -tickadj)
- time_adjust_step = -tickadj;
- else
- time_adjust_step = time_adjust;
-
- /* Reduce by this step the amount of time left */
- time_adjust -= time_adjust_step;
+ xtime.tv_usec += ltemp;
X }
- else
- time_adjust_step = 0;
X }
X
X /*
diff -u --recursive --new-file v2.2.0-pre8/linux/kernel/time.c linux/kernel/time.c
--- v2.2.0-pre8/linux/kernel/time.c Fri Nov 27 13:09:30 1998
+++ linux/kernel/time.c Tue Jan 19 10:20:00 1999
@@ -16,6 +16,12 @@
X * adjtime interface update and CMOS clock write code
X * 1995-08-13 Torsten Duwe
X * kernel PLL updated to 1994-12-13 specs (rfc-1589)
+ * 1999-01-16 Ulrich Windl
+ * Introduced error checking for many cases in adjtimex().
+ * Updated NTP code according to technical memorandum Jan '96


+ * "A Kernel Model for Precision Timekeeping" by Dave Mills

+ * Allow time_constant larger than MAXTC(6) for NTP v4 (MAXTC == 10)
+ * (Even though the technical memorandum forbids it)
X */
X
X #include <linux/mm.h>
@@ -88,9 +94,11 @@
X cli();
X xtime.tv_sec = value;
X xtime.tv_usec = 0;
- time_state = TIME_ERROR;


- time_maxerror = MAXPHASE;
- time_esterror = MAXPHASE;
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR; /* p. 24, (a) */
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
X sti();

X return 0;
X }
@@ -213,6 +221,7 @@
X int do_adjtimex(struct timex *txc)
X {
X long ltemp, mtemp, save_adjust;
+ int error = 0;
X
X /* In order to modify anything, you gotta be super-user! */
X if (txc->modes && !capable(CAP_SYS_TIME))
@@ -235,109 +244,153 @@
X /* Save for later - semantics of adjtime is to return old value */
X save_adjust = time_adjust;
X
+#if 0 /* STA_CLOCKERR is never set yet */
+ time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */
+#endif
X /* If there are input parameters, then process them */
X if (txc->modes)
X {
- if (time_state == TIME_BAD)
- time_state = TIME_OK;
-
- if (txc->modes & ADJ_STATUS)
- time_status = txc->status;
+ if (time_state == TIME_ERROR)
+ time_state = TIME_OK; /* reset error -- why? */
X
- if (txc->modes & ADJ_FREQUENCY)
- time_freq = txc->freq;
+ if (txc->modes & ADJ_STATUS) /* only set allowed bits */
+ time_status = (txc->status & ~STA_RONLY) |
+ (time_status & STA_RONLY);
+
+ if (txc->modes & ADJ_FREQUENCY) { /* p. 22 */
+ if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) {
+ error = -EINVAL;
+ goto leave;
+ }
+ time_freq = txc->freq - pps_freq;
+ }
X
- if (txc->modes & ADJ_MAXERROR)
+ if (txc->modes & ADJ_MAXERROR) {
+ if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) {
+ error = -EINVAL;
+ goto leave;
+ }
X time_maxerror = txc->maxerror;
+ }
X
- if (txc->modes & ADJ_ESTERROR)
+ if (txc->modes & ADJ_ESTERROR) {
+ if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) {
+ error = -EINVAL;
+ goto leave;
+ }
X time_esterror = txc->esterror;
+ }
X
- if (txc->modes & ADJ_TIMECONST)
+ if (txc->modes & ADJ_TIMECONST) { /* p. 24 */
+ if (txc->constant < 0) { /* NTP v4 uses values > 6 */
+ error = -EINVAL;
+ goto leave;
+ }
X time_constant = txc->constant;
+ }
X
- if (txc->modes & ADJ_OFFSET) {
- if ((txc->modes == ADJ_OFFSET_SINGLESHOT)
- || !(time_status & STA_PLL))
- {
- time_adjust = txc->offset;
+ if (txc->modes & ADJ_OFFSET) { /* values checked earlier */
+ if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
+ /* adjtime() is independent from ntp_adjtime() */
+ time_adjust = txc->offset;
X }
- else if ((time_status & STA_PLL)||(time_status & STA_PPSTIME))
- {
- ltemp = (time_status & STA_PPSTIME &&
- time_status & STA_PPSSIGNAL) ?
- pps_offset : txc->offset;
-
- /*
- * Scale the phase adjustment and
- * clamp to the operating range.
- */
- if (ltemp > MAXPHASE)
- time_offset = MAXPHASE << SHIFT_UPDATE;
- else if (ltemp < -MAXPHASE)
- time_offset = -(MAXPHASE << SHIFT_UPDATE);
- else
- time_offset = ltemp << SHIFT_UPDATE;
-
- /*
- * Select whether the frequency is to be controlled and in which
- * mode (PLL or FLL). Clamp to the operating range. Ugly
- * multiply/divide should be replaced someday.
- */
-
- if (time_status & STA_FREQHOLD || time_reftime == 0)
+ else if ( time_status & (STA_PLL | STA_PPSTIME) ) {
+ ltemp = (time_status & (STA_PPSTIME | STA_PPSSIGNAL)) ==
+ (STA_PPSTIME | STA_PPSSIGNAL) ?
+ pps_offset : txc->offset;
+
+ /*
+ * Scale the phase adjustment and
+ * clamp to the operating range.
+ */
+ if (ltemp > MAXPHASE)
+ time_offset = MAXPHASE << SHIFT_UPDATE;
+ else if (ltemp < -MAXPHASE)
+ time_offset = -(MAXPHASE << SHIFT_UPDATE);
+ else
+ time_offset = ltemp << SHIFT_UPDATE;
+
+ /*
+ * Select whether the frequency is to be controlled
+ * and in which mode (PLL or FLL). Clamp to the operating
+ * range. Ugly multiply/divide should be replaced someday.
+ */
+
+ if (time_status & STA_FREQHOLD || time_reftime == 0)
+ time_reftime = xtime.tv_sec;
+ mtemp = xtime.tv_sec - time_reftime;
X time_reftime = xtime.tv_sec;
- mtemp = xtime.tv_sec - time_reftime;
- time_reftime = xtime.tv_sec;
- if (time_status & STA_FLL)
- {
- if (mtemp >= MINSEC)
- {
- ltemp = ((time_offset / mtemp) << (SHIFT_USEC -
- SHIFT_UPDATE));
- if (ltemp < 0)
- time_freq -= -ltemp >> SHIFT_KH;
- else
- time_freq += ltemp >> SHIFT_KH;
- }
- }
- else
- {
- if (mtemp < MAXSEC)
- {
- ltemp *= mtemp;
- if (ltemp < 0)
- time_freq -= -ltemp >> (time_constant +
- time_constant + SHIFT_KF -
- SHIFT_USEC);
- else
- time_freq += ltemp >> (time_constant +
- time_constant + SHIFT_KF -
- SHIFT_USEC);
- }
+ if (time_status & STA_FLL) {
+ if (mtemp >= MINSEC) {
+ ltemp = (time_offset / mtemp) << (SHIFT_USEC -
+ SHIFT_UPDATE);
+ if (ltemp < 0)
+ time_freq -= -ltemp >> SHIFT_KH;
+ else
+ time_freq += ltemp >> SHIFT_KH;
+ } else /* calibration interval too short (p. 12) */
+ time_state = TIME_ERROR;
+ } else { /* PLL mode */
+ if (mtemp < MAXSEC) {
+ ltemp *= mtemp;
+ if (ltemp < 0)
+ time_freq -= -ltemp >> (time_constant +
+ time_constant +
+ SHIFT_KF - SHIFT_USEC);
+ else
+ time_freq += ltemp >> (time_constant +
+ time_constant +
+ SHIFT_KF - SHIFT_USEC);
+ } else /* calibration interval too long (p. 12) */
+ time_state = TIME_ERROR;
X }
- if (time_freq > time_tolerance)
- time_freq = time_tolerance;
- else if (time_freq < -time_tolerance)
- time_freq = -time_tolerance;
+ if (time_freq > time_tolerance)
+ time_freq = time_tolerance;
+ else if (time_freq < -time_tolerance)
+ time_freq = -time_tolerance;
X } /* STA_PLL || STA_PPSTIME */
+ } /* txc->modes & ADJ_OFFSET */
+ if (txc->modes & ADJ_TICK) {
+ /* if the quartz is off by more than 10% something is
+ VERY wrong ! */
+ if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ) {
+ error = -EINVAL;
+ goto leave;
+ }
+ tick = txc->tick;
X }
- if (txc->modes & ADJ_TICK)
- tick = txc->tick;
-
+ } /* txc->modes */
+leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
+ || ((time_status & (STA_PPSFREQ|STA_PPSTIME)) != 0
+ && (time_status & STA_PPSSIGNAL) == 0)
+ /* p. 24, (b) */
+ || ((time_status & (STA_PPSTIME|STA_PPSJITTER))
+ == (STA_PPSTIME|STA_PPSJITTER))
+ /* p. 24, (c) */
+ || ((time_status & STA_PPSFREQ) != 0
+ && (time_status & (STA_PPSWANDER|STA_PPSERROR)) != 0))
+ /* p. 24, (d) */
+ time_state = TIME_ERROR;
+
+ if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
+ txc->offset = save_adjust;
+ else {
+ if (time_offset < 0)
+ txc->offset = -(-time_offset >> SHIFT_UPDATE);
+ else
+ txc->offset = time_offset >> SHIFT_UPDATE;
X }
- txc->offset = save_adjust;
- txc->freq = time_freq;
+ txc->freq = time_freq + pps_freq;
X txc->maxerror = time_maxerror;
X txc->esterror = time_esterror;
X txc->status = time_status;
X txc->constant = time_constant;
X txc->precision = time_precision;
X txc->tolerance = time_tolerance;
- txc->time = xtime;
+ do_gettimeofday(&txc->time);
X txc->tick = tick;
X txc->ppsfreq = pps_freq;
- txc->jitter = pps_jitter;
+ txc->jitter = pps_jitter >> PPS_AVG;
X txc->shift = pps_shift;
X txc->stabil = pps_stabil;
X txc->jitcnt = pps_jitcnt;
@@ -346,7 +399,7 @@
X txc->stbcnt = pps_stbcnt;
X
X sti();
- return 0;
+ return(error < 0 ? error : time_state);
X }
X
X asmlinkage int sys_adjtimex(struct timex *txc_p)
@@ -360,8 +413,6 @@
X */
X if(copy_from_user(&txc, txc_p, sizeof(struct timex)))
X return -EFAULT;
- if ((ret = do_adjtimex(&txc)))
- return ret;
-
- return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : time_state;
+ ret = do_adjtimex(&txc);
+ return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/mm/filemap.c linux/mm/filemap.c
--- v2.2.0-pre8/linux/mm/filemap.c Tue Jan 19 11:32:53 1999
+++ linux/mm/filemap.c Wed Jan 20 13:37:41 1999
@@ -144,7 +144,7 @@
X if (PageSkip(page)) {
X /* next_hash is overloaded for PageSkip */
X page = page->next_hash;
- clock = page->map_nr;
+ clock = page - mem_map;
X }
X
X count--;
diff -u --recursive --new-file v2.2.0-pre8/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.2.0-pre8/linux/mm/page_alloc.c Wed Jan 13 15:00:44 1999
+++ linux/mm/page_alloc.c Wed Jan 20 13:40:00 1999
@@ -125,7 +125,7 @@
X if (PageSwapCache(page))
X panic ("Freeing swap cache page");
X page->flags &= ~(1 << PG_referenced);
- free_pages_ok(page->map_nr, 0);
+ free_pages_ok(page - mem_map, 0);
X return;
X }
X }
@@ -163,7 +163,7 @@
X if (!dma || CAN_DMA(ret)) { \
X unsigned long map_nr; \
X (prev->next = ret->next)->prev = prev; \
- map_nr = ret->map_nr; \
+ map_nr = ret - mem_map; \
X MARK_USED(map_nr, new_order, area); \
X nr_free_pages -= 1 << order; \
X EXPAND(ret, map_nr, order, new_order, area); \
@@ -189,6 +189,8 @@
X atomic_set(&map->count, 1); \
X } while (0)
X
+int low_on_memory = 0;
+
X unsigned long __get_free_pages(int gfp_mask, unsigned long order)
X {
X unsigned long flags;
@@ -212,19 +214,18 @@
X * further thought.
X */
X if (!(current->flags & PF_MEMALLOC)) {
- static int trashing = 0;
X int freed;
X
X if (nr_free_pages > freepages.min) {
- if (!trashing)
+ if (!low_on_memory)
X goto ok_to_allocate;
- if (nr_free_pages > freepages.low) {
- trashing = 0;
+ if (nr_free_pages >= freepages.high) {
+ low_on_memory = 0;
X goto ok_to_allocate;
X }
X }
X
- trashing = 1;
+ low_on_memory = 1;
X current->flags |= PF_MEMALLOC;
X freed = try_to_free_pages(gfp_mask);
X current->flags &= ~PF_MEMALLOC;
@@ -322,7 +323,6 @@
X --p;
X atomic_set(&p->count, 0);
X p->flags = (1 << PG_DMA) | (1 << PG_reserved);
- p->map_nr = p - mem_map;
X } while (p > mem_map);
X
X for (i = 0 ; i < NR_MEM_LISTS ; i++) {
diff -u --recursive --new-file v2.2.0-pre8/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.2.0-pre8/linux/mm/swapfile.c Wed Jan 13 15:00:44 1999
+++ linux/mm/swapfile.c Tue Jan 19 10:01:37 1999
@@ -627,11 +627,11 @@
X p->highest_bit = swap_header->info.last_page - 1;
X p->max = swap_header->info.last_page;
X
- if (p->max >= 0x7fffffffL/PAGE_SIZE ||
- (void *) &swap_header->info.badpages[(int) swap_header->info.nr_badpages-1] >= (void *) swap_header->magic.magic) {
- error = -EINVAL;
+ error = -EINVAL;
+ if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
+ goto bad_swap;
+ if (p->max >= SWP_OFFSET(SWP_ENTRY(0,~0UL)))
X goto bad_swap;
- }
X
X /* OK, set up the swap map and apply the bad block list */
X if (!(p->swap_map = vmalloc (p->max * sizeof(short)))) {
diff -u --recursive --new-file v2.2.0-pre8/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.2.0-pre8/linux/mm/vmscan.c Tue Jan 19 11:32:53 1999
+++ linux/mm/vmscan.c Wed Jan 20 16:27:39 1999
@@ -407,12 +407,7 @@
X current->session = 1;
X current->pgrp = 1;
X strcpy(current->comm, "kswapd");
-
- /*
- * Hey, if somebody wants to kill us, be our guest.
- * Don't come running to mama if things don't work.
- */
- siginitsetinv(&current->blocked, sigmask(SIGKILL));
+ sigfillset(&current->blocked);
X
X /*
X * Tell the memory management that we're a "memory allocator",
@@ -429,23 +424,29 @@
X current->flags |= PF_MEMALLOC;
X
X while (1) {
- if (signal_pending(current))
- break;
- current->state = TASK_INTERRUPTIBLE;
- run_task_queue(&tq_disk);
- schedule_timeout(HZ);
+ int tmo;
X
X /*
- * kswapd isn't even meant to keep up with anything,
- * so just a few pages per second is plenty: the only
- * point is to make sure that the system doesn't stay
- * forever in a really bad memory squeeze.
+ * Wake up once a second to see if we need to make
+ * more memory available. When we get into a low
+ * memory situation, we start waking up more often.
+ *
+ * We consider "freepages.low" to be low on memory,
+ * but we also try to be aggressive if other processes
+ * are low on memory and would otherwise block when
+ * calling __get_free_page().
X */
- if (nr_free_pages < freepages.high)
- try_to_free_pages(GFP_KSWAPD);
+ tmo = HZ;
+ if (nr_free_pages < freepages.high) {
+ if (nr_free_pages < freepages.low || low_on_memory) {
+ if (try_to_free_pages(GFP_KSWAPD))
+ tmo = (HZ+9)/10;
+ }
+ }
+ run_task_queue(&tq_disk);


+ current->state = TASK_INTERRUPTIBLE;

+ schedule_timeout(tmo);
X }
-
- return 0;
X }
X
X /*
@@ -475,11 +476,13 @@
X }
X
X /* Try to get rid of some shared memory pages.. */
- while (shm_swap(priority, gfp_mask)) {
- if (!--count)
- goto done;
+ if (gfp_mask & __GFP_IO) {
+ while (shm_swap(priority, gfp_mask)) {
+ if (!--count)
+ goto done;
+ }
X }
-
+
X /* Then, try to page stuff out.. */
X while (swap_out(priority, gfp_mask)) {
X if (!--count)
diff -u --recursive --new-file v2.2.0-pre8/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c
--- v2.2.0-pre8/linux/net/ipv4/ip_output.c Thu Jan 7 15:11:41 1999
+++ linux/net/ipv4/ip_output.c Wed Jan 20 11:03:22 1999
@@ -35,6 +35,9 @@
X * Andi Kleen : Split fast and slow ip_build_xmit path
X * for decreased register pressure on x86
X * and more readibility.
+ * Marc Boucher : When call_out_firewall returns FW_QUEUE,
+ * silently abort send instead of failing
+ * with -EPERM.
X */
X
X #include <asm/uaccess.h>
@@ -128,8 +131,10 @@
X
X dev = rt->u.dst.dev;
X
+#ifdef CONFIG_FIREWALL
X if (call_out_firewall(PF_INET, dev, iph, NULL, &skb) < FW_ACCEPT)
X goto drop;
+#endif
X
X ip_send_check(iph);
X
@@ -137,8 +142,10 @@
X skb->dst->output(skb);
X return;
X
+#ifdef CONFIG_FIREWALL
X drop:
X kfree_skb(skb);
+#endif
X }
X
X int __ip_finish_output(struct sk_buff *skb)
@@ -284,8 +291,10 @@
X
X dev = rt->u.dst.dev;
X
+#ifdef CONFIG_FIREWALL
X if (call_out_firewall(PF_INET, dev, iph, NULL, &skb) < FW_ACCEPT)
X goto drop;
+#endif
X
X /* This can happen when the transport layer has segments queued
X * with a cached route, and by the time we get here things are
@@ -546,9 +555,19 @@
X * Account for the fragment.
X */
X
- if(!err &&
- call_out_firewall(PF_INET, rt->u.dst.dev, skb->nh.iph, NULL, &skb) < FW_ACCEPT)
- err = -EPERM;
+#ifdef CONFIG_FIREWALL
+ if(!err) {
+ int fw_res;
+
+ fw_res = call_out_firewall(PF_INET, rt->u.dst.dev, skb->nh.iph, NULL, &skb);
+ if(fw_res == FW_QUEUE) {
+ kfree_skb(skb);
+ skb = NULL;
+ } else if(fw_res < FW_ACCEPT) {
+ err = -EPERM;
+ }
+ }
+#endif
X
X if (err) {
X ip_statistics.IpOutDiscards++;
@@ -564,7 +583,7 @@
X nfrags++;
X
X err = 0;
- if (rt->u.dst.output(skb)) {
+ if (skb && rt->u.dst.output(skb)) {
X err = -ENETDOWN;
X ip_statistics.IpOutDiscards++;
X break;
@@ -663,8 +682,20 @@
X if (err)
X err = -EFAULT;
X
- if(!err && call_out_firewall(PF_INET, rt->u.dst.dev, iph, NULL, &skb) < FW_ACCEPT)
- err = -EPERM;
+#ifdef CONFIG_FIREWALL
+ if(!err) {
+ int fw_res;
+
+ fw_res = call_out_firewall(PF_INET, rt->u.dst.dev, iph, NULL, &skb);
+ if(fw_res == FW_QUEUE) {
+ /* re-queued elsewhere; silently abort this send */
+ kfree_skb(skb);
+ return 0;
+ }
+ if(fw_res < FW_ACCEPT)
+ err = -EPERM;
+ }
+#endif
X
X if (err) {
X kfree_skb(skb);
diff -u --recursive --new-file v2.2.0-pre8/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.2.0-pre8/linux/net/ipv4/tcp_input.c Tue Jan 19 11:32:53 1999
+++ linux/net/ipv4/tcp_input.c Wed Jan 20 10:11:21 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_input.c,v 1.150 1999/01/16 08:31:08 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.153 1999/01/20 07:20:03 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -100,8 +100,10 @@
X tp->lrcvtime = jiffies;
X
X /* Help sender leave slow start quickly,
- * this sets our initial ato value.
+ * and also makes sure we do not take this
+ * branch ever again for this connection.
X */
+ tp->ato = 1;
X tcp_enter_quickack_mode(tp);
X } else {
X int m = jiffies - tp->lrcvtime;
@@ -314,7 +316,8 @@
X if(!after(start_seq, TCP_SKB_CB(skb)->seq) &&
X !before(end_seq, TCP_SKB_CB(skb)->end_seq)) {
X /* If this was a retransmitted frame, account for it. */
- if(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)
+ if((TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) &&
+ tp->retrans_out)
X tp->retrans_out--;
X TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED;
X
diff -u --recursive --new-file v2.2.0-pre8/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- v2.2.0-pre8/linux/net/ipv4/tcp_output.c Tue Jan 19 11:32:53 1999
+++ linux/net/ipv4/tcp_output.c Wed Jan 20 10:11:21 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_output.c,v 1.100 1999/01/16 08:31:06 davem Exp $
+ * Version: $Id: tcp_output.c,v 1.101 1999/01/20 07:20:14 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -544,8 +544,10 @@
X
X tp->retrans_head = tp->retrans_head->next;
X if((tp->retrans_head == tp->send_head) ||
- (tp->retrans_head == (struct sk_buff *) &sk->write_queue))
+ (tp->retrans_head == (struct sk_buff *) &sk->write_queue)) {
X tp->retrans_head = NULL;
+ tp->rexmt_done = 1;
+ }
X }
X
X /* This retransmits one SKB. Policy decisions and retransmit queue
@@ -610,7 +612,8 @@
X struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
X struct sk_buff *skb;
X
- if (tp->retrans_head == NULL)
+ if (tp->retrans_head == NULL &&
+ tp->rexmt_done == 0)
X tp->retrans_head = skb_peek(&sk->write_queue);
X if (tp->retrans_head == tp->send_head)
X tp->retrans_head = NULL;
diff -u --recursive --new-file v2.2.0-pre8/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.2.0-pre8/linux/net/ipv4/tcp_timer.c Thu Dec 31 10:29:03 1998
+++ linux/net/ipv4/tcp_timer.c Wed Jan 20 10:11:21 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_timer.c,v 1.56 1998/11/30 15:18:12 davem Exp $
+ * Version: $Id: tcp_timer.c,v 1.57 1999/01/20 07:20:21 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -468,6 +468,7 @@
X
X /* Retransmission. */
X tp->retrans_head = NULL;
+ tp->rexmt_done = 0;
X tp->fackets_out = 0;
X tp->retrans_out = 0;
X if (tp->retransmits == 0) {
diff -u --recursive --new-file v2.2.0-pre8/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- v2.2.0-pre8/linux/net/ipv6/af_inet6.c Tue Jan 19 11:32:53 1999
+++ linux/net/ipv6/af_inet6.c Wed Jan 20 10:11:21 1999
@@ -7,7 +7,7 @@
X *
X * Adapted from linux/net/ipv4/af_inet.c
X *
- * $Id: af_inet6.c,v 1.41 1999/01/02 16:51:50 davem Exp $
+ * $Id: af_inet6.c,v 1.42 1999/01/19 08:20:06 davem Exp $
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/Config.in linux/net/irda/Config.in
--- v2.2.0-pre8/linux/net/irda/Config.in Tue Dec 22 14:16:59 1998
+++ linux/net/irda/Config.in Wed Jan 20 11:05:33 1999
@@ -14,6 +14,7 @@
X source net/irda/irlan/Config.in
X source net/irda/irobex/Config.in
X source net/irda/ircomm/Config.in
+ source net/irda/irlpt/Config.in
X
X bool 'IrDA protocol options' CONFIG_IRDA_OPTIONS
X if [ "$CONFIG_IRDA_OPTIONS" != "n" ] ; then
@@ -21,6 +22,7 @@
X bool ' Cache last LSAP' CONFIG_IRDA_CACHE_LAST_LSAP
X bool ' Fast RRs' CONFIG_IRDA_FAST_RR
X bool ' Recycle RRs' CONFIG_IRDA_RECYCLE_RR
+ bool ' Debug information' CONFIG_IRDA_DEBUG
X fi
X fi
X
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/Makefile linux/net/irda/Makefile


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 10'
echo 'File patch-2.2.0-pre9 is continued in part 11'
echo 11 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part11

#!/bin/sh
# this is part 11 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 11; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

--- v2.2.0-pre8/linux/net/irda/Makefile Tue Dec 22 14:16:59 1998
+++ linux/net/irda/Makefile Wed Jan 20 11:05:33 1999
@@ -7,7 +7,7 @@
X #
X # Note 2! The CFLAGS definition is now in the main makefile...
X
-ALL_SUB_DIRS := irlan ircomm compressors
+ALL_SUB_DIRS := irlan ircomm irlpt compressors
X SUB_DIRS :=
X MOD_SUB_DIRS :=
X
@@ -36,6 +36,15 @@
X else
X ifeq ($(CONFIG_IRLAN),m)
X MOD_SUB_DIRS += irlan
+ endif
+endif
+
+ifeq ($(CONFIG_IRLPT),y)
+SUB_DIRS += irlpt
+O_OBJS += irlpt/irlpt.o
+else
+ ifeq ($(CONFIG_IRLPT),m)
+ MOD_IN_SUB_DIRS += irlpt
X endif
X endif
X
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/af_irda.c linux/net/irda/af_irda.c
--- v2.2.0-pre8/linux/net/irda/af_irda.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/af_irda.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun May 31 10:12:43 1998
- * Modified at: Mon Dec 14 10:39:45 1998
+ * Modified at: Thu Jan 14 13:42:16 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X * Sources: af_netroom.c, af_ax25.x
X *
@@ -703,7 +703,7 @@
X */
X void irda_proto_init(struct net_proto *pro)
X {
- DEBUG( 0, __FUNCTION__ "\n");
+ DEBUG( 4, __FUNCTION__ "\n");
X
X /* sock_register( irda_proto_ops.family, &irda_proto_ops); */
X irda_packet_type.type = htons(ETH_P_IRDA);
@@ -723,7 +723,7 @@
X */
X void irda_proto_cleanup(void)
X {
- DEBUG( 0, __FUNCTION__ "\n");
+ DEBUG( 4, __FUNCTION__ "\n");
X
X irda_packet_type.type = htons(ETH_P_IRDA);
X dev_remove_pack(&irda_packet_type);
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irda_device.c linux/net/irda/irda_device.c
--- v2.2.0-pre8/linux/net/irda/irda_device.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irda_device.c Wed Jan 20 11:05:33 1999


@@ -1,12 +1,12 @@
X /*********************************************************************
X *

X * Filename: irda_device.c
- * Version:
- * Description:
+ * Version: 0.3
+ * Description: Abstract device driver layer and helper functions


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Wed Sep 2 20:22:08 1998
- * Modified at: Mon Dec 14 19:18:51 1998
+ * Modified at: Mon Jan 18 11:05:59 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998 Dag Brattli, All Rights Reserved.

@@ -122,8 +122,6 @@
X int result;
X int i=0;
X
- DEBUG( 4, __FUNCTION__ "()\n");
-
X /* Check that a minimum of allocation flags are specified */
X ASSERT(( self->rx_buff.flags & (GFP_KERNEL|GFP_ATOMIC)) != 0,
X return -1;);
@@ -160,7 +158,6 @@
X
X /* A pointer to the low level implementation */
X self->priv = priv;
- strncpy( self->name, name, 16);
X
X /* Initialize IrDA net device */
X do {
@@ -172,16 +169,25 @@
X self->netdev.next = NULL;
X
X if (( result = register_netdev( &self->netdev)) != 0) {
- DEBUG( 0, "IrDA Device, register_netdev() failed!\n");
+ DEBUG( 0, __FUNCTION__ "(), register_netdev() failed!\n");
X return -1;
X }
X
+ /*
+ * Make the description for the device. self->netdev.name will get
+ * a name like "irda0" and the self->descriptin will get a name
+ * like "irda0 <-> irtty0"
+ */
+ strncpy( self->description, self->name, 4);
+ strcat( self->description, " <-> ");
+ strncat( self->description, name, 23);
+
X hashbin_insert( irda_device, (QUEUE *) self, (int) self, NULL);
X
X /* Open network device */
X dev_open( &self->netdev);
X
- printk( "IrDA irda_device %s registered.\n", self->name);
+ printk( "IrDA device %s registered.\n", self->name);
X
X irda_device_set_media_busy( self, FALSE);
X
@@ -536,7 +542,7 @@
X *
X */
X int irda_device_proc_read( char *buf, char **start, off_t offset, int len,
- int unused)
+ int unused)
X {
X struct irda_device *self;
X unsigned long flags;
@@ -548,7 +554,11 @@
X
X self = (struct irda_device *) hashbin_get_first( irda_device);
X while ( self != NULL) {
- len += sprintf( buf+len, "Irda_Device name: %s\n", self->name);
+ len += sprintf( buf+len, "device name: %s\n", self->name);
+ len += sprintf( buf+len, "description: %s\n",
+ self->description);
+ len += sprintf( buf+len, " tbusy=%s\n", self->netdev.tbusy ?
+ "TRUE" : "FALSE");
X len += sprintf( buf+len, " bps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\n");
X
X len += sprintf( buf+len, " %d\t",
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/iriap.c linux/net/irda/iriap.c
--- v2.2.0-pre8/linux/net/irda/iriap.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/iriap.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Thu Aug 21 00:02:07 1997
- * Modified at: Wed Dec 9 02:19:23 1998
+ * Modified at: Tue Dec 15 16:00:35 1998


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,

@@ -24,10 +24,12 @@
X ********************************************************************/
X
X #include <linux/config.h>
-#include <asm/byteorder.h>
X #include <linux/types.h>
X #include <linux/skbuff.h>
X #include <linux/string.h>
+#include <linux/init.h>
+
+#include <asm/byteorder.h>
X
X #include <net/irda/irda.h>
X #include <net/irda/irttp.h>
@@ -50,7 +52,7 @@
X * Initializes the IrIAP layer, called by the module initialization code
X * in irmod.c
X */
-int iriap_init(void)
+__initfunc(int iriap_init(void))
X {
X struct ias_object *obj;
X
@@ -102,15 +104,11 @@
X */
X void iriap_cleanup(void)
X {
- DEBUG( 4, "--> iriap_cleanup\n");
-
X irlmp_unregister_layer( S_COMPUTER, SERVER | CLIENT);
X irlmp_unregister_layer( S_PNP, SERVER);
X
X hashbin_delete( iriap, (FREE_FUNC) __iriap_close);
- hashbin_delete( objects, (FREE_FUNC) __irias_delete_object);
-
- DEBUG( 4, "iriap_cleanup -->\n");
+ hashbin_delete( objects, (FREE_FUNC) __irias_delete_object);
X }
X
X /*
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irias_object.c linux/net/irda/irias_object.c
--- v2.2.0-pre8/linux/net/irda/irias_object.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irias_object.c Wed Jan 20 11:05:33 1999


@@ -1,12 +1,12 @@
X /*********************************************************************
X *

X * Filename: irias_object.c
- * Version: 0.1
+ * Version: 0.3
X * Description: IAS object database and functions


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Thu Oct 1 22:50:04 1998
- * Modified at: Sat Dec 5 13:54:39 1998
+ * Modified at: Tue Dec 15 09:19:43 1998


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlan/irlan_cli.c linux/net/irda/irlan/irlan_cli.c
--- v2.2.0-pre8/linux/net/irda/irlan/irlan_cli.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irlan/irlan_cli.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun Aug 31 20:14:37 1997
- * Modified at: Mon Dec 14 10:44:07 1998
+ * Modified at: Mon Jan 18 13:24:26 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X * Sources: skeleton.c by Donald Becker <bec...@CESDIS.gsfc.nasa.gov>
X * slip.c by Laurence Culhane, <l...@holmes.demon.co.uk>
@@ -143,11 +143,9 @@
X */
X void irlan_client_cleanup(void)
X {
- DEBUG( 0, "--> irlan_client_cleanup\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X irlmp_unregister_layer( S_LAN, CLIENT);
-
- DEBUG( 4, "irlan_client_cleanup -->\n");
X }
X
X /*
@@ -244,7 +242,7 @@
X if ( self != NULL) {
X ASSERT( self->magic == IRLAN_MAGIC, return;);
X
- DEBUG( 0, "Found instance!\n");
+ DEBUG( 4, __FUNCTION__ "(), Found instance!\n");
X if ( self->state == IRLAN_IDLE) {
X /* daddr may have changed! */
X self->daddr = daddr;
@@ -311,10 +309,10 @@
X DEBUG( 4, __FUNCTION__ "(), reason=%d\n", reason);
X
X if ( tsap == self->tsap_data) {
- DEBUG( 0, "IrLAN, data channel disconnected by peer!\n");
+ DEBUG( 4, "IrLAN, data channel disconnected by peer!\n");
X self->connected = FALSE;
X } else if ( tsap == self->tsap_ctrl) {
- DEBUG( 0, "IrLAN, control channel disconnected by peer!\n");
+ DEBUG( 4, "IrLAN, control channel disconnected by peer!\n");
X } else {
X DEBUG( 0, "Error, disconnect on unknown handle!\n");
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlan/irlan_common.c linux/net/irda/irlan/irlan_common.c
--- v2.2.0-pre8/linux/net/irda/irlan/irlan_common.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irlan/irlan_common.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun Aug 31 20:14:37 1997
- * Modified at: Mon Dec 14 10:43:05 1998
+ * Modified at: Tue Jan 19 23:11:30 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1997 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -23,7 +23,7 @@
X ********************************************************************/
X
X #include <linux/config.h>
-#include <linux/module.h>

+#include <linux/module.h>
X
X #include <linux/kernel.h>

X #include <linux/string.h>
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlap.c linux/net/irda/irlap.c
--- v2.2.0-pre8/linux/net/irda/irlap.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irlap.c Wed Jan 20 11:05:33 1999


@@ -1,12 +1,12 @@
X /*********************************************************************
X *

X * Filename: irlap.c
- * Version: 0.3
+ * Version: 0.8
X * Description: An IrDA LAP driver for Linux


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Mon Aug 4 20:40:53 1997

- * Modified at: Mon Dec 14 11:54:42 1998
+ * Modified at: Sat Jan 16 22:19:27 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,
@@ -208,7 +208,7 @@
X */
X void irlap_connect_indication( struct irlap_cb *self, struct sk_buff *skb)
X {
- DEBUG( 4, "irlap_connect_indication()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LAP_MAGIC, return;);
@@ -257,7 +257,7 @@
X if ( self->state == LAP_NDM) {
X irlap_do_event( self, CONNECT_REQUEST, NULL, NULL);
X } else {
- DEBUG( 0, "irlap_connect_request() Wrong state!\n");
+ DEBUG( 0, __FUNCTION__ "() Wrong state!\n");
X
X irlap_disconnect_indication( self, LAP_MEDIA_BUSY);
X }
@@ -295,8 +295,6 @@
X ASSERT( self->magic == LAP_MAGIC, return;);
X ASSERT( skb != NULL, return;);
X
- IS_SKB( skb, return;);
-
X /* Hide LAP header from IrLMP layer */
X skb_pull( skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
X
@@ -321,14 +319,12 @@
X */
X void irlap_unit_data_indication( struct irlap_cb *self, struct sk_buff *skb)
X {
- DEBUG( 4, __FUNCTION__ "()\n");

+ DEBUG( 0, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LAP_MAGIC, return;);
X ASSERT( skb != NULL, return;);
X
- IS_SKB( skb, return;);
-
X /* Hide LAP header from IrLMP layer */
X skb_pull( skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
X
@@ -342,9 +338,7 @@
X }
X }
X #endif
-
- irlmp_link_data_indication( self->notify.instance, LAP_UNRELIABLE,
- skb);
+ irlmp_link_data_indication(self->notify.instance, LAP_UNRELIABLE, skb);
X }
X
X /*
@@ -362,8 +356,6 @@
X ASSERT( self->magic == LAP_MAGIC, return;);
X ASSERT( skb != NULL, return;);
X
- IS_SKB( skb, return;);
-
X DEBUG( 4, "irlap_data_request: tx_list=%d\n",
X skb_queue_len( &self->tx_list));
X
@@ -392,8 +384,6 @@
X skb->data[1] = UI_FRAME;
X }
X
- IS_SKB( skb, return;);
-
X /*
X * Send event if this frame only if we are in the right state
X * FIXME: udata should be sent first! (skb_queue_head?)
@@ -408,7 +398,6 @@
X skb = skb_dequeue( &self->tx_list);
X
X ASSERT( skb != NULL, return;);
- IS_SKB( skb, return;);
X }
X irlap_do_event( self, SEND_I_CMD, skb, NULL);
X } else
@@ -479,8 +468,6 @@
X {
X struct irlap_info info;
X
- DEBUG( 4, __FUNCTION__ "()\n");
-
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LAP_MAGIC, return;);
X ASSERT( discovery != NULL, return;);


@@ -506,26 +493,22 @@
X }

X }
X
-
X /*

X * Function irlap_discovery_confirm (log)
X *
X * A device has been discovered in front of this station, we
X * report directly to LMP.
X */
-void irlap_discovery_confirm( struct irlap_cb *self,
- hashbin_t *discovery_log)
+void irlap_discovery_confirm( struct irlap_cb *self, hashbin_t *discovery_log)
X {
- DEBUG( 4, __FUNCTION__ "()\n");
-
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LAP_MAGIC, return;);
X
X ASSERT( self->notify.instance != NULL, return;);
-
+
X /* Inform IrLMP */
X irlmp_link_discovery_confirm( self->notify.instance, discovery_log);
-
+
X /*
X * IrLMP has now the responsibilities for the discovery_log
X */
@@ -538,8 +521,7 @@
X * Somebody is trying to discover us!
X *
X */
-inline void irlap_discovery_indication( struct irlap_cb *self,
- DISCOVERY *discovery)
+void irlap_discovery_indication( struct irlap_cb *self, DISCOVERY *discovery)
X {
X DEBUG( 4, __FUNCTION__ "()\n");
X
@@ -587,7 +569,10 @@
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LAP_MAGIC, return;);
X
- irlap_do_event( self, RESET_REQUEST, NULL, NULL);
+ if ( self->state == LAP_RESET_WAIT)
+ irlap_do_event( self, RESET_REQUEST, NULL, NULL);
+ else
+ irlap_do_event( self, RESET_RESPONSE, NULL, NULL);
X }
X
X /*
@@ -598,7 +583,7 @@
X */
X void irlap_reset_confirm(void)
X {
- DEBUG( 0, __FUNCTION__ "() Not implemented!\n");

+ DEBUG( 0, __FUNCTION__ "()\n");

X }
X
X /*
@@ -616,8 +601,6 @@
X
X slot = s + jiffies % (S-s);
X
- DEBUG( 4, "S=%d, s=%d, rnd=%d\n", S, s, slot);
-
X ASSERT(( slot >= s) || ( slot < S), return 0;);
X
X return slot;
@@ -687,9 +670,7 @@
X ASSERT( self != NULL, return -ENODEV;);
X ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
X
- /*
- * ns as expected?
- */
+ /* ns as expected? */
X if ( ns == self->vr) {
X DEBUG( 4, "*** irlap_validate_ns_received: expected!\n");
X return NS_EXPECTED;
@@ -713,9 +694,7 @@
X ASSERT( self != NULL, return -ENODEV;);
X ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
X
- /*
- * nr as expected?
- */
+ /* nr as expected? */
X if ( nr == self->vs) {
X DEBUG( 4, "*** irlap_validate_nr_received: expected!\n");
X return NR_EXPECTED;
@@ -726,24 +705,14 @@
X * ns numbers of the frames in the current window wrap.
X */
X if ( self->va < self->vs) {
- if (( nr >= self->va) && ( nr <= self->vs)) {
- DEBUG( 4, "*** irlap_validate_nr_received:"
- " unexpected nr, no wrap\n");
+ if (( nr >= self->va) && ( nr <= self->vs))
X return NR_UNEXPECTED;
- }
X } else {
- if (( nr >= self->va) || ( nr <= self->vs)) {
- DEBUG( 4, "*** irlap_validate_nr_received:"
- " unexpected nr, wrapped\n");
+ if (( nr >= self->va) || ( nr <= self->vs))
X return NR_UNEXPECTED;
- }
- }
-
+ }
+
X /* Invalid nr! */
- DEBUG( 4, "irlap_validate_nr_received: invalid nr!, "
- " vs=%d, vr=%d, va=%d, nr=%d\n",
- self->vs, self->vr, self->va, nr);
-
X return NR_INVALID;
X }
X
@@ -760,9 +729,7 @@
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LAP_MAGIC, return;);
X
- /*
- * Next to send and next to receive
- */
+ /* Next to send and next to receive */
X self->vs = self->vr = 0;
X
X /* Last frame which got acked (0 - 1) % 8 */
@@ -792,9 +759,7 @@
X ASSERT( self->magic == LAP_MAGIC, return;);
X ASSERT( qos != NULL, return;);
X
- /*
- * Get QoS values.
- */
+ /* Get QoS values. */
X speed = qos->baud_rate.value;
X usecs = qos->min_turn_time.value;
X
@@ -828,24 +793,23 @@
X {


X struct sk_buff* skb;
X

- DEBUG( 4, "irlap_flush_all_queues()\n");
-
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LAP_MAGIC, return;);
X
- /*
- * Free transmission queue
- */
- while (( skb = skb_dequeue( &self->tx_list)) != NULL) {
+ /* Free transmission queue */
+ while (( skb = skb_dequeue( &self->tx_list)) != NULL)
X dev_kfree_skb( skb);
- }
X
- /*
- * Free sliding window buffered packets
- */
- while (( skb = skb_dequeue( &self->wx_list)) != NULL) {
+ /* Free sliding window buffered packets */
+ while (( skb = skb_dequeue( &self->wx_list)) != NULL)
X dev_kfree_skb( skb);
- }
+
+#ifdef CONFIG_IRDA_RECYCLE_RR
+ if ( self->recycle_rr_skb) {
+ dev_kfree_skb( self->recycle_rr_skb);
+ self->recycle_rr_skb = NULL;
+ }
+#endif
X }
X
X /*
@@ -972,10 +936,14 @@
X
X /* Use 500ms in IrLAP for now */
X self->qos_rx.max_turn_time.bits &= 0x03;
+ self->qos_rx.max_turn_time.bits &= 0x01;
X
X /* Set data size */
X /* self->qos_rx.data_size.bits &= 0x03; */
X
+ /* Set disconnect time */
+ self->qos_rx.link_disc_time.bits &= 0x07;
+
X irda_qos_bits_to_value( &self->qos_rx);
X }
X
@@ -987,7 +955,7 @@
X */
X void irlap_apply_default_connection_parameters( struct irlap_cb *self)
X {
- DEBUG( 4, "irlap_apply_default_connection_parameters()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LAP_MAGIC, return;);
@@ -1062,13 +1030,6 @@
X self->poll_timeout = qos->max_turn_time.value / 10;
X self->final_timeout = qos->max_turn_time.value / 10;
X self->wd_timeout = self->poll_timeout * 2;
-
- DEBUG( 4, __FUNCTION__ "(), Setting poll timeout = %d\n",
- self->poll_timeout);
- DEBUG( 4, __FUNCTION__ "(), Setting final timeout = %d\n",
- self->final_timeout);
- DEBUG( 4, __FUNCTION__ "(), Setting wd timeout = %d\n",
- self->wd_timeout);
X
X #ifdef CONFIG_IRDA_COMPRESSION
X if ( qos->compression.value) {
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlap_event.c linux/net/irda/irlap_event.c
--- v2.2.0-pre8/linux/net/irda/irlap_event.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irlap_event.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Sat Aug 16 00:59:29 1997

- * Modified at: Mon Dec 14 14:16:00 1998
+ * Modified at: Tue Jan 19 22:58:45 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,
@@ -68,6 +68,8 @@
X struct sk_buff *skb, struct irlap_info *info);
X static int irlap_state_sclose ( struct irlap_cb *self, IRLAP_EVENT event,
X struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_reset_check( struct irlap_cb *, IRLAP_EVENT event,
+ struct sk_buff *, struct irlap_info *);
X
X static char *irlap_event[] = {
X "DISCOVERY_REQUEST",
@@ -76,6 +78,7 @@
X "DISCONNECT_REQUEST",
X "DATA_REQUEST",
X "RESET_REQUEST",
+ "RESET_RESPONSE",
X "SEND_I_CMD",
X "RECV_DISCOVERY_XID_CMD",
X "RECV_DISCOVERY_XID_RSP",
@@ -115,6 +118,7 @@
X "LAP_NRM_S",
X "LAP_XMIT_S",
X "LAP_SCLOSE",
+ "LAP_RESET_CHECK",
X };
X
X static int (*state[])( struct irlap_cb *self, IRLAP_EVENT event,
@@ -134,6 +138,7 @@
X irlap_state_nrm_s,
X irlap_state_xmit_s,
X irlap_state_sclose,
+ irlap_state_reset_check,
X };
X
X /*
@@ -146,8 +151,6 @@
X {
X struct irlap_cb *self = (struct irlap_cb *) data;
X
- DEBUG( 4, "Poll timer expired!\n");
-
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LAP_MAGIC, return;);
X
@@ -252,8 +255,7 @@
X *
X */
X void irlap_next_state( struct irlap_cb *self, IRLAP_STATE state)
-{
-
+{
X if ( !self || self->magic != LAP_MAGIC) {
X DEBUG( 4, "irlap_next_state: I have lost myself!\n");
X return;
@@ -285,7 +287,7 @@
X DISCOVERY *discovery_rsp;
X int ret = 0;
X
- DEBUG( 4, "irlap_state_ndm()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return -1;);
X ASSERT( self->magic == LAP_MAGIC, return -1;);
@@ -404,7 +406,7 @@
X ASSERT( info != NULL, return -1;);
X ASSERT( info->discovery != NULL, return -1;);
X
- DEBUG( 4, "irlap_state_query(), daddr=%08x\n",
+ DEBUG( 4, __FUNCTION__ "(), daddr=%08x\n",
X info->discovery->daddr);
X
X hashbin_insert( self->discovery_log,
@@ -443,7 +445,7 @@
X }
X break;
X default:
- DEBUG( 4, "irlap_state_query: Unknown event %d, %s\n", event,
+ DEBUG( 4, __FUNCTION__ "(), Unknown event %d, %s\n", event,
X irlap_event[event]);
X
X if ( skb != NULL) {
@@ -468,14 +470,14 @@
X DISCOVERY *discovery_rsp;
X int ret=0;
X
- DEBUG( 4, "irlap_state_reply()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return -1;);
X ASSERT( self->magic == LAP_MAGIC, return -1;);
X
X switch( event) {
X case QUERY_TIMER_EXPIRED:
- DEBUG( 0, "irlap_state_reply: QUERY_TIMER_EXPIRED <%ld>\n",
+ DEBUG( 0, __FUNCTION__ "(), QUERY_TIMER_EXPIRED <%ld>\n",
X jiffies);
X irlap_next_state( self, LAP_NDM);
X break;
@@ -532,7 +534,7 @@
X {
X int ret = 0;
X
- DEBUG( 0, __FUNCTION__ "(), event=%s\n", irlap_event[ event]);
+ DEBUG( 4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]);
X
X ASSERT( self != NULL, return -1;);
X ASSERT( self->magic == LAP_MAGIC, return -1;);
@@ -564,14 +566,14 @@
X break;
X
X case RECV_SNRM_CMD:
- DEBUG( 3, "irlap_state_conn: event RECV_SNRM_CMD!\n");
+ DEBUG( 3, __FUNCTION__ "(), event RECV_SNRM_CMD!\n");
X #if 0
X irlap_next_state( self, LAP_NDM);
X #endif
X break;
X
X case RECV_DISCOVERY_XID_CMD:
- DEBUG( 3, "irlap_state_conn: event RECV_DISCOVER_XID_CMD!\n");
+ DEBUG( 3, __FUNCTION__ "(), event RECV_DISCOVER_XID_CMD!\n");
X irlap_next_state( self, LAP_NDM);
X break;
X
@@ -581,7 +583,7 @@
X break;
X
X default:
- DEBUG( 0, "irlap_state_conn: Unknown event %d, %s\n", event,
+ DEBUG( 0, __FUNCTION__ "(), Unknown event %d, %s\n", event,
X irlap_event[event]);
X ret = -1;
X break;
@@ -631,7 +633,7 @@
X break;
X
X case RECV_SNRM_CMD:
- DEBUG( 0, "irlap_state_setup: SNRM battle!\n");
+ DEBUG( 4, __FUNCTION__ "(), SNRM battle!\n");
X
X ASSERT( skb != NULL, return 0;);
X ASSERT( info != NULL, return 0;);
@@ -672,7 +674,6 @@
X irlap_initiate_connection_state( self);
X
X /* Negotiate connection parameters */
- IS_SKB( skb, return -1;);
X ASSERT( skb->len > 10, return -1;);
X skb_pull( skb, 10);
X
@@ -741,7 +742,7 @@
X switch( event) {
X case SEND_I_CMD:
X ASSERT( skb != NULL, return -1;);
- DEBUG( 4, "irlap_state_xmit: Window=%d\n", self->window);
+ DEBUG( 4, __FUNCTION__ "(), Window=%d\n", self->window);
X
X /*
X * Only send frame if send-window > 0.
@@ -790,7 +791,7 @@
X self->fast_RR = FALSE;
X #endif
X } else {
- DEBUG( 0, __FUNCTION__
+ DEBUG( 4, __FUNCTION__
X "(), Unable to send! remote busy?\n");
X skb_queue_head( &self->tx_list, skb);
X
@@ -869,7 +870,7 @@
X }
X break;
X default:
- DEBUG( 0, "irlap_state_pclose: Unknown event %d\n", event);
+ DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event);
X ret = -1;
X break;
X }
@@ -897,7 +898,7 @@
X
X switch( event) {
X case RECV_RR_RSP:
- DEBUG( 4, "irlap_state_nrm_p: RECV_RR_FRAME: "
+ DEBUG( 4, __FUNCTION__ "(), RECV_RR_FRAME: "
X "Retrans:%d, nr=%d, va=%d, vs=%d, vr=%d\n",
X self->retry_count, info->nr, self->va, self->vs,
X self->vr);
@@ -1074,8 +1075,8 @@
X /* Keep state */
X irlap_next_state( self, LAP_NRM_P);
X } else {
- DEBUG( 4, "*** irlap_state_nrm_p:"
- " missing or duplicate frame!\n");
+ DEBUG( 4, __FUNCTION__
+ "(), missing or duplicate frame!\n");
X
X /* Update Nr received */
X irlap_update_nr_received( self, info->nr);
@@ -1321,7 +1322,7 @@
X irlap_next_state( self, LAP_PCLOSE);
X break;
X default:
- DEBUG( 0, "irlap_state_reset_wait: Unknown event %s\n",
+ DEBUG( 0, __FUNCTION__ "(), Unknown event %s\n",
X irlap_event[event]);
X ret = -1;
X break;
@@ -1402,7 +1403,7 @@
X break;
X
X default:
- DEBUG( 0, "irlap_state_reset: Unknown event %s\n",
+ DEBUG( 0, __FUNCTION__ "(), Unknown event %s\n",
X irlap_event[ event]);
X ret = -1;
X break;
@@ -1429,9 +1430,6 @@
X
X switch( event) {
X case SEND_I_CMD:
- ASSERT( skb != NULL, return -1;);
- DEBUG( 4, "irlap_state_xmit: Window=%d\n", self->window);
-
X /*
X * Send frame only if send window > 1
X */
@@ -1463,16 +1461,16 @@
X if (( self->window > 1) &&
X skb_queue_len( &self->tx_list) > 0)
X {
- DEBUG( 4, "irlap_state_xmit: window > 1\n");
+ DEBUG( 4, __FUNCTION__ "(), window > 1\n");
X irlap_send_data_secondary( self, skb);
X irlap_next_state( self, LAP_XMIT_S);
X } else {
- DEBUG( 4, "irlap_state_xmit: window <= 1\n");
+ DEBUG( 4, "(), window <= 1\n");
X irlap_send_data_secondary_final( self, skb);
X irlap_next_state( self, LAP_NRM_S);
X }
X } else {
- DEBUG( 0, "Unable to send!\n");
+ DEBUG( 0, __FUNCTION__ "(), Unable to send!\n");
X skb_queue_head( &self->tx_list, skb);
X ret = -EPROTO;
X }
@@ -1545,7 +1543,7 @@
X /* Keep state */
X irlap_next_state( self, LAP_NRM_S);
X } else {
- DEBUG( 0, "irlap_state_nrm_s: **** "


+ DEBUG( 0, __FUNCTION__ "(), "

X "invalid nr not implemented!\n");
X }
X if ( skb)
@@ -1732,23 +1730,17 @@
X }
X break;
X case RECV_SNRM_CMD:
-#if 1
X del_timer( &self->wd_timer);
X DEBUG( 0, "irlap_state_nrm_s: received SNRM cmd\n");
- irlap_next_state( self, LAP_RESET);
-#else
- irlap_wait_min_turn_around( &self->qos_session);
- irlap_send_ua_response_frame( &self->qos_session);
- irda_start_timer( WD_TIMER, self->wd_timeout);
- irlap_next_state( self, LAP_SCLOSE)
-
-#endif
+ irlap_next_state( self, LAP_RESET_CHECK);
+
+ irlap_reset_indication( self);
X break;
X case WD_TIMER_EXPIRED:
X DEBUG( 4, "WD_TIMER_EXPIRED: %ld\n", jiffies);
X
X /*
- * Wait until retry_count * n matches negotiated threshold/
+ * Wait until retry_count * n matches negotiated threshold/
X * disconnect time (note 2 in IrLAP p. 82)
X */
X DEBUG( 0, "retry_count = %d\n", self->retry_count);
@@ -1767,7 +1759,7 @@
X
X /* Always switch state before calling upper layers */
X irlap_next_state( self, LAP_NDM);
-
+
X irlap_disconnect_indication( self, LAP_NO_RESPONSE);
X }
X break;
@@ -1808,7 +1800,7 @@
X break;
X
X default:
- DEBUG( 0, "irlap_state_nrm_s: Unknown event %d, (%s)\n",
+ DEBUG( 0, __FUNCTION__ "(), Unknown event %d, (%s)\n",
X event, irlap_event[event]);
X ret = -1;
X break;
@@ -1829,3 +1821,42 @@
X
X return -1;
X }
+
+static int irlap_state_reset_check( struct irlap_cb *self, IRLAP_EVENT event,
+ struct sk_buff *skb,
+ struct irlap_info *info)
+{
+ int ret = 0;
+
+ DEBUG( 0, __FUNCTION__ "(), event=%s\n", irlap_event[ event]);
+
+ ASSERT( self != NULL, return -ENODEV;);
+ ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
+
+ switch( event) {
+ case RESET_RESPONSE:
+ irlap_send_ua_response_frame( self, &self->qos_rx);
+ irlap_initiate_connection_state( self);
+ irlap_start_wd_timer( self, WD_TIMEOUT);
+ irlap_flush_all_queues( self);
+
+ irlap_next_state( self, LAP_NRM_S);
+ break;
+ case DISCONNECT_REQUEST:
+ irlap_wait_min_turn_around( self, &self->qos_tx);
+ /* irlap_send_rd_frame(self); */
+ irlap_start_wd_timer( self, WD_TIMEOUT);
+ break;
+ default:
+ DEBUG( 0, __FUNCTION__ "(), Unknown event %d, (%s)\n",
+ event, irlap_event[event]);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+
+
+
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlap_frame.c linux/net/irda/irlap_frame.c
--- v2.2.0-pre8/linux/net/irda/irlap_frame.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irlap_frame.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Tue Aug 19 10:27:26 1997
- * Modified at: Mon Dec 14 14:24:05 1998
+ * Modified at: Tue Jan 19 22:58:13 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Resrved.
@@ -76,7 +76,7 @@
X }
X
X /*
- * Function irlap_send_connect_snrm_cmd (void)
+ * Function irlap_send_snrm_cmd (void)
X *
X * Transmits a connect SNRM command frame
X */
@@ -564,7 +564,6 @@
X if ( self->recycle_rr_skb) {
X DEBUG( 4, __FUNCTION__ "(), recycling skb!\n");
X skb = self->recycle_rr_skb;
- skb->stamp.tv_sec = 0;
X self->recycle_rr_skb = NULL;
X }
X #endif
@@ -640,7 +639,7 @@
X
X /*
X * Set skb to NULL, so that the state machine will not
- * deallocate it.
+ * try to deallocate it.
X */
X skb = NULL;
X }
@@ -652,11 +651,6 @@
X irlap_do_event( self, RECV_RR_RSP, skb, info);
X }
X
-/*
- * Function irlap_send_rr_frame ()
- *
- * Build and transmit RR (Receive Ready) frame
- */
X void irlap_send_frmr_frame( struct irlap_cb *self, int command)
X {
X struct sk_buff *skb = NULL;
@@ -805,8 +799,6 @@
X ASSERT( self->magic == LAP_MAGIC, return;);
X ASSERT( skb != NULL, return;);
X
- IS_SKB( skb, return;);
-
X /* Initialize variables */
X tx_skb = NULL;
X
@@ -888,8 +880,6 @@
X ASSERT( self->magic == LAP_MAGIC, return;);
X ASSERT( skb != NULL, return;);
X
- IS_SKB( skb,return;);
-
X /* Is this reliable or unreliable data? */
X if ( skb->data[1] == I_FRAME) {
X
@@ -950,8 +940,6 @@
X ASSERT( self->magic == LAP_MAGIC, return;);
X ASSERT( skb != NULL, return;);
X
- IS_SKB( skb, return;);
-
X /* Is this reliable or unreliable data? */
X if ( skb->data[1] == I_FRAME) {
X
@@ -1066,8 +1054,7 @@
X
X while ( skb_queue_len( &self->tx_list) > 0) {
X
- DEBUG( 0, "irlap_resend_rejected_frames: "
- "sending additional frames!\n");
+ DEBUG( 0, __FUNCTION__ "(), sending additional frames!\n");
X if (( skb_queue_len( &self->tx_list) > 0) &&
X ( self->window > 0)) {
X skb = skb_dequeue( &self->tx_list);
@@ -1141,8 +1128,7 @@
X
X /* Insert next to receive (Vr) */
X frame[1] |= (self->vr << 5); /* insert nr */
-
-#if 0
+#if 0
X {
X int vr, vs, pf;
X
@@ -1151,7 +1137,7 @@
X vs = (frame[1] >> 1) & 0x07;
X pf = (frame[1] >> 4) & 0x01;
X
- DEBUG( 4, __FUNCTION__ "(), vs=%d, vr=%d, p=%d, %ld\n",
+ DEBUG( 0, __FUNCTION__ "(), vs=%d, vr=%d, p=%d, %ld\n",
X vs, vr, pf, jiffies);
X }
X #endif
@@ -1351,7 +1337,7 @@
X self->stats.rx_packets++;
X break;
X case RNR:
- DEBUG( 3, "*** RNR frame received! pf = %d ***\n",
+ DEBUG( 4, "*** RNR frame received! pf = %d ***\n",
X info.pf >> 4);
X irlap_recv_rnr_frame( self, skb, &info);
X self->stats.rx_packets++;
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlmp.c linux/net/irda/irlmp.c
--- v2.2.0-pre8/linux/net/irda/irlmp.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irlmp.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun Aug 17 20:54:32 1997
- * Modified at: Mon Dec 14 11:54:08 1998
+ * Modified at: Sat Jan 16 22:13:20 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,
@@ -373,8 +373,8 @@
X if ( userdata == NULL) {
X skb = dev_alloc_skb( 64);
X if (skb == NULL) {
- DEBUG( 0, "irlmp_connect_request: "
- "Could not allocate an sk_buff of length %d\n",
+ DEBUG( 0, __FUNCTION__
+ "(), Could not allocate sk_buff of length %d\n",
X 64);
X return;
X }
@@ -596,7 +596,7 @@
X {
X struct lsap_cb *lsap;
X
- DEBUG( 4, "irlmp_disconnect_indication()\n");

+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
@@ -625,10 +625,9 @@
X
X /* FIXME: the reasons should be extracted somewhere else? */
X if ( userdata) {
- DEBUG( 4, "irlmp_disconnect_indication: reason=%02x\n",
- userdata->data[3]);
+ DEBUG( 4, __FUNCTION__ "(), reason=%02x\n", userdata->data[3]);


X }
-
+
X /*

X * Inform service user
X */
@@ -648,7 +647,7 @@
X {
X struct lap_cb *lap;
X
- DEBUG( 4, "irlmp_discovery_request()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( irlmp != NULL, return;);
X
@@ -702,7 +701,6 @@
X printk( KERN_INFO "IrDA Discovered: %s\n", discovery->info);
X printk( KERN_INFO " Services: ");
X
-
X service = irlmp_hint_to_service( discovery->hint);
X if (service != NULL) {
X /*
@@ -746,22 +744,12 @@
X {
X DISCOVERY *discovery;
X
- DEBUG( 4, "irlmp_discovery_confirm()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LAP_MAGIC, return;);
X
X /*
- * If log is missing this means that IrLAP was unable to perform the
- * discovery, so restart discovery again with just the half timeout
- * of the normal one.
- */
- if ( !log) {
- irlmp_start_discovery_timer( irlmp, 150);
- return;
- }
-
- /*
X * Now, check all discovered devices (if any)
X */
X discovery = ( DISCOVERY *) hashbin_get_first( log);
@@ -798,8 +786,10 @@
X /*
X * Create a new discovery log if neccessary
X */
- if ( self->cachelog == NULL)
- self->cachelog = hashbin_new( HB_LOCAL);
+ /* if ( self->cachelog == NULL) */
+/* self->cachelog = hashbin_new( HB_LOCAL); */
+ ASSERT( self->cachelog != NULL, return;);
+
X /*
X * Insert this discovery device into the discovery_log if its
X * not there already
@@ -932,7 +922,7 @@
X */
X void irlmp_connectionless_data_request( struct sk_buff *skb)
X {
- DEBUG( 0, __FUNCTION__ "()\n");
+ DEBUG( 0, __FUNCTION__ "(), Sorry not implemented\n");
X }
X
X /*
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlmp_event.c linux/net/irda/irlmp_event.c
--- v2.2.0-pre8/linux/net/irda/irlmp_event.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irlmp_event.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Mon Aug 4 20:40:53 1997

- * Modified at: Wed Dec 9 01:48:48 1998
+ * Modified at: Sat Jan 16 22:22:29 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,
@@ -119,7 +119,7 @@
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
X
- DEBUG( 4, "do_lsap_event: EVENT = %s, STATE = %s\n",
+ DEBUG( 4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n",
X irlmp_event[ event], irlmp_state[ self->lsap_state]);
X
X (*lsap_state[ self->lsap_state]) ( self, event, skb);
@@ -137,7 +137,7 @@
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LAP_MAGIC, return;);
X
- DEBUG( 4, "do_lap_event: EVENT = %s, STATE = %s\n",
+ DEBUG( 4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n",
X irlmp_event[event],
X irlmp_state[self->lap_state]);
X
@@ -152,9 +152,7 @@
X
X irlmp_discovery_request( 8);
X
- /*
- * Restart timer
- */
+ /* Restart timer */
X irlmp_start_discovery_timer( irlmp, 300);
X }
X
@@ -185,7 +183,7 @@
X static void irlmp_state_standby( struct lap_cb *self, IRLMP_EVENT event,
X struct sk_buff *skb)
X {
- DEBUG( 4, "irlmp_state_standby()\n");

+ DEBUG( 4, __FUNCTION__ "()\n");

X ASSERT( self->irlap != NULL, return;);
X
X switch( event) {
@@ -241,7 +239,7 @@
X struct lsap_cb *lsap;
X struct lsap_cb *lsap_current;
X
- DEBUG( 4, "irlmp_state_u_connect()\n");

+ DEBUG( 4, __FUNCTION__ "()\n");

X
X switch( event) {
X case LM_LAP_CONNECT_CONFIRM:
@@ -250,14 +248,12 @@
X
X lsap = ( struct lsap_cb *) hashbin_get_first( self->lsaps);
X while ( lsap != NULL) {
- irlmp_do_lsap_event( lsap,
- LM_LAP_CONNECT_CONFIRM,
- skb);
+ irlmp_do_lsap_event(lsap, LM_LAP_CONNECT_CONFIRM, skb);
X lsap = (struct lsap_cb*) hashbin_get_next(self->lsaps);
X }
X break;
X case LM_LAP_DISCONNECT_INDICATION:
- DEBUG( 0, __FUNCTION__ "(), IRLAP_DISCONNECT_INDICATION\n");
+ DEBUG( 4, __FUNCTION__ "(), IRLAP_DISCONNECT_INDICATION\n");
X
X irlmp_next_lap_state( self, LAP_STANDBY);
X
@@ -277,13 +273,15 @@
X }
X break;
X case LM_LAP_DISCONNECT_REQUEST:
- DEBUG( 0, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n");
- /* irlmp_next_lap_state( self, LAP_STANDBY); */
+ DEBUG( 4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n");
X
+ irlmp_next_lap_state( self, LAP_STANDBY);
+
+ /* FIXME */
X /* irlap_disconnect_request( self->irlap); */
X break;
X default:
- DEBUG( 4, "irlmp_state_u_connect: Unknown event\n");
+ DEBUG( 4, __FUNCTION__ "(), Unknown event\n");
X break;
X }
X }
@@ -300,11 +298,11 @@
X struct lsap_cb *lsap;
X struct lsap_cb *lsap_current;
X
- DEBUG( 4, "irlmp_state_active()\n");

+ DEBUG( 4, __FUNCTION__ "()\n");

X
X switch( event) {
X case LM_LAP_CONNECT_REQUEST:
- DEBUG( 4, "irlmp_state_active(), LS_CONNECT_REQUEST\n");
+ DEBUG( 4, __FUNCTION__ "(), LS_CONNECT_REQUEST\n");
X
X /*
X * LAP connection allready active, just bounce back! Since we
@@ -379,14 +377,14 @@
X {
X struct lsap_cb *lsap;
X
- DEBUG( 4, "irlmp_state_disconnected()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
X
X switch( event) {
X case LM_CONNECT_REQUEST:
- DEBUG( 4, "irlmp_state_disconnected: LM_CONNECT_REQUEST\n");
+ DEBUG( 4, __FUNCTION__ "(), LM_CONNECT_REQUEST\n");
X irlmp_next_lsap_state( self, LSAP_SETUP_PEND);
X
X irlmp_do_lap_event( self->lap, LM_LAP_CONNECT_REQUEST, NULL);
@@ -433,7 +431,7 @@
X struct sk_buff *skb)
X {
X
- DEBUG( 4, "irlmp_state_connect()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
@@ -464,7 +462,7 @@
X static void irlmp_state_connect_pend( struct lsap_cb *self, IRLMP_EVENT event,
X struct sk_buff *skb)
X {
- DEBUG( 4, "irlmp_state_connect_pend()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
@@ -508,7 +506,7 @@
X {
X LM_REASON reason;
X
- DEBUG( 4, "irlmp_state_dtr()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
@@ -584,7 +582,7 @@
X
X break;
X default:
- DEBUG( 4, "irlmp_state_dtr: Unknown event %d\n", event);
+ DEBUG( 4, __FUNCTION__ "(), Unknown event %d\n", event);
X break;
X }
X }
@@ -629,7 +627,7 @@
X irlmp_disconnect_indication( self, reason, skb);
X break;
X default:
- DEBUG( 4, "irlmp_state_setup: Unknown event %d\n", event);
+ DEBUG( 4, __FUNCTION__ "(), Unknown event %d\n", event);
X break;
X }
X }
@@ -664,23 +662,22 @@
X irlmp_next_lsap_state( self, LSAP_DISCONNECTED);
X break;
X case LM_WATCHDOG_TIMEOUT:
- DEBUG( 0, "irlmp_state_setup_pend() WATCHDOG_TIMEOUT!\n");
+ DEBUG( 0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n");
X
X /* FIXME: should we do a disconnect_indication? */
- return;
X ASSERT( self->lap != NULL, return;);
X irlmp_do_lap_event( self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
X irlmp_next_lsap_state( self, LSAP_DISCONNECTED);
X break;
X default:
- DEBUG( 4, "irlmp_state_setup_pend: Unknown event %d\n", event);
+ DEBUG( 4, __FUNCTION__ "(), Unknown event %d\n", event);
X break;
X }
X }
X
X void irlmp_next_lap_state( struct lap_cb *self, IRLMP_STATE state)
X {
- DEBUG( 4, "LMP LAP = %s\n", irlmp_state[state]);
+ DEBUG( 4, __FUNCTION__ "(), LMP LAP = %s\n", irlmp_state[state]);
X self->lap_state = state;
X }
X
@@ -688,6 +685,6 @@
X {
X ASSERT( self != NULL, return;);
X
- DEBUG( 4, "LMP LSAP = %s\n", irlsap_state[state]);
+ DEBUG( 4, __FUNCTION__ "(), LMP LSAP = %s\n", irlsap_state[state]);
X self->lsap_state = state;
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlmp_frame.c linux/net/irda/irlmp_frame.c
--- v2.2.0-pre8/linux/net/irda/irlmp_frame.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irlmp_frame.c Wed Jan 20 11:05:33 1999
@@ -1,15 +1,16 @@
X /*********************************************************************
X *
X * Filename: irlmp_frame.c
- * Version: 0.1
+ * Version: 0.8
X * Description: IrLMP frame implementation


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Tue Aug 19 02:09:59 1997
- * Modified at: Wed Dec 9 01:25:47 1998
+ * Modified at: Sat Jan 16 22:14:04 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

- * Copyright (c) 1997 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
+ * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>
+ * All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or

X * modify it under the terms of the GNU General Public License as
@@ -28,19 +29,18 @@
X
X #include <net/irda/irda.h>
X #include <net/irda/irlap.h>
+#include <net/irda/timer.h>
X #include <net/irda/irlmp.h>
X #include <net/irda/irlmp_frame.h>
X
X static struct lsap_cb *irlmp_find_lsap( struct lap_cb *self, __u8 dlsap,
- __u8 slsap, int status);
+ __u8 slsap, int status, hashbin_t *);
X
X inline void irlmp_send_data_pdu( struct lap_cb *self, __u8 dlsap, __u8 slsap,
X int expedited, struct sk_buff *skb)
X {
X __u8 *frame;
X
- DEBUG( 4, __FUNCTION__ "()\n");
-
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LAP_MAGIC, return;);
X ASSERT( skb != NULL, return;);
@@ -104,9 +104,6 @@
X __u8 slsap_sel; /* Source (this) LSAP address */
X __u8 dlsap_sel; /* Destination LSAP address */
X struct lsap_cb *lsap;
-
-
- DEBUG( 4, "irlmp_link_data_indication()\n");
X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LAP_MAGIC, return;);
@@ -119,12 +116,9 @@
X * The next statements may be confusing, but we do this so that
X * destination LSAP of received frame is source LSAP in our view
X */
- slsap_sel = fp[0] & ~CONTROL_BIT;
+ slsap_sel = fp[0] & LSAP_MASK;
X dlsap_sel = fp[1];
X
- DEBUG( 4, "slsap_sel = %02x, dlsap_sel = %02x\n", slsap_sel,
- dlsap_sel);
-
X /*
X * Check if this is an incoming connection, since we must deal with
X * it in a different way than other established connections.
@@ -132,11 +126,19 @@
X if (( fp[0] & CONTROL_BIT) && ( fp[2] == CONNECT_CMD)) {
X DEBUG( 4,"Incoming connection, source LSAP=%d, dest LSAP=%d\n",
X slsap_sel, dlsap_sel);
+
+ /* Try to find LSAP among the unconnected LSAPs */
X lsap = irlmp_find_lsap( self, dlsap_sel, slsap_sel,
- CONNECT_CMD);
+ CONNECT_CMD, irlmp->unconnected_lsaps);
+
+ /* Maybe LSAP was already connected, so try one more time */
+ if ( !lsap)
+ lsap = irlmp_find_lsap( self, dlsap_sel, slsap_sel, 0,
+ self->lsaps);
X } else
- lsap = irlmp_find_lsap( self, dlsap_sel, slsap_sel, 0);
-
+ lsap = irlmp_find_lsap( self, dlsap_sel, slsap_sel, 0,
+ self->lsaps);
+
X if ( lsap == NULL) {
X DEBUG( 0, "IrLMP, Sorry, no LSAP for received frame!\n");
X DEBUG( 0, __FUNCTION__
@@ -146,8 +148,7 @@
X DEBUG( 0, __FUNCTION__
X "(), received control frame %02x\n", fp[2]);
X } else {
- DEBUG( 0, __FUNCTION__
- "(), received data frame\n");
+ DEBUG( 0, __FUNCTION__ "(), received data frame\n");
X }
X dev_kfree_skb( skb);
X return;
@@ -157,10 +158,8 @@
X * Check if we received a control frame?
X */
X if ( fp[0] & CONTROL_BIT) {
- /* DEBUG( 0, "irlmp_input: Got control frame\n"); */
X switch( fp[2]) {
X case CONNECT_CMD:
- DEBUG( 4, "irlmp_input: CONNECT_CMD\n");
X lsap->lap = self;
X irlmp_do_lsap_event( lsap, LM_CONNECT_INDICATION, skb);
X break;
@@ -168,7 +167,7 @@
X irlmp_do_lsap_event( lsap, LM_CONNECT_CONFIRM, skb);
X break;
X case DISCONNECT:
- DEBUG( 4, "irlmp_input: Disconnect indication!\n");
+ DEBUG( 4, __FUNCTION__ "(), Disconnect indication!\n");
X irlmp_do_lsap_event( lsap, LM_DISCONNECT_INDICATION,
X skb);
X break;
@@ -179,8 +178,8 @@
X DEBUG( 0, "Access mode cnf not implemented!\n");
X break;
X default:
- DEBUG( 0, "irlmp_input: Unknown control frame %02x\n",
- fp[2]);
+ DEBUG( 0, __FUNCTION__
+ "(), Unknown control frame %02x\n", fp[2]);
X break;
X }
X } else if ( reliable == LAP_RELIABLE) {
@@ -202,7 +201,7 @@
X LAP_REASON reason,
X struct sk_buff *userdata)
X {
- DEBUG( 4, "irlmp_link_disconnect_indication()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( lap != NULL, return;);
X ASSERT( lap->magic == LMP_LAP_MAGIC, return;);
@@ -226,7 +225,7 @@
X void irlmp_link_connect_indication( struct lap_cb *self, struct qos_info *qos,
X struct sk_buff *skb)
X {
- DEBUG( 4, "irlmp_link_connect_indication()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");

X
X /* Copy QoS settings for this session */
X self->qos = qos;
@@ -265,24 +264,53 @@
X */
X void irlmp_link_discovery_confirm( struct lap_cb *self, hashbin_t *log)
X {
- DEBUG( 4, "irlmp_link_connect_confirm()\n");
+/* DISCOVERY *discovery; */
+ hashbin_t *old_log;


+
+ DEBUG( 4, __FUNCTION__ "()\n");

X
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == LMP_LAP_MAGIC, return;);
X
- if ( self->cachelog)
- hashbin_delete( self->cachelog, (FREE_FUNC) kfree);
+ ASSERT( self->cachelog != NULL, return;);
X
+ /*
+ * If log is missing this means that IrLAP was unable to perform the
+ * discovery, so restart discovery again with just the half timeout
+ * of the normal one.
+ */
+ if ( !log) {
+ irlmp_start_discovery_timer( irlmp, 150);
+ return;
+ }
+
+#if 0
+ discovery = hashbin_remove_first( log);
+ while ( discovery) {
+ DEBUG( 0, __FUNCTION__ "(), found %s\n", discovery->info);
+
+ /* Remove any old discovery of this device */
+ hashbin_remove( self->cachelog, discovery->daddr, NULL);
+
+ /* Insert the new one */
+ hashbin_insert( self->cachelog, (QUEUE *) discovery,
+ discovery->daddr, NULL);
+
+ discovery = hashbin_remove_first( log);
+ }
+#endif
+ old_log = self->cachelog;
X self->cachelog = log;
+ hashbin_delete( old_log, (FREE_FUNC) kfree);
X
X irlmp_do_lap_event( self, LM_LAP_DISCOVERY_CONFIRM, NULL);
+
+ DEBUG( 4, __FUNCTION__ "() -->\n");
X }
X
X #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-void irlmp_update_cache( struct lsap_cb *self)
+__inline__ void irlmp_update_cache( struct lsap_cb *self)
X {
- DEBUG( 4, __FUNCTION__ "()\n");
-
X /* Update cache entry */
X irlmp->cache.dlsap_sel = self->dlsap_sel;
X irlmp->cache.slsap_sel = self->slsap_sel;
@@ -292,28 +320,20 @@
X #endif
X
X /*
- * Function irlmp_find_handle (dlsap, slsap)
+ * Function irlmp_find_handle (self, dlsap_sel, slsap_sel, status, queue)
X *
X * Find handle assosiated with destination and source LSAP
X *
X */
X static struct lsap_cb *irlmp_find_lsap( struct lap_cb *self, __u8 dlsap_sel,
- __u8 slsap_sel, int status)
+ __u8 slsap_sel, int status,
+ hashbin_t *queue)
X {
X struct lsap_cb *lsap;
- hashbin_t *queue;
-
- DEBUG( 4, "irlmp_find_lsap: dlsap_sel=0x%02x, slsap_sel=0x%02x\n",
- dlsap_sel, slsap_sel);
X
X ASSERT( self != NULL, return NULL;);
X ASSERT( self->magic == LMP_LAP_MAGIC, return NULL;);
X
- if ( status)
- queue = irlmp->unconnected_lsaps;
- else
- queue = self->lsaps;
-
X /*
X * Optimize for the common case. We assume that the last frame
X * received is in the same connection as the last one, so check in
@@ -333,14 +353,11 @@
X lsap = ( struct lsap_cb *) hashbin_get_first( queue);
X while ( lsap != NULL) {
X /*
- * Check if source LSAP (in our view!) match, and if
- * dest LSAP is equal to LM_ANY, which is the case
- * for incomming connections
+ * If this is an incomming connection, then the destination
+ * LSAP selector may have been specified as LM_ANY so that
+ * any client can connect. In that case we only need to check
+ * if the source LSAP (in our view!) match!
X */
- DEBUG( 4, "irlmp_find_lsap: "
- "LSAP: lsap->dlsap=%d, lsap->slsap=%d\n",
- lsap->dlsap_sel, lsap->slsap_sel);
-
X if (( status == CONNECT_CMD) &&
X ( lsap->slsap_sel == slsap_sel) &&
X ( lsap->dlsap_sel == LSAP_ANY))
@@ -371,3 +388,5 @@
X /* Sorry not found! */
X return NULL;
X }
+
+
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlpt/Config.in linux/net/irda/irlpt/Config.in
--- v2.2.0-pre8/linux/net/irda/irlpt/Config.in Wed Dec 31 16:00:00 1969
+++ linux/net/irda/irlpt/Config.in Wed Jan 20 11:05:33 1999
@@ -0,0 +1,7 @@
+
+dep_tristate 'IrLPT protocol' CONFIG_IRLPT $CONFIG_IRDA
+
+if [ "$CONFIG_IRLPT" != "n" ]; then
+ dep_tristate ' IrLPT client support' CONFIG_IRLPT_CLIENT $CONFIG_IRLPT
+ dep_tristate ' IrLPT server support' CONFIG_IRLPT_SERVER $CONFIG_IRLPT
+fi
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlpt/Makefile linux/net/irda/irlpt/Makefile
--- v2.2.0-pre8/linux/net/irda/irlpt/Makefile Wed Dec 31 16:00:00 1969
+++ linux/net/irda/irlpt/Makefile Wed Jan 20 11:05:33 1999
@@ -0,0 +1,48 @@
+#
+# Makefile for the Linux IrDA IrLPT protocol layer.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+MOD_LIST_NAME := IRDA_MODULES
+O_TARGET := irlpt.o
+O_OBJS := irlpt_common.o
+M_OBJS := $(O_TARGET)
+MI_OBJS :=
+
+OX_OBJS +=
+
+ifeq ($(CONFIG_IRLPT_CLIENT),y)
+O_OBJS += irlpt_cli.o irlpt_cli_fsm.o
+else
+ ifeq ($(CONFIG_IRLPT_CLIENT),m)
+ M_OBJS += irlpt_client.o
+ endif
+endif
+
+ifeq ($(CONFIG_IRLPT_SERVER),y)
+O_OBJS += irlpt_srvr.o irlpt_srvr_fsm.o
+else
+ ifeq ($(CONFIG_IRLPT_SERVER),m)
+ M_OBJS += irlpt_server.o
+ endif
+endif
+
+# Special rule to build the composite modules
+ifeq ($(CONFIG_IRLPT_CLIENT),m)
+irlpt_client.o: irlpt_cli.o irlpt_cli_fsm.o
+ $(LD) $(LD_RFLAG) -r -o $@ irlpt_cli.o irlpt_cli_fsm.o
+endif
+ifeq ($(CONFIG_IRLPT_SERVER),m)
+irlpt_server.o: irlpt_srvr.o irlpt_srvr_fsm.o
+ $(LD) $(LD_RFLAG) -r -o $@ irlpt_srvr.o irlpt_srvr_fsm.o
+endif
+
+include $(TOPDIR)/Rules.make
+
+tar:
+ tar -cvf /dev/f1 .
+
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlpt/irlpt_cli.c linux/net/irda/irlpt/irlpt_cli.c
--- v2.2.0-pre8/linux/net/irda/irlpt/irlpt_cli.c Wed Dec 31 16:00:00 1969
+++ linux/net/irda/irlpt/irlpt_cli.c Wed Jan 20 11:05:33 1999
@@ -0,0 +1,599 @@


+/*********************************************************************
+ *
+ * Filename: irlpt.c
+ * Version:
+ * Description:
+ * Status: Experimental.
+ * Author: Thomas Davis, <rat...@radiks.net>
+ * Created at: Sat Feb 21 18:54:38 1998
+ * Modified at: Sun Mar 8 23:44:19 1998
+ * Modified by: Dag Brattli <da...@cs.uit.no>
+ * Sources: irlan.c
+ *
+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>,

+ * Copyright (c) 1998, Dag Brattli, <da...@cs.uit.no>


+ * All Rights Reserved.
+ *
+ * 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.
+ *
+ * I, Thomas Davis, provide no warranty for any of this software.
+ * This material is provided "AS-IS" and at no charge.
+ *
+ ********************************************************************/
+

+#include <net/irda/irlap.h>
+#include <net/irda/irttp.h>
+#include <net/irda/irlmp.h>
+#include <net/irda/irias_object.h>
+#include <net/irda/iriap.h>
+#include <net/irda/irlpt_common.h>
+#include <net/irda/irlpt_cli.h>
+#include <net/irda/irlpt_cli_fsm.h>
+#include <net/irda/timer.h>
+#include <net/irda/irda.h>
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+
+int irlpt_client_init(void);
+static void irlpt_client_cleanup(void);
+static void irlpt_client_close(struct irlpt_cb *self);
+
+static void irlpt_client_discovery_indication( DISCOVERY *);
+
+static void irlpt_client_connect_confirm( void *instance, void *sap,

+ struct qos_info *qos,
+ int max_seg_size,
+ struct sk_buff *skb);

+static void irlpt_client_disconnect_indication( void *instance, void *sap,
+ LM_REASON reason,
+ struct sk_buff *userdata);
+
+#if 0
+static char *rcsid = "$Id: irlpt_client.c,v 1.10 1998/11/10 22:50:57 dagb Exp $";
+#endif
+static char *version = "IrLPT, $Revision: 1.10 $/$Date: 1998/11/10 22:50:57 $ (Thomas Davis)";
+
+struct file_operations client_fops = {
+ irlpt_seek, /* seek */
+ NULL, /* read_irlpt (server) */
+ irlpt_write, /* write */
+ NULL, /* readdir */
+ NULL, /* poll */
+ NULL, /* ioctl */
+ NULL, /* mmap */
+ irlpt_open, /* open */
+ NULL, /* flush */
+ irlpt_close, /* release */
+ NULL, /* fsync */
+ NULL, /* fasync */
+ NULL, /* check_media_change */
+ NULL, /* revalidate */
+ NULL, /* lock */
+};
+
+int irlpt_client_debug = 4;
+
+extern char *irlptstate[];
+
+#ifdef CONFIG_PROC_FS
+
+/*
+ * Function client_proc_read (buf, start, offset, len, unused)
+ *
+ */
+static int irlpt_client_proc_read( char *buf, char **start, off_t offset,
+ int len, int unused)
+{
+ struct irlpt_cb *self;
+ int index;
+
+ len = sprintf(buf, "%s\n\n", version);
+
+ self = (struct irlpt_cb *) hashbin_get_first( irlpt_clients);
+ while( self) {
+ ASSERT( self != NULL, return len;);
+ ASSERT( self->magic == IRLPT_MAGIC, return len;);
+
+ len += sprintf(buf+len, "ifname: %s\n", self->ifname);
+ len += sprintf(buf+len, "minor: %d\n", self->ir_dev.minor);
+
+ switch ( self->servicetype) {
+ case IRLPT_UNKNOWN:
+ index = 0;
+ break;
+ case IRLPT_THREE_WIRE_RAW:
+ index = 1;
+ break;
+ case IRLPT_THREE_WIRE:
+ index = 2;
+ break;
+ case IRLPT_NINE_WIRE:
+ index = 3;
+ break;
+ case IRLPT_CENTRONICS:
+ index = 4;
+ break;
+ case IRLPT_SERVER_MODE:
+ index = 5;
+ break;
+ default:
+ index = 0;
+ break;
+ }
+
+ len += sprintf(buf+len, "service_type: %s\n",
+ irlpt_service_type[index]);
+ len += sprintf(buf+len, "port_type: %s\n",
+ irlpt_port_type[ self->porttype]);
+ len += sprintf(buf+len, "daddr: 0x%08x\n", self->daddr);
+ len += sprintf(buf+len, "fsm_state: %s\n",
+ irlpt_client_fsm_state[self->state]);
+ len += sprintf(buf+len, "retries: %d\n", self->open_retries);
+ len += sprintf(buf+len, "dlsap: %d\n", self->dlsap_sel);
+
+ len += sprintf(buf+len, "count: %d\n", self->count);
+ len += sprintf(buf+len, "rx_queue: %d\n",
+ skb_queue_len(&self->rx_queue));
+ len += sprintf(buf+len, "\n\n");
+
+ self = (struct irlpt_cb *) hashbin_get_next( irlpt_clients);
+ }
+
+ return len;
+}
+
+struct proc_dir_entry proc_irlpt_client = {
+ 0, 12, "irlpt_client",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, NULL /* ops -- default to array */,
+ &irlpt_client_proc_read /* get_info */,
+};
+
+extern struct proc_dir_entry proc_irda;
+
+#endif /* CONFIG_PROC_FS */
+
+/*
+ * Function irlpt_init (dev)
+ *
+ * Initializes the irlpt control structure
+ *
+ */
+__initfunc(int irlpt_client_init(void))
+{
+ DEBUG( irlpt_client_debug, "--> "__FUNCTION__ "\n");
+
+ printk( KERN_INFO "%s\n", version);
+
+ irlpt_clients = hashbin_new( HB_LOCAL);
+ if ( irlpt_clients == NULL) {
+ printk( KERN_WARNING "IrLPT: Can't allocate hashbin!\n");


+ return -ENOMEM;
+ }
+

+ irlmp_register_layer( S_PRINTER, CLIENT, TRUE,
+ irlpt_client_discovery_indication);
+
+#ifdef CONFIG_PROC_FS
+ proc_register( &proc_irda, &proc_irlpt_client);
+#endif /* CONFIG_PROC_FS */
+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
+


+ return 0;
+}
+

+
+#ifdef MODULE
+/*
+ * Function irlpt_cleanup (void)


+ *
+ *
+ *
+ */

+static void irlpt_client_cleanup(void)
+{
+ DEBUG( irlpt_client_debug, "--> "__FUNCTION__ "\n");
+
+ irlmp_unregister_layer( S_PRINTER, CLIENT);
+
+ /*
+ * Delete hashbin and close all irlan client instances in it
+ */
+ hashbin_delete( irlpt_clients, (FREE_FUNC) irlpt_client_close);
+
+#ifdef CONFIG_PROC_FS
+ proc_unregister( &proc_irda, proc_irlpt_client.low_ino);
+#endif
+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");


+}
+#endif /* MODULE */
+

+
+/*
+ * Function irlpt_open (void)
+ *
+ * This is the entry-point which starts all the fun! Currently this
+ *
+ */
+static struct irlpt_cb *irlpt_client_open( __u32 daddr)
+{
+ struct irlpt_cb *self;
+
+ DEBUG( irlpt_client_debug, "--> "__FUNCTION__ "\n");
+
+ self = kmalloc(sizeof(struct irlpt_cb), GFP_ATOMIC);
+ if (self == NULL)
+ return NULL;
+
+ memset(self, 0, sizeof(struct irlpt_cb));
+
+ ASSERT( self != NULL, return NULL;);
+
+ sprintf(self->ifname, "irlpt%d", hashbin_get_size(irlpt_clients));
+ self->ir_dev.minor = MISC_DYNAMIC_MINOR;
+ self->ir_dev.name = self->ifname;
+ self->ir_dev.fops = &client_fops;
+
+ misc_register(&self->ir_dev);
+
+ self->magic = IRLPT_MAGIC;
+ self->in_use = TRUE;
+ self->servicetype = IRLPT_THREE_WIRE_RAW;
+ self->porttype = IRLPT_SERIAL;
+
+ skb_queue_head_init(&self->rx_queue);
+
+ irlpt_client_next_state( self, IRLPT_CLIENT_IDLE);
+
+ hashbin_insert( irlpt_clients, (QUEUE *) self, daddr, NULL);
+
+ /* MOD_INC_USE_COUNT; */
+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
+
+ return self;
+}
+
+/*
+ * Function irlpt_client_close (self)
+ *
+ * This function closes and marks the IrLPT instance as not in use.
+ */
+static void irlpt_client_close( struct irlpt_cb *self)


+{
+ struct sk_buff *skb;
+

+ DEBUG( irlpt_client_debug, "--> " __FUNCTION__ "\n");
+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 11'
echo 'File patch-2.2.0-pre9 is continued in part 12'
echo 12 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part12

#!/bin/sh
# this is part 12 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 12; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

+
+ while (( skb = skb_dequeue(&self->rx_queue)) != NULL) {
+ DEBUG(3, "irlpt_client_close: freeing SKB\n");


+ dev_kfree_skb( skb);
+ }
+

+ misc_deregister(&self->ir_dev);
+
+ self->magic = ~IRLPT_MAGIC;
+
+ kfree( self);
+
+ /* MOD_DEC_USE_COUNT; */


+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
+}
+

+/*
+ * Function irlpt_discovery_indication (daddr)
+ *
+ * Remote device discovered, try query the remote IAS to see which
+ * device it is, and which services it has.
+ *
+ */
+static void irlpt_client_discovery_indication( DISCOVERY *discovery)
+{
+ struct irlpt_info info;
+ struct irlpt_cb *self;
+ __u32 daddr;


+
+ DEBUG( irlpt_client_debug, "--> " __FUNCTION__ "\n");
+

+ ASSERT( irlpt_clients != NULL, return;);
+ ASSERT( discovery != NULL, return;);
+
+ daddr = discovery->daddr;
+
+ /*
+ * Check if an instance is already dealing with this device
+ * (daddr)
+ */
+ self = (struct irlpt_cb *) hashbin_find( irlpt_clients, daddr, NULL);
+ if ( self != NULL) {


+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+ if ( self->state == IRLPT_CLIENT_IDLE) {
+ irlpt_client_do_event( self,
+ IRLPT_DISCOVERY_INDICATION,
+ NULL, &info);


+ }
+ return;
+ }
+

+
+ /*
+ * We have no instance for daddr, so time to start a new instance.
+ * First we must find a free entry in master array
+ */
+ if (( self = irlpt_client_open( daddr)) == NULL) {
+ DEBUG(irlpt_client_debug, __FUNCTION__
+ ":irlpt_client_open failed!\n");
+ }
+
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == IRLPT_MAGIC, return;);
+
+ self->daddr = info.daddr = daddr;
+
+ if (self->state == IRLPT_CLIENT_IDLE) {
+ irlpt_client_do_event( self, IRLPT_DISCOVERY_INDICATION,
+ NULL, &info);
+ }


+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
+}
+

+/*
+ * Function irlpt_disconnect_indication (handle)
+ *
+ */


+static void irlpt_client_disconnect_indication( void *instance, void *sap,
+ LM_REASON reason,

+ struct sk_buff *skb)
+{
+ struct irlpt_info info;


+ struct irlpt_cb *self;
+
+ DEBUG( irlpt_client_debug, "--> " __FUNCTION__ "\n");
+

+ self = ( struct irlpt_cb *) instance;


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ info.daddr = self->daddr;


+
+ DEBUG( irlpt_client_debug, __FUNCTION__

+ ": reason=%d (%s), peersap=%d\n",
+ reason, irlpt_reasons[reason], self->dlsap_sel);
+
+ self->connected = IRLPT_DISCONNECTED;
+ self->eof = reason;
+
+ wake_up_interruptible( &self->write_wait);
+
+ irlpt_client_do_event( self, LMP_DISCONNECT, NULL, NULL);
+
+ if (skb) {
+ dev_kfree_skb( skb);
+ }


+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
+}
+

+/*
+ * Function irlpt_connect_confirm (handle, qos, skb)
+ *
+ * LSAP connection confirmed!
+ */


+static void irlpt_client_connect_confirm( void *instance, void *sap,
+ struct qos_info *qos,

+ int max_sdu_size,
+ struct sk_buff *skb)
+{
+ struct irlpt_info info;


+ struct irlpt_cb *self;
+
+ DEBUG( irlpt_client_debug, "--> " __FUNCTION__ "\n");
+

+ self = ( struct irlpt_cb *) instance;


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ info.daddr = self->daddr;
+
+ /*
+ * Check if we have got some QoS parameters back! This should be the
+ * negotiated QoS for the link.
+ */
+ if ( qos) {
+ DEBUG( irlpt_client_debug, __FUNCTION__ ": Frame Size: %d\n",
+ qos->data_size.value);
+ }
+
+ self->irlap_data_size = (qos->data_size.value - IRLPT_MAX_HEADER);
+ self->connected = TRUE;
+
+ irlpt_client_do_event( self, LMP_CONNECT, NULL, NULL);
+
+ if (skb) {
+ dev_kfree_skb( skb);
+ }


+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
+}
+

+/*
+ * Function client_data_indication (handle, skb)
+ *
+ * This function gets the data that is received on the data channel
+ *
+ */
+static void irlpt_client_data_indication( void *instance, void *sap,
+ struct sk_buff *skb)

+{
+ struct irlpt_cb *self;
+
+ DEBUG( irlpt_client_debug, "--> " __FUNCTION__ "\n");
+

+ ASSERT( skb != NULL, return;);
+ DEBUG( irlpt_client_debug, __FUNCTION__ ": len=%d\n", (int) skb->len);
+
+ self = ( struct irlpt_cb *) instance;


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+#if 1
+ {
+ int i;
+
+ for(i=0;i<skb->len;i++)
+ if (skb->data[i] > 31 && skb->data[i] < 128) {
+ printk("%c", skb->data[i]);
+ } else {
+ if (skb->data[i] == 0x0d) {
+ printk("\n");
+ } else {
+ printk(".");
+ }
+ }
+
+ printk("\n");
+ }
+#endif
+
+ skb_queue_tail(&self->rx_queue, skb);
+ wake_up_interruptible(&self->read_wait);
+
+/* if (skb) { */
+/* dev_kfree_skb( skb); */
+/* } */


+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
+}
+

+/*
+ * Function irlpt_get_value_confirm (obj_id, type, value_int, value_char, priv)
+ *
+ * Fixed to match changes in iriap.h, DB.
+ *
+ */
+
+void irlpt_client_get_value_confirm(__u16 obj_id, struct ias_value *value,
+ void *priv)
+{
+ struct irlpt_info info;


+ struct irlpt_cb *self;
+
+ DEBUG( irlpt_client_debug, "--> " __FUNCTION__ "\n");
+

+ ASSERT( priv != NULL, return;);
+
+ self = (struct irlpt_cb *) priv;


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ /* can't stop here.. if we get a bad obj, must tell the state
+ machine that!
+ ASSERT( type == IAS_INTEGER, return;);
+ */
+
+ if ( value->type == IAS_INTEGER && value->t.integer != -1) {
+ info.dlsap_sel = value->t.integer;
+ self->dlsap_sel = value->t.integer;


+
+ DEBUG( irlpt_client_debug, __FUNCTION__

+ ": obj_id = %d, value = %d\n",
+ obj_id, value->t.integer);
+
+ irlpt_client_do_event( self, IAS_PROVIDER_AVAIL,
+ NULL, &info);
+ } else
+ irlpt_client_do_event( self, IAS_PROVIDER_NOT_AVAIL,
+ NULL, &info);


+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
+}
+

+void irlpt_client_connect_request( struct irlpt_cb *self)
+{
+ struct notify_t lpt_notify;


+
+ DEBUG( irlpt_client_debug, "--> " __FUNCTION__ "\n");
+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ lpt_notify.connect_confirm = irlpt_client_connect_confirm;
+ lpt_notify.disconnect_indication = irlpt_client_disconnect_indication;
+ lpt_notify.data_indication = irlpt_client_data_indication;
+ lpt_notify.instance = self;
+
+ self->lsap = irlmp_open_lsap( LSAP_ANY, &lpt_notify);
+ DEBUG( irlpt_client_debug, __FUNCTION__ ": Dest LSAP sel= %d\n",
+ self->dlsap_sel);
+
+ if (self->servicetype == IRLPT_THREE_WIRE_RAW) {
+ DEBUG( irlpt_client_debug, __FUNCTION__
+ ": issue THREE_WIRE_RAW connect\n");
+ irlmp_connect_request( self->lsap, self->dlsap_sel,
+ self->daddr, NULL, NULL);
+ }


+
+ DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
+}
+

+
+#ifdef MODULE
+
+MODULE_AUTHOR("Thomas Davis <rat...@radiks.net>");
+MODULE_DESCRIPTION("The Linux IrDA/IrLPT protocol");
+
+/*
+ * Function init_module (void)
+ *
+ * Initialize the IrLPT client module, this function is called by the
+ * modprobe(1) program.


+ */
+int init_module(void)
+{

+
+ DEBUG( irlpt_client_debug, "--> irlpt client: init_module\n");
+
+ irlpt_client_init();
+
+ DEBUG( irlpt_client_debug, "irlpt client: init_module -->\n");


+
+ return 0;
+}
+

+/*
+ * Function cleanup_module (void)
+ *
+ * Remove the IrLPT server module, this function is called by the rmmod(1)
+ * program
+ */
+void cleanup_module(void)
+{
+ DEBUG( irlpt_client_debug, "--> irlpt client: cleanup_module\n");
+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+
+ /* Free some memory */
+ irlpt_client_cleanup();
+
+ DEBUG( irlpt_client_debug, "irlpt client: cleanup_module -->\n");
+}
+
+#endif /* MODULE */
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlpt/irlpt_cli_fsm.c linux/net/irda/irlpt/irlpt_cli_fsm.c
--- v2.2.0-pre8/linux/net/irda/irlpt/irlpt_cli_fsm.c Wed Dec 31 16:00:00 1969
+++ linux/net/irda/irlpt/irlpt_cli_fsm.c Wed Jan 20 11:05:33 1999
@@ -0,0 +1,374 @@
+/*********************************************************************
+ *
+ * Filename: irlpt_cli_fsm.c
+ * Version: 0.1


+ * Description:
+ * Status: Experimental.

+ * Author: Dag Brattli <da...@cs.uit.no>
+ * Created at: Tue Jan 12 11:06:00 1999
+ * Modified at: Tue Jan 12 11:14:22 1999


+ * Modified by: Dag Brattli <da...@cs.uit.no>
+ *

+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>

+ * Copyright (c) 1998, Dag Brattli, <da...@cs.uit.no>
+ * All Rights Reserved.
+ *
+ * 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.
+ *

+ * I, Thomas Davis, provide no warranty for any of this software. This
+ * material is provided "AS-IS" and at no charge.


+ *
+ ********************************************************************/
+

+#include <net/irda/iriap.h>
+#include <net/irda/irlmp.h>
+#include <net/irda/irttp.h>


+#include <net/irda/irlpt_common.h>
+#include <net/irda/irlpt_cli.h>
+#include <net/irda/irlpt_cli_fsm.h>

+#include <net/irda/irda.h>
+
+#if 0
+static char *rcsid = "$Id: irlpt_client_fsm.c,v 1.3 1998/10/05 05:46:44 ratbert Exp $";
+#endif
+
+static int irlpt_client_state_idle ( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
+static int irlpt_client_state_query ( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
+static int irlpt_client_state_ready ( struct irlpt_cb *self,
+ IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
+static int irlpt_client_state_waiti ( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
+static int irlpt_client_state_waitr ( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
+static int irlpt_client_state_conn ( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
+
+int irlpt_client_fsm_debug = 3;
+
+int (*irlpt_client_state[])( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info) =
+{
+ irlpt_client_state_idle,
+ irlpt_client_state_query,
+ irlpt_client_state_ready,
+ irlpt_client_state_waiti,
+ irlpt_client_state_waitr,
+ irlpt_client_state_conn,
+};
+
+void irlpt_client_do_event( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info)
+{
+ DEBUG( irlpt_client_fsm_debug,"--> " __FUNCTION__ "\n");


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": STATE = %s, EVENT = %s\n",
+ irlpt_server_fsm_state[self->state], irlpt_fsm_event[event]);
+
+ (*irlpt_client_state[ self->state]) ( self, event, skb, info);
+
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ " -->\n");
+}
+
+void irlpt_client_next_state( struct irlpt_cb *self, IRLPT_CLIENT_STATE state)
+{
+ DEBUG( irlpt_client_fsm_debug,"--> " __FUNCTION__ ":\n");


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": NEXT STATE = %s\n",
+ irlpt_client_fsm_state[state]);
+
+ self->state = state;
+
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ " -->\n");
+}
+
+/*
+ * Function client_state_idle (event, skb, info)
+ *
+ * IDLE, We are waiting for an indication that there is a provider
+ * available.
+ */
+static int irlpt_client_state_idle( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info)
+{
+ DEBUG( irlpt_client_fsm_debug,"--> " __FUNCTION__ ":\n");
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ switch( event) {
+ case IRLPT_DISCOVERY_INDICATION:
+ /* Get some values from peer IAS */
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": IRLPT_DISCOVERY_INDICATION, sending getvaluebyclass command..\n");
+ iriap_getvaluebyclass_request( info->daddr,
+ "IrLPT", "IrDA:IrLMP:LsapSel",
+ irlpt_client_get_value_confirm,
+ (void *) self);
+ irlpt_client_next_state( self, IRLPT_CLIENT_QUERY);
+ break;
+
+ default:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": Unknown event %d (%s)\n",
+ event, irlpt_fsm_event[event]);
+ break;
+ }
+
+ if (skb) {


+ dev_kfree_skb( skb);
+ }
+

+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+/*
+ * Function client_state_query
+ *
+ * QUERY, We have queryed the remote IAS and is ready to connect
+ * to provider, just waiting for the confirm.
+ *
+ */
+static int irlpt_client_state_query( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info)
+{
+ DEBUG( irlpt_client_fsm_debug,"--> " __FUNCTION__ ":\n");
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ switch( event) {
+ case IAS_PROVIDER_AVAIL:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": IAS_PROVIDER_AVAIL\n");
+ self->open_retries = 0;
+ irlpt_client_next_state( self, IRLPT_CLIENT_READY);
+ irlpt_client_do_event( self, IRLPT_CONNECT_REQUEST, NULL, NULL);
+ break;
+
+ case IAS_PROVIDER_NOT_AVAIL:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": IAS_PROVIDER_NOT_AVAIL\n");
+ irlpt_client_next_state( self, IRLPT_CLIENT_IDLE);
+ break;
+
+ default:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": Unknown event %d (%s)\n",
+ event, irlpt_fsm_event[event]);
+ break;
+ }
+
+ if (skb) {


+ dev_kfree_skb( skb);
+ }
+

+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+/*
+ * Function client_state_info
+ *
+ * INFO, We have issued a GetInfo command and is awaiting a reply.
+ */
+static int irlpt_client_state_ready( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info)
+{
+ DEBUG( irlpt_client_fsm_debug,"--> " __FUNCTION__ ":\n");
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ switch( event) {
+ case IRLPT_CONNECT_REQUEST:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": IRLPT_CONNECT_REQUEST\n");
+ irlpt_client_connect_request(self);
+ irlpt_client_next_state( self, IRLPT_CLIENT_WAITI);
+ break;
+ case LMP_DISCONNECT:
+ case LAP_DISCONNECT:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": LMP_DISCONNECT or LAP_DISCONNECT\n");
+ irlpt_client_next_state( self, IRLPT_CLIENT_IDLE);
+ break;
+ default:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": Unknown event %d (%s)\n",
+ event, irlpt_fsm_event[event]);
+ break;
+ }
+
+ if ( skb) {


+ dev_kfree_skb( skb);
+ }
+

+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+
+

+/*
+ * Function client_state_waiti

+ *
+ *
+ */

+static int irlpt_client_state_waiti( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info)
+{
+ DEBUG( irlpt_client_fsm_debug,"--> " __FUNCTION__ ":\n");
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ switch( event) {
+ case LMP_CONNECT:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": LMP_CONNECT\n");
+ irlpt_client_next_state(self, IRLPT_CLIENT_CONN);
+ break;
+ case LAP_DISCONNECT:
+ case LMP_DISCONNECT:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": LMP_DISCONNECT\n");
+ irlpt_client_next_state( self, IRLPT_CLIENT_IDLE);
+ break;
+
+ default:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": Unknown event %d (%s)\n",
+ event, irlpt_fsm_event[event]);
+ break;
+ }
+
+ if ( skb) {


+ dev_kfree_skb( skb);
+ }
+

+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+/*
+ * Function client_state_waitr

+ *
+ *
+ */

+static int irlpt_client_state_waitr( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info)
+{
+ DEBUG( irlpt_client_fsm_debug,"--> " __FUNCTION__ ":\n");
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ switch( event) {
+ case LMP_CONNECT:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": LMP_CONNECT\n");
+ irlpt_client_next_state(self, IRLPT_CLIENT_CONN);
+ break;
+
+ case LMP_DISCONNECT:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": LMP_DISCONNECT\n");
+ irlpt_client_next_state( self, IRLPT_CLIENT_IDLE);
+ break;
+
+ case LAP_DISCONNECT:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ ": LAP_DISCONNECT\n");
+ irlpt_client_next_state( self, IRLPT_CLIENT_IDLE);
+ break;
+
+ default:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": Unknown event %d, (%s)\n",
+ event, irlpt_fsm_event[event]);
+ break;
+ }
+
+ if ( skb) {


+ dev_kfree_skb( skb);
+ }
+

+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+/*
+ * Function client_state_conn (event, skb, info)
+ *
+ * CONN, We have connected to a provider but has not issued any
+ * commands yet.
+ *
+ */
+static int irlpt_client_state_conn( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info)
+{
+ DEBUG( irlpt_client_fsm_debug,"--> " __FUNCTION__ ":\n");
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ switch( event) {
+ case CLIENT_DATA_INDICATION:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": CLIENT_DATA_INDICATION\n");
+ irlpt_client_next_state( self, IRLPT_CLIENT_CONN);
+ break;
+
+ case LMP_DISCONNECT:
+ case LAP_DISCONNECT:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": LMP_DISCONNECT/LAP_DISCONNECT\n");
+ irlpt_client_next_state( self, IRLPT_CLIENT_IDLE);
+ break;
+
+ default:
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": Unknown event %d (%s)\n",
+ event, irlpt_fsm_event[event]);
+ break;
+ }
+
+ if ( skb) {


+ dev_kfree_skb( skb);
+ }
+

+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+void irlpt_client_print_event( IRLPT_EVENT event)
+{
+ DEBUG( irlpt_client_fsm_debug, __FUNCTION__
+ ": IRLPT_EVENT = %s\n", irlpt_fsm_event[event]);
+}
+
+
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlpt/irlpt_common.c linux/net/irda/irlpt/irlpt_common.c
--- v2.2.0-pre8/linux/net/irda/irlpt/irlpt_common.c Wed Dec 31 16:00:00 1969
+++ linux/net/irda/irlpt/irlpt_common.c Wed Jan 20 11:05:33 1999
@@ -0,0 +1,512 @@
+/*********************************************************************
+ *
+ * Filename: irlpt_common.c


+ * Version:
+ * Description:
+ * Status: Experimental.
+ * Author: Thomas Davis, <rat...@radiks.net>
+ * Created at: Sat Feb 21 18:54:38 1998
+ * Modified at: Sun Mar 8 23:44:19 1998
+ * Modified by: Dag Brattli <da...@cs.uit.no>

+ * Sources: irlpt.c


+ *
+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>,
+ * Copyright (c) 1998, Dag Brattli, <da...@cs.uit.no>
+ * All Rights Reserved.
+ *
+ * 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.
+ *
+ * I, Thomas Davis, provide no warranty for any of this software.
+ * This material is provided "AS-IS" and at no charge.
+ *
+ ********************************************************************/
+

+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <asm/segment.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irlap.h>
+#include <net/irda/irlmp.h>
+#include <net/irda/iriap.h>
+#include <net/irda/irttp.h>
+#include <net/irda/timer.h>
+
+#include <net/irda/irlpt_common.h>
+/* #include "irlpt_client.h" */
+/* #include "irlpt_server.h" */


+
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>

+#include <linux/fs.h>
+
+char *irlpt_service_type[] = {
+ "IRLPT_UNKNOWN",
+ "IRLPT_THREE_WIRE_RAW",
+ "IRLPT_THREE_WIRE",
+ "IRLPT_NINE_WIRE",
+ "IRLPT_CENTRONICS",
+ "IRLPT_SERVER_MODE",
+};
+
+char *irlpt_port_type[] = {
+ "IRLPT_UNKNOWN",
+ "IRLPT_SERIAL",
+ "IRLPT_PARALLEL",
+};
+
+char *irlpt_connected[] = {
+ "IRLPT_DISCONNECTED",
+ "IRLPT_WAITING",
+ "IRLPT_CONNECTED",
+ "IRLPT_FLUSHED",
+};
+
+char *irlpt_reasons[] = {
+ "SERVICE_CLOSE", /* Service has closed the connection */
+ "DISC_INDICATION", /* Received a disconnect request from peer entity*/
+ "NO_RESPONSE", /* To many retransmits without response */
+ "DEADLOCK_DETECTED", /* To many retransmits _with_ response */
+ "FOUND_NONE", /* No devices were discovered */
+ "MEDIA_BUSY",
+
+};
+
+char *irlpt_client_fsm_state[] = {
+ "IRLPT_CLIENT_IDLE",
+ "IRLPT_CLIENT_QUERY",
+ "IRLPT_CLIENT_READY",
+ "IRLPT_CLIENT_WAITI",
+ "IRLPT_CLIENT_WAITR",
+ "IRLPT_CLIENT_CONN"
+};
+
+char *irlpt_server_fsm_state[] = {
+ "IRLPT_SERVER_IDLE",
+ "IRLPT_SERVER_CONN"
+};
+
+char *irlpt_fsm_event[] = {
+ "QUERY_REMOTE_IAS",
+ "IAS_PROVIDER_AVAIL",
+ "IAS_PROVIDER_NOT_AVAIL",
+ "LAP_DISCONNECT",
+ "LMP_CONNECT",
+ "LMP_DISCONNECT",
+ "LMP_CONNECT_INDICATION",
+ "LMP_DISCONNECT_INDICATION",
+ "IRLPT_DISCOVERY_INDICATION",
+ "IRLPT_CONNECT_REQUEST",
+ "IRLPT_DISCONNECT_REQUEST",
+ "CLIENT_DATA_INDICATION",
+};
+
+hashbin_t *irlpt_clients = NULL;
+struct irlpt_cb *irlpt_server = NULL;
+int irlpt_common_debug = 4; /* want to change this? please don't!
+ use irlpt_common_debug=3 on the command line! */
+
+static struct wait_queue *irlpt_wait;
+
+#if 0
+static char *rcsid = "$Id: irlpt_common.c,v 1.6 1998/11/10 22:50:58 dagb Exp $";
+#endif
+
+struct irlpt_cb *irlpt_find_handle(unsigned int minor)


+{
+ struct irlpt_cb *self;
+

+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ /* Check for server */
+ if (irlpt_server != NULL && irlpt_server->ir_dev.minor == minor) {
+ DEBUG(irlpt_common_debug, __FUNCTION__
+ ": irlpt_server file handle!\n");
+ return irlpt_server;
+ }
+
+ /* Check the clients */


+ self = (struct irlpt_cb *) hashbin_get_first( irlpt_clients);
+ while ( self) {

+ ASSERT( self->magic == IRLPT_MAGIC, return NULL;);
+
+ if ( minor == self->ir_dev.minor)
+ return self;
+


+ self = (struct irlpt_cb *) hashbin_get_next( irlpt_clients);
+ }
+

+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
+
+ return NULL;
+}
+
+ssize_t irlpt_read( struct file *file, char *buffer, size_t count, loff_t
+ *noidea)
+{
+ int len=0;
+ char *ptr = buffer;
+ struct irlpt_cb *self;
+ struct sk_buff *skb = NULL;
+ struct wait_queue wait = { current, NULL };
+
+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ self = irlpt_find_handle(MINOR( file->f_dentry->d_inode->i_rdev));
+
+ ASSERT( self != NULL, return 0;);
+ ASSERT( self->magic == IRLPT_MAGIC, return 0;);
+
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ": count=%d, skb_len=%d, connected=%d (%s) eof=%d\n",
+ count, skb_queue_len(&self->rx_queue), self->connected,
+ irlpt_connected[self->connected], self->eof);
+
+ if (self->eof && !skb_queue_len(&self->rx_queue)) {
+ switch (self->eof) {
+ case LM_USER_REQUEST:
+ self->eof = FALSE;
+ DEBUG(3, "irlpt_read: returning 0\n");
+ return 0;
+ case LM_LAP_DISCONNECT:
+ self->eof = FALSE;
+ return -EIO;
+ case LM_LAP_RESET:
+ self->eof = FALSE;
+ return -ECONNRESET;
+ default:
+ self->eof = FALSE;
+ return -EIO;
+ }
+ }
+
+ while (len <= count) {
+ skb = skb_dequeue(&self->rx_queue);
+
+ if (skb != NULL) {
+ DEBUG(irlpt_common_debug, __FUNCTION__
+ ": len=%d, skb->len=%d, count=%d\n",
+ len, (int) skb->len, count);
+
+ if ((skb->len + len) < count) {
+ copy_to_user(ptr, skb->data, skb->len);
+ len += skb->len;
+ ptr += skb->len;
+
+ dev_kfree_skb( skb);
+ } else {
+ skb_queue_head(&self->rx_queue, skb);
+ break;
+ }
+ } else {
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ": skb=NULL, len=%d, count=%d, eof=%d\n",
+ len, count, self->eof);
+
+ if (!signal_pending(current) && !self->eof) {
+ add_wait_queue(&irlpt_wait, &wait);


+ current->state = TASK_INTERRUPTIBLE;

+ schedule();
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&irlpt_wait, &wait);
+ } else


+ break;
+ }
+ }
+

+ DEBUG(irlpt_common_debug, __FUNCTION__ ": len=%d\n", len);
+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
+ return len;
+}
+
+ssize_t irlpt_write(struct file *file, const char *buffer,


+ size_t count, loff_t *noidea)

+{
+ struct irlpt_cb *self;

+ struct sk_buff *skb;
+ struct wait_queue wait = { current, NULL };
+
+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ self = irlpt_find_handle(MINOR( file->f_dentry->d_inode->i_rdev));
+
+ ASSERT( self != NULL, return 0;);
+ ASSERT( self->magic == IRLPT_MAGIC, return 0;);
+
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ": count = %d\n", count);
+
+ if (self->state != IRLPT_CLIENT_CONN) {
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ": state != IRLPT_CONN (possible link problems?)\n");
+ return -ENOLINK;
+ }
+
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ": pkt_count = %d\n", self->pkt_count);
+ if (self->pkt_count > 8) {
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ": too many outstanding buffers, going to sleep\n");
+ add_wait_queue(&self->write_wait, &wait);


+ current->state = TASK_INTERRUPTIBLE;

+ schedule();
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&self->write_wait, &wait);
+ }
+
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ":count = %d, irlap_data_size = %d, IRLPT_MAX_HEADER = %d\n",
+ count, self->irlap_data_size, IRLPT_MAX_HEADER);
+
+ if (count > (self->irlap_data_size - IRLPT_MAX_HEADER)) {
+ count = (self->irlap_data_size - IRLPT_MAX_HEADER);
+ DEBUG(irlpt_common_debug, __FUNCTION__
+ ": setting count to %d\n", count);
+ }
+
+ DEBUG( irlpt_common_debug, __FUNCTION__ ": count = %d\n", count);
+
+ skb = dev_alloc_skb(count + IRLPT_MAX_HEADER);
+ if ( skb == NULL) {
+ printk( KERN_INFO __FUNCTION__ ": couldn't allocate skbuff!\n");


+ return 0;
+ }
+

+ /*
+ * we use the unused stamp field to hold the device minor
+ * number, so we can look it up when the skb is destroyed.
+ */
+ *((__u32 *) &skb->stamp) = MINOR( file->f_dentry->d_inode->i_rdev);
+
+ skb_reserve( skb, IRLPT_MAX_HEADER);
+ skb_put( skb, count);
+
+ skb->destructor = irlpt_flow_control;
+ self->pkt_count++;
+
+ copy_from_user( skb->data, buffer, count);
+
+ irlmp_data_request(self->lsap, skb);
+
+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
+
+ return(count);
+}
+
+loff_t irlpt_seek( struct file *file, loff_t offset, int count)
+{
+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
+ return -ESPIPE;


+}
+
+#if 0
+

+/*
+ * Function irlpt_select (inode, filp, mode, table)
+ *
+ * Implementation for the select() call
+ *
+ */
+int irlpt_select( struct inode *inode, struct file *filp, int mode,
+ select_table *table)


+{
+ struct irlpt_cb *self;
+

+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ self = irlpt_find_handle(MINOR( inode->i_rdev));
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ switch (mode) {
+ case SEL_IN:
+ if ( skb_queue_len( &self->rx_queue))
+ return 1; /* Readable */
+ select_wait( &self->read_wait, table);
+ break;
+ case SEL_OUT:
+ if ( self->connected)
+ return 1;
+ select_wait( &self->write_wait, table);
+ break;
+ case SEL_EX:
+ if ( self->connected)
+ return 1;
+ select_wait( &self->ex_wait, table);
+ break;
+ default:
+ break;
+ }
+
+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+#else
+
+/*
+ * Function irobex_poll (file, wait)


+ *
+ *
+ *
+ */

+static u_int irlpt_poll(struct file *file, poll_table *wait)
+{
+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ /* check out /usr/src/pcmcia/modules/ds.c for an example */
+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
+ return 0;
+}
+
+#endif
+
+/*
+ * Function open_irlpt (inode, file)


+ *
+ *
+ *
+ */

+int irlpt_open(struct inode *inode, struct file *file)


+{
+ struct irlpt_cb *self;
+

+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ self = irlpt_find_handle(MINOR( file->f_dentry->d_inode->i_rdev));
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+#if 0
+ if (self->state == IRLPT_IDLE) {
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ": state == IRLPT_IDLE! (no device found yet)\n");


+ return -ENODEV;
+ }
+

+ if (self->state == IRLPT_QUERY ||
+ self->state == IRLPT_READY ||
+ self->state == IRLPT_WAITI) {
+ DEBUG( irlpt_common_debug, __FUNCTION__ ": state == IRLPT_QUERY, "
+ "IRLPT_READY or IRLPT_WAITI (link problems)!\n");
+ return -EBUSY;
+ }
+#endif
+
+ if (self->count++) {
+ DEBUG( irlpt_common_debug, __FUNCTION__
+ ": count not zero; actual = %d\n", self->count);
+ self->count--;


+ return -EBUSY;
+ }
+

+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+/*
+ * Function close_irlpt (inode, file)


+ *
+ *
+ *
+ */

+int irlpt_close(struct inode *inode, struct file *file)


+{
+ struct irlpt_cb *self;
+

+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ self = irlpt_find_handle(MINOR( file->f_dentry->d_inode->i_rdev));
+
+ DEBUG(irlpt_common_debug, __FUNCTION__ ": have handle!\n");
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ DEBUG(irlpt_common_debug, __FUNCTION__ ": self->count=%d\n", self->count);
+ if (self->count > 0)
+ self->count--;
+
+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+void irlpt_dump_buffer( struct sk_buff *skb)
+{
+ int i;
+
+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ for(i=0;i<skb->len;i++)
+ if (skb->data[i] > 31 && skb->data[i] < 128) {
+ printk("%c", skb->data[i]);
+ } else {
+ if (skb->data[i] == 0x0d) {
+ printk("\n");
+ } else {
+ printk(".");
+ }
+ }
+
+ printk("\n");
+
+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
+}
+
+void irlpt_flow_control(struct sk_buff *skb)


+{
+ struct irlpt_cb *self;
+

+ DEBUG(irlpt_common_debug, "--> " __FUNCTION__ "\n");
+
+ self = irlpt_find_handle( *((__u32 *) &skb->stamp));
+
+ self->pkt_count--;
+
+ ASSERT(self->pkt_count >= 0, return;);
+
+ DEBUG(irlpt_common_debug, __FUNCTION__
+ ": packet destroyed, count = %d\n", self->pkt_count);
+
+ wake_up_interruptible( &self->write_wait);
+
+ DEBUG(irlpt_common_debug, __FUNCTION__ " -->\n");
+}
+
+#ifdef MODULE
+
+/*
+ * Function init_module (void)
+ *
+ * Initialize the module, this function is called by the
+ * modprobe(1) program.
+ */
+int init_module(void)

+{
+ return 0;
+}
+

+/*
+ * Function cleanup_module (void)
+ *
+ * Remove the module, this function is called by the rmmod(1)
+ * program


+ */
+void cleanup_module(void)
+{
+

+}


+
+#endif /* MODULE */

diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlpt/irlpt_srvr.c linux/net/irda/irlpt/irlpt_srvr.c
--- v2.2.0-pre8/linux/net/irda/irlpt/irlpt_srvr.c Wed Dec 31 16:00:00 1969
+++ linux/net/irda/irlpt/irlpt_srvr.c Wed Jan 20 11:05:33 1999
@@ -0,0 +1,545 @@


+/*********************************************************************
+ *
+ * Filename: irlpt.c
+ * Version:
+ * Description:
+ * Status: Experimental.
+ * Author: Thomas Davis, <rat...@radiks.net>
+ * Created at: Sat Feb 21 18:54:38 1998
+ * Modified at: Sun Mar 8 23:44:19 1998
+ * Modified by: Dag Brattli <da...@cs.uit.no>
+ * Sources: irlan.c
+ *
+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>,

+ * Dag Brattli, <da...@cs.uit.no>


+ * All Rights Reserved.
+ *
+ * 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.
+ *
+ * I, Thomas Davis, provide no warranty for any of this software.
+ * This material is provided "AS-IS" and at no charge.
+ *
+ ********************************************************************/
+

+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/proc_fs.h>
+

+#include <net/irda/irlap.h>
+#include <net/irda/irlmp.h>
+#include <net/irda/iriap.h>
+#include <net/irda/irias_object.h>
+#include <net/irda/timer.h>
+#include <net/irda/irda.h>
+#include <net/irda/irlpt_common.h>
+#include <net/irda/irlpt_server.h>
+#include <net/irda/irlpt_server_fsm.h>
+
+#ifdef CONFIG_PROC_FS
+static int irlpt_server_proc_read(char *buf, char **start, off_t offset,
+ int len, int unused);


+#endif /* CONFIG_PROC_FS */
+

+int irlpt_server_init(void);
+static void irlpt_server_cleanup(void);
+static void irlpt_server_disconnect_indication( void *instance, void *sap,
+ LM_REASON reason,
+ struct sk_buff *skb);
+static void irlpt_server_connect_confirm( void *instance, void *sap,

+ struct qos_info *qos,
+ int max_seg_size,
+ struct sk_buff *skb);

+static void irlpt_server_connect_indication( void *instance, void *sap,

+ struct qos_info *qos,
+ int max_seg_size,
+ struct sk_buff *skb);

+static void irlpt_server_data_indication( void *instance, void *sap,
+ struct sk_buff *skb);
+static void register_irlpt_server(void);
+static void deregister_irlpt_server(void);
+
+static struct wait_queue *irlpt_server_wait;
+
+int irlpt_server_lsap = LSAP_IRLPT;
+int irlpt_server_debug = 4;
+
+#if 0
+static char *rcsid = "$Id: irlpt_server.c,v 1.9 1998/10/22 12:02:22 dagb Exp $";
+#endif
+static char *version = "IrLPT server, $Revision: 1.9 $/$Date: 1998/10/22 12:02:22 $ (Thomas Davis)";
+
+struct file_operations irlpt_fops = {


+ irlpt_seek, /* seek */

+ irlpt_read, /* read */
+ irlpt_write,


+ NULL, /* readdir */
+ NULL, /* poll */
+ NULL, /* ioctl */
+ NULL, /* mmap */
+ irlpt_open, /* open */
+ NULL, /* flush */
+ irlpt_close, /* release */
+ NULL, /* fsync */
+ NULL, /* fasync */
+ NULL, /* check_media_change */
+ NULL, /* revalidate */
+ NULL, /* lock */
+};
+

+#ifdef CONFIG_PROC_FS
+
+/*
+ * Function proc_irlpt_read (buf, start, offset, len, unused)
+ *


+ *
+ *
+ */

+static int irlpt_server_proc_read(char *buf, char **start, off_t offset,

+ int len, int unused)
+{

+ int index;
+
+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
+
+ if (irlpt_server != NULL) {


+ len = sprintf(buf, "%s\n\n", version);

+ len += sprintf(buf+len, "ifname: %s\n", irlpt_server->ifname);
+ len += sprintf(buf+len, "minor: %d\n", irlpt_server->ir_dev.minor);
+
+ switch (irlpt_server->servicetype) {


+ case IRLPT_UNKNOWN:
+ index = 0;
+ break;
+ case IRLPT_THREE_WIRE_RAW:
+ index = 1;
+ break;
+ case IRLPT_THREE_WIRE:
+ index = 2;
+ break;
+ case IRLPT_NINE_WIRE:
+ index = 3;
+ break;
+ case IRLPT_CENTRONICS:
+ index = 4;
+ break;
+ case IRLPT_SERVER_MODE:
+ index = 5;
+ break;
+ default:
+ index = 0;
+ break;
+ }
+

+ len += sprintf(buf+len, "servicetype: %s\n",
+ irlpt_service_type[index]);
+ len += sprintf(buf+len, "porttype: %s\n",
+ irlpt_port_type[irlpt_server->porttype]);
+ len += sprintf(buf+len, "daddr: %d\n",
+ irlpt_server->daddr);
+ len += sprintf(buf+len, "state: %s\n",
+ irlpt_server_fsm_state[irlpt_server->state]);


+ len += sprintf(buf+len, "retries: %d\n",

+ irlpt_server->open_retries);
+ len += sprintf(buf+len, "peersap: %d\n",
+ irlpt_server->dlsap_sel);


+ len += sprintf(buf+len, "count: %d\n",

+ irlpt_server->count);


+ len += sprintf(buf+len, "rx_queue: %d\n",

+ skb_queue_len(&irlpt_server->rx_queue));
+ len += sprintf(buf+len, "\n");
+ }
+
+ DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
+
+ return len;


+}
+
+extern struct proc_dir_entry proc_irda;
+

+struct proc_dir_entry proc_irlpt_server = {
+ 0, 12, "irlpt_server",


+ S_IFREG | S_IRUGO, 1, 0, 0,
+ 0, NULL /* ops -- default to array */,

+ &irlpt_server_proc_read /* get_info */,
+};
+


+#endif /* CONFIG_PROC_FS */
+
+/*
+ * Function irlpt_init (dev)
+ *
+ * Initializes the irlpt control structure
+ *
+ */
+

+/*int irlpt_init( struct device *dev) {*/
+__initfunc(int irlpt_server_init(void))
+{
+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");


+
+ printk( KERN_INFO "%s\n", version);
+

+ irlpt_server = (struct irlpt_cb *) kmalloc (sizeof(struct irlpt_cb),
+ GFP_KERNEL);
+
+ if ( irlpt_server == NULL) {
+ printk( KERN_WARNING "IrLPT server: Can't allocate"
+ " irlpt_server control block!\n");


+ return -ENOMEM;
+ }
+

+ memset( irlpt_server, 0, sizeof(struct irlpt_cb));
+
+ sprintf(irlpt_server->ifname, "irlpt_server");
+ irlpt_server->ir_dev.minor = MISC_DYNAMIC_MINOR;
+ irlpt_server->ir_dev.name = irlpt_server->ifname;
+ irlpt_server->ir_dev.fops = &irlpt_fops;
+ misc_register(&irlpt_server->ir_dev);
+ irlpt_server->magic = IRLPT_MAGIC;
+ irlpt_server->in_use = TRUE;
+ irlpt_server->servicetype = IRLPT_THREE_WIRE_RAW;
+ irlpt_server->porttype = IRLPT_SERIAL;
+
+ skb_queue_head_init(&irlpt_server->rx_queue);
+
+ irlmp_register_layer( S_PRINTER, SERVER, FALSE, NULL);
+
+ register_irlpt_server();
+
+#ifdef CONFIG_PROC_FS
+ proc_register( &proc_irda, &proc_irlpt_server);


+#endif /* CONFIG_PROC_FS */
+

+ DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+/*
+ * Function irlpt_cleanup (void)
+ *
+ *
+ *
+ */

+static void irlpt_server_cleanup(void)


+{
+ struct sk_buff *skb;
+

+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
+
+ deregister_irlpt_server();
+
+ while (( skb = skb_dequeue(&irlpt_server->rx_queue)) != NULL) {
+ DEBUG(irlpt_server_debug, __FUNCTION__ ": freeing SKB\n");
+ IS_SKB( skb, return;);
+ FREE_SKB_MAGIC( skb);


+ dev_kfree_skb( skb);
+ }
+

+ misc_deregister(&irlpt_server->ir_dev);
+
+ kfree(irlpt_server);
+
+#ifdef CONFIG_PROC_FS
+ proc_unregister( &proc_irda, proc_irlpt_server.low_ino);
+#endif
+
+ DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
+}
+
+/*
+ * Function irlpt_disconnect_indication (handle)
+ *
+ */
+static void irlpt_server_disconnect_indication( void *instance, void *sap,

+ LM_REASON reason,
+ struct sk_buff *userdata)

+{
+ struct irlpt_info info;


+ struct irlpt_cb *self;
+

+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
+
+ self = ( struct irlpt_cb *) instance;


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ info.daddr = self->daddr;
+
+ DEBUG( irlpt_server_debug, __FUNCTION__ ": reason=%d (%s), dlsap_sel=%d\n",
+ reason, irlpt_reasons[reason], self->dlsap_sel);
+
+ self->connected = IRLPT_DISCONNECTED;
+ self->eof = reason;
+
+ wake_up_interruptible(&irlpt_server_wait);
+
+ DEBUG( irlpt_server_debug, __FUNCTION__ ": skb_queue_len=%d\n",
+ skb_queue_len(&irlpt_server->rx_queue));
+
+ irlpt_server_do_event( self, LMP_DISCONNECT, NULL, NULL);
+
+ deregister_irlpt_server();
+ register_irlpt_server();
+
+ DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
+}
+
+/*
+ * Function irlpt_connect_confirm (handle, qos, skb)
+ *
+ * LSAP connection confirmed!
+ */
+static void irlpt_server_connect_confirm( void *instance, void *sap,

+ struct qos_info *qos,
+ int max_seg_size,
+ struct sk_buff *skb)

+{
+ struct irlpt_info info;


+ struct irlpt_cb *self;
+

+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
+ self = ( struct irlpt_cb *) instance;


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ info.daddr = self->daddr;
+
+ /*
+ * Check if we have got some QoS parameters back! This should be the
+ * negotiated QoS for the link.
+ */
+ if ( qos) {
+ DEBUG( irlpt_server_debug, __FUNCTION__
+ ": IrLPT Negotiated BAUD_RATE: %02x\n",
+ qos->baud_rate.bits);
+ DEBUG( irlpt_server_debug, __FUNCTION__
+ ": IrLPT Negotiated BAUD_RATE: %d bps.\n",
+ qos->baud_rate.value);
+ }
+
+ self->connected = TRUE;
+
+ irlpt_server_do_event( self, LMP_CONNECT, NULL, NULL);
+
+ DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
+}
+
+/*
+ * Function irlpt_connect_indication (handle)
+ *
+ */
+static void irlpt_server_connect_indication( void *instance, void *sap,

+ struct qos_info *qos,
+ int max_seg_size,
+ struct sk_buff *skb)

+{
+ struct irlpt_cb *self;

+ struct irlpt_info info;


+ struct lsap_cb *lsap;
+

+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
+
+ self = ( struct irlpt_cb *) instance;
+ lsap = (struct lsap_cb *) sap;


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ self->connected = IRLPT_CONNECTED;
+ self->eof = FALSE;
+
+ info.lsap = lsap;
+
+ irlpt_server_do_event( self, LMP_CONNECT, NULL, &info);
+
+ if (skb) {


+ dev_kfree_skb( skb);
+ }
+

+ DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
+}
+
+/*
+ * Function irlpt_data_indication (handle, skb)
+ *
+ * This function gets the data that is received on the data channel
+ *
+ */
+static void irlpt_server_data_indication( void *instance, void *sap,
+ struct sk_buff *skb)
+{


+
+ struct irlpt_cb *self;
+

+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
+
+ self = ( struct irlpt_cb *) instance;


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ ASSERT( skb != NULL, return;);
+
+ DEBUG( irlpt_server_debug, __FUNCTION__ ": len=%d\n", (int) skb->len);
+
+#if 0
+ dump_buffer(skb);
+#endif
+
+ skb_queue_tail(&self->rx_queue, skb);
+ wake_up_interruptible(&irlpt_server_wait);
+
+ DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
+}
+
+/*
+ * Function register_irlpt_server(void)
+ *
+ * Register server support so we can accept incoming connections. We
+ * must register both a TSAP for control and data
+ *
+ */
+static void register_irlpt_server(void)
+{
+ struct notify_t notify;
+ struct ias_object *obj;
+
+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
+
+ /*
+ * First register control TSAP
+ */
+
+ if ( !irlpt_server || irlpt_server->magic != IRLPT_MAGIC) {
+ DEBUG( 0, "irlpt_register_server:, unable to obtain handle!\n");
+ return;
+ }
+
+ irda_notify_init(&notify);
+
+ notify.connect_confirm = irlpt_server_connect_confirm;
+ notify.connect_indication = irlpt_server_connect_indication;
+ notify.disconnect_indication = irlpt_server_disconnect_indication;
+ notify.data_indication = irlpt_server_data_indication;
+ notify.instance = irlpt_server;
+ strcpy(notify.name, "IrLPT");
+
+ irlpt_server->lsap = irlmp_open_lsap( irlpt_server_lsap, &notify);
+
+ irlpt_server->connected = IRLPT_WAITING;
+ irlpt_server->service_LSAP = irlpt_server_lsap;
+
+ /*
+ * Register with LM-IAS
+ */
+
+ obj = irias_new_object("IrLPT", IAS_IRLPT_ID);
+ irias_add_integer_attrib(obj, "IrDA:IrLMP:LsapSel", irlpt_server_lsap);
+ irias_insert_object(obj);
+
+ DEBUG( irlpt_server_debug, __FUNCTION__
+ ": Source LSAP sel=%d\n", irlpt_server->slsap_sel);
+ DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
+}
+
+/*
+ * Function register_irlpt_server(void)
+ *
+ * Register server support so we can accept incoming connections. We
+ * must register both a TSAP for control and data
+ *
+ */
+static void deregister_irlpt_server(void)
+{
+#if 0
+ struct notify_t notify;
+#endif
+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
+
+#if 0
+ /*
+ * First register control TSAP
+ */
+
+ if ( !irlpt_server || irlpt_server->magic != IRLPT_MAGIC) {
+ DEBUG( 0, "irlpt_register_server:, unable to obtain handle!\n");
+ return;
+ }
+
+ irda_notify_init(&notify);
+
+ notify.connect_confirm = irlpt_server_connect_confirm;
+ notify.connect_indication = irlpt_server_connect_indication;
+ notify.disconnect_indication = irlpt_server_disconnect_indication;
+ notify.data_indication = irlpt_server_data_indication;
+ notify.instance = irlpt_server;
+ strcpy(notify.name, "IrLPT");
+
+ irlpt_server->lsap = irlmp_open_lsap( irlpt_server_lsap, &notify);
+
+ irlpt_server->connected = IRLPT_WAITING;
+ irlpt_server->service_LSAP = irlpt_server_lsap;
+#endif
+
+ /*
+ * de-Register with LM-IAS
+ */
+ irias_delete_object( "IrLPT");
+
+ DEBUG( irlpt_server_debug,
+ __FUNCTION__ ": Source LSAP sel=%d\n", irlpt_server->slsap_sel);
+ DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Thomas Davis <rat...@radiks.net>");
+MODULE_DESCRIPTION("The Linux IrDA/IrLPT protocol");
+
+/*
+ * Function init_module (void)
+ *
+ * Initialize the IrLPT server module, this function is called by the
+ * modprobe(1) program.


+ */
+int init_module(void)
+{
+

+ DEBUG( irlpt_server_debug, "--> irlpt server: init_module\n");
+
+ irlpt_server_init();
+
+ DEBUG( irlpt_server_debug, "irlpt server: init_module -->\n");


+
+ return 0;
+}
+

+/*
+ * Function cleanup_module (void)
+ *
+ * Remove the IrLPT server module, this function is called by the rmmod(1)
+ * program


+ */
+void cleanup_module(void)
+{

+ DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
+ DEBUG( 3, "--> irlpt server: cleanup_module\n");
+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+
+ /* Free some memory */
+ irlpt_server_cleanup();
+
+ DEBUG( irlpt_server_debug, "irlpt server: cleanup_module -->\n");
+}
+
+#endif /* MODULE */
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irlpt/irlpt_srvr_fsm.c linux/net/irda/irlpt/irlpt_srvr_fsm.c
--- v2.2.0-pre8/linux/net/irda/irlpt/irlpt_srvr_fsm.c Wed Dec 31 16:00:00 1969
+++ linux/net/irda/irlpt/irlpt_srvr_fsm.c Wed Jan 20 11:05:33 1999
@@ -0,0 +1,182 @@
+/*********************************************************************
+ *
+ * Filename: irlpt_srvr_fsm.c
+ * Version: 0.1
+ * Sources: irlan_event.c
+ *
+ * Copyright (c) 1997, Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
+ * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>, All Rights Reserved.


+ *
+ * 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.
+ *

+ * I, Thomas Davis, provide no warranty for any of this software. This
+ * material is provided "AS-IS" and at no charge.


+ *
+ ********************************************************************/
+

+#include <linux/config.h>
+
+#include <net/irda/iriap.h>
+#include <net/irda/irlmp.h>
+#include <net/irda/irttp.h>
+#include <net/irda/irlpt_common.h>
+#include <net/irda/irlpt_server.h>
+#include <net/irda/irlpt_server_fsm.h>
+#include <net/irda/irda.h>
+
+static int irlpt_server_state_idle ( struct irlpt_cb *self,
+ IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
+static int irlpt_server_state_conn ( struct irlpt_cb *self,
+ IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
+
+#if 0
+static char *rcsid = "$Id: irlpt_server_fsm.c,v 1.4 1998/10/05 05:46:45 ratbert Exp $";
+#endif
+
+int irlpt_server_fsm_debug = 3;
+
+static int (*irlpt_server_state[])( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info) =
+{
+ irlpt_server_state_idle,
+ irlpt_server_state_conn,
+};
+
+void irlpt_server_do_event( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb, struct irlpt_info *info)
+{
+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__ ": STATE = %s, EVENT = %s\n",
+ irlpt_server_fsm_state[self->state], irlpt_fsm_event[event]);
+


+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ (*irlpt_server_state[ self->state]) ( self, event, skb, info);
+
+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__ " -->\n");
+}
+
+void irlpt_server_next_state( struct irlpt_cb *self, IRLPT_CLIENT_STATE state)
+{
+
+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__ ": NEXT STATE = %s\n",
+ irlpt_server_fsm_state[state]);


+
+ ASSERT( self != NULL, return;);
+ ASSERT( self->magic == IRLPT_MAGIC, return;);

+
+ self->state = state;
+
+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__ " -->\n");
+}
+
+/*
+ * Function server_state_idle (event, skb, info)
+ *
+ * IDLE, We are waiting for an indication that there is a provider
+ * available.
+ */
+static int irlpt_server_state_idle( struct irlpt_cb *self, IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info)
+{
+ struct sk_buff *r_skb;
+
+ DEBUG( irlpt_server_fsm_debug, "--> " __FUNCTION__ ":\n");
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ switch( event) {
+ case LMP_CONNECT:
+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__
+ ": LM_CONNECT, remote lsap=%d\n",
+ info->dlsap_sel);
+
+ self->dlsap_sel = info->dlsap_sel;
+
+ r_skb = dev_alloc_skb(64);
+ if (r_skb == NULL) {
+ printk( KERN_INFO __FUNCTION__
+ ": can't allocate sk_buff of length 64\n");
+ return 0;
+ }
+ ALLOC_SKB_MAGIC(r_skb);
+ skb_reserve( r_skb, LMP_MAX_HEADER);
+ skb->len = 0;
+ irlmp_connect_response( self->lsap, r_skb);
+ irlpt_server_next_state( self, IRLPT_SERVER_CONN);
+
+ break;
+
+ default:
+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__
+ ": Unknown event %d (%s)\n",
+ event, irlpt_fsm_event[event]);
+ break;
+ }
+
+ if (skb) {


+ dev_kfree_skb( skb);
+ }
+

+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+/*
+ * Function server_state_conn (event, skb, info)
+ *
+ * CONN, We have connected to a provider but has not issued any
+ * commands yet.
+ *
+ */
+static int irlpt_server_state_conn( struct irlpt_cb *self,
+ IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info)
+{
+ DEBUG( irlpt_server_fsm_debug, "--> " __FUNCTION__ ":\n");
+
+ ASSERT( self != NULL, return -1;);
+ ASSERT( self->magic == IRLPT_MAGIC, return -1;);
+
+ switch( event) {
+ case LMP_DISCONNECT:
+ case LAP_DISCONNECT:
+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__
+ ": LMP_DISCONNECT/LAP_DISCONNECT\n");
+ irlpt_server_next_state( self, IRLPT_SERVER_IDLE);
+ break;
+
+ default:
+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__
+ ": Unknown event %d (%s)\n",
+ event, irlpt_fsm_event[event]);
+ break;
+ }
+
+ if ( skb) {


+ dev_kfree_skb( skb);
+ }
+

+ DEBUG( irlpt_server_fsm_debug, __FUNCTION__ " -->\n");


+
+ return 0;
+}
+

+#if 0
+static void irlpt_server_print_event( IRLPT_EVENT event)
+{
+ DEBUG( 0, "IRLPT_EVENT = %s\n", irlpt_fsm_event[event]);
+}
+#endif
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irmod.c linux/net/irda/irmod.c
--- v2.2.0-pre8/linux/net/irda/irmod.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irmod.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Mon Dec 15 13:55:39 1997
- * Modified at: Mon Dec 14 20:10:28 1998
+ * Modified at: Tue Jan 19 23:34:18 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1997 Dag Brattli, All Rights Reserved.
@@ -33,7 +33,11 @@
X #include <net/irda/iriap.h>
X #include <net/irda/irttp.h>
X
-struct irda irda; /* One global instance */
+struct irda_cb irda; /* One global instance */
+
+#ifdef CONFIG_IRDA_DEBUG
+__u32 irda_debug = IRDA_DEBUG;
+#endif
X
X extern void irda_proc_register(void);
X extern void irda_proc_unregister(void);
@@ -50,6 +54,8 @@
X extern int irlan_server_init(void);
X extern int ircomm_init(void);
X extern int irvtd_init(void);
+extern int irlpt_client_init(void);
+extern int irlpt_server_init(void);
X
X static int irda_open( struct inode * inode, struct file *file);
X static int irda_ioctl( struct inode *inode, struct file *filp,
@@ -99,6 +105,8 @@
X
X misc_register( &irda.dev);
X
+ irda.in_use = FALSE;
+
X /*
X * Initialize modules that got compiled into the kernel
X */
@@ -119,6 +127,14 @@
X irvtd_init();
X #endif
X
+#ifdef CONFIG_IRLPT_CLIENT
+ irlpt_client_init();
+#endif
+
+#ifdef CONFIG_IRLPT_SERVER
+ irlpt_server_init();
+#endif


+
X return 0;
X }
X

@@ -206,6 +222,12 @@
X struct irda_todo *new;
X struct irmanager_event event;
X
+ /* Make sure irmanager is running */
+ if ( !irda.in_use) {
+ printk( KERN_ERR "irmanager is not running!\n");
+ return;
+ }
+
X /* Make new todo event */
X new = (struct irda_todo *) kmalloc( sizeof(struct irda_todo),
X GFP_ATOMIC);
@@ -239,6 +261,12 @@


X
X DEBUG( 4, __FUNCTION__ "()\n");
X

+ /* Make sure irmanager is running */
+ if ( !irda.in_use) {
+ printk( KERN_ERR "irmanager is not running!\n");
+ return;
+ }
+
X /* Make new IrDA Event */
X new = (struct irda_event *) kmalloc( sizeof(struct irda_event),
X GFP_ATOMIC);
@@ -259,6 +287,12 @@


X {
X DEBUG( 4, __FUNCTION__ "()\n");
X

+ if ( irda.in_use) {
+ DEBUG( 0, __FUNCTION__ "(), irmanager is already running!\n");
+ return -1;
+ }
+ irda.in_use = TRUE;
+
X MOD_INC_USE_COUNT;
X
X return 0;
@@ -312,6 +346,8 @@
X DEBUG( 4, __FUNCTION__ "()\n");
X
X MOD_DEC_USE_COUNT;
+
+ irda.in_use = FALSE;
X
X return 0;
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irobex/irobex.c linux/net/irda/irobex/irobex.c
--- v2.2.0-pre8/linux/net/irda/irobex/irobex.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irobex/irobex.c Wed Jan 20 11:05:33 1999


@@ -1,12 +1,12 @@
X /*********************************************************************
X *

X * Filename: irobex.c


- * Version: 0.1
+ * Version: 0.3

X * Description: Kernel side of the IrOBEX layer


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Thu Jun 25 21:21:07 1998
- * Modified at: Mon Dec 14 11:56:26 1998
+ * Modified at: Sat Jan 16 22:18:03 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998 Dag Brattli, All Rights Reserved.

@@ -46,6 +46,14 @@
X */
X struct irobex_cb *irobex;
X
+char *irobex_state[] = {
+ "OBEX_IDLE",
+ "OBEX_DISCOVER",
+ "OBEX_QUERY",
+ "OBEX_CONN",
+ "OBEX_DATA",
+};
+
X static int irobex_dev_open( struct inode * inode, struct file *file);
X static int irobex_ioctl( struct inode *inode, struct file *filp,
X unsigned int cmd, unsigned long arg);
@@ -99,14 +107,12 @@
X {
X struct irobex_cb *self;
X
- DEBUG( 4, "--> " __FUNCTION__ "()\n");
-
X self = kmalloc(sizeof(struct irobex_cb), GFP_ATOMIC);
X if ( self == NULL)
X return -ENOMEM;
X
X memset( self, 0, sizeof(struct irobex_cb));
- sprintf( self->devname, "irobex%d", 1); /* Just one instance for now */
+ sprintf( self->devname, "irobex%d", 0); /* Just one instance for now */
X
X self->magic = IROBEX_MAGIC;
X self->rx_flow = self->tx_flow = FLOW_START;
@@ -121,8 +127,6 @@
X irobex = self;
X
X misc_register( &self->dev);
-
- irobex_register_server( self);
X
X #ifdef CONFIG_PROC_FS
X proc_register( &proc_irda, &proc_irobex);
@@ -131,8 +135,6 @@
X irlmp_register_layer( S_OBEX, CLIENT | SERVER, TRUE,
X irobex_discovery_indication);
X
- DEBUG( 4, "irobex_init -->\n");
-

X return 0;
X }
X

@@ -142,12 +144,13 @@
X * Removes the IrOBEX layer
X *
X */
+#ifdef MODULE
X void irobex_cleanup(void)


X {
X struct sk_buff *skb;

X struct irobex_cb *self;
X
- DEBUG( 4, "-->" __FUNCTION__ "()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X

X self = irobex;
X
@@ -170,9 +173,8 @@
X /*
X * Deallocate buffers
X */
- while (( skb = skb_dequeue( &self->rx_queue)) != NULL) {
+ while (( skb = skb_dequeue( &self->rx_queue)) != NULL)


X dev_kfree_skb( skb);
- }
X

X #ifdef CONFIG_PROC_FS
X proc_unregister( &proc_irda, proc_irobex.low_ino);
@@ -180,10 +182,9 @@
X
X misc_deregister( &self->dev);
X
- kfree( self);
-
- DEBUG( 4, __FUNCTION__ "() -->\n");
+ kfree( self);
X }
+#endif /* MODULE */
X
X /*
X * Function irobex_read (inode, file, buffer, count)
@@ -204,19 +205,24 @@
X ASSERT( self != NULL, return -EIO;);
X ASSERT( self->magic == IROBEX_MAGIC, return -EIO;);
X
- DEBUG( 4, __FUNCTION__ ": count=%d, skb_len=%d, conn.=%d, eof=%d\n",
- count, skb_queue_len( &self->rx_queue), self->connected,
+ DEBUG( 4, __FUNCTION__ ": count=%d, skb_len=%d, state=%s, eof=%d\n",
+ count, skb_queue_len( &self->rx_queue),
+ irobex_state[self->state],
X self->eof);
-
+
+ if ( self->state != OBEX_DATA) {
+ DEBUG( 0, __FUNCTION__ "(), link not connected yet!\n");
+ return -EIO;
+ }
+
X /*
- * Check if there is no data to return
+ * If there is data to return, then we return it. If not, then we
+ * must check if we are still connected
X */
X if ( skb_queue_len( &self->rx_queue) == 0) {
X
- /*
- * Disconnected yet?
- */
- if ( !self->connected) {
+ /* Still connected? */
+ if ( self->state != OBEX_DATA) {
X switch ( self->eof) {
X case LM_USER_REQUEST:


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 12'
echo 'File patch-2.2.0-pre9 is continued in part 13'
echo 13 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part13

#!/bin/sh
# this is part 13 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 13; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

X self->eof = FALSE;
@@ -243,7 +249,7 @@
X if ( file->f_flags & O_NONBLOCK)
X return -EAGAIN;
X
- /* * Go to sleep and wait for data! */
+ /* Go to sleep and wait for data! */
X interruptible_sleep_on( &self->read_wait);
X
X /*
@@ -266,7 +272,7 @@
X */
X if ( self->rx_flow == FLOW_STOP) {
X if ( skb_queue_len( &self->rx_queue) < LOW_THRESHOLD) {
- DEBUG( 0, __FUNCTION__ "(), Starting IrTTP\n");
+ DEBUG( 4, __FUNCTION__ "(), Starting IrTTP\n");
X self->rx_flow = FLOW_START;
X irttp_flow_request( self->tsap, FLOW_START);
X }
@@ -279,7 +285,7 @@
X if ( count < skb->len) {
X copy_to_user( buffer+len, skb->data, count);
X len += count;
-
+
X /*
X * Remove copied data from skb and queue
X * it for next read
@@ -323,34 +329,36 @@
X /*
X * If we are not connected then we just give up!
X */


- if ( !self->connected) {

+ if ( self->state != OBEX_DATA) {

X DEBUG( 0, __FUNCTION__ "(): Not connected!\n");
-
+
X return -ENOLINK;
X }
-
+
X /* Check if IrTTP is wants us to slow down */
X if ( self->tx_flow == FLOW_STOP) {


- DEBUG( 0, __FUNCTION__
+ DEBUG( 4, __FUNCTION__

X "(), IrTTP wants us to slow down, going to sleep\n");
X interruptible_sleep_on( &self->write_wait);
X }
X
X /* Send data to TTP layer possibly as muliple packets */
X while ( count) {
-
+
X /*
X * Check if request is larger than what fits inside a TTP
- * frame
+ * frame. In that case we must fragment the frame into
+ * multiple TTP frames. IrOBEX should not care about message
+ * boundaries.
X */
X if ( count < (self->irlap_data_size - IROBEX_MAX_HEADER))
X data_len = count;
X else
X data_len = self->irlap_data_size - IROBEX_MAX_HEADER;
-
+
X DEBUG( 4, __FUNCTION__ "(), data_len=%d, header_len = %d\n",
X data_len, IROBEX_MAX_HEADER);
-
+
X skb = dev_alloc_skb( data_len + IROBEX_MAX_HEADER);
X if ( skb == NULL) {
X DEBUG( 0, "irobex - couldn't allocate skbuff!\n");
@@ -363,10 +371,11 @@
X copy_from_user( skb->data, buffer+len, data_len);
X len += data_len;
X count -= data_len;
-
+
X DEBUG( 4, __FUNCTION__ "(), skb->len=%d\n", (int) skb->len);
X ASSERT( skb->len <= (self->irlap_data_size-IROBEX_MAX_HEADER),
X return len;);
+
X irttp_data_request( self->tsap, skb);
X }
X return (len);
@@ -433,7 +442,7 @@
X int err = 0;
X int size = _IOC_SIZE(cmd);
X
- DEBUG( 0, __FUNCTION__ "()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X
X self = irobex;
X

@@ -454,73 +463,73 @@
X
X switch ( cmd) {
X case IROBEX_IOCSCONNECT:
- DEBUG( 0, __FUNCTION__ "(): IROBEX_IOCSCONNECT!\n");
+ DEBUG( 4, __FUNCTION__ "(): IROBEX_IOCSCONNECT!\n");
X
X /* Already connected? */
- if ( self->connected)
+ if ( self->state == OBEX_DATA) {
+ DEBUG( 0, __FUNCTION__ "(), already connected!\n");
X return 0;
+ }
X
+ /* Timeout after 15 secs. */
+ irobex_start_watchdog_timer( self, 1000);
+
X /*
- * Wait until we have discovered a remote IrOBEX device
+ * If we have discovered a remote device we
+ * check if the discovery is still fresh. If not, we don't
+ * trust the address.
X */
- if (( self->daddr == 0) ||
- (( jiffies - self->time_discovered) > 500)) {
-
- if ( self->daddr != 0) {
- DEBUG( 0, __FUNCTION__ "(), daddr is old!\n");
- self->daddr = 0;
- }
+ if ( self->daddr && ((jiffies - self->time_discovered) > 500))
+ self->daddr = 0;
X
+ /*
+ * Try to discover remote remote device if it has not been
+ * discovered yet.
+ */
+ if ( !self->daddr) {
+ self->state = OBEX_DISCOVER;
+
X irlmp_discovery_request( 8);
- DEBUG( 0, __FUNCTION__
- "(): Sleep until device discovered\n");
X
- /* Timeout after 10 secs. */
- irobex_start_watchdog_timer( self, 1000);
- /*
- * Wait for discovery to complete
- */
- interruptible_sleep_on( &self->discover_wait);
- /* del_timer( &self->watchdog_timer); */
+ /* Wait for discovery to complete */
+ interruptible_sleep_on( &self->write_wait);
+ del_timer( &self->watchdog_timer);
X }
X
X /* Give up if we are unable to discover any remote devices */
- if ( self->daddr == 0) {
+ if ( !self->daddr) {
X DEBUG( 0, __FUNCTION__
X "(), Unable to discover any devices!\n");
X return -ENOTTY;
X }
X
X /* Need to find remote destination TSAP selector? */
- if ( self->dtsap_sel == 0) {
-
+ if ( !self->dtsap_sel) {
X DEBUG( 0, __FUNCTION__ "() : Quering remote IAS!\n");
X
+ self->state = OBEX_QUERY;
+
X /* Timeout after 5 secs. */
X irobex_start_watchdog_timer( self, 500);
- iriap_getvaluebyclass_request( self->daddr,
- "OBEX",
- "IrDA:TinyTP:LsapSel",
- irobex_get_value_confirm,
- self);
+ iriap_getvaluebyclass_request(
+ self->daddr,
+ "OBEX",
+ "IrDA:TinyTP:LsapSel",
+ irobex_get_value_confirm,
+ self);
X
- DEBUG( 0, __FUNCTION__ "(): Sleep until IAS answer\n");
- interruptible_sleep_on( &self->ias_wait);
- /* del_timer( &self->watchdog_timer); */
+ interruptible_sleep_on( &self->write_wait);
+ del_timer( &self->watchdog_timer);
X }
X
- if ( self->dtsap_sel == 0) {
+ if ( !self->dtsap_sel) {
X DEBUG( 0, __FUNCTION__
X "(), Unable to query remote LM-IAS!\n");
X return -ENOTTY;
X }
X
-
- /*
- * Try connect
- */
- DEBUG( 0, __FUNCTION__ "(): Connecting ...\n");
-
+ self->state = OBEX_CONN;
+
X /* Timeout after 5 secs. */
X irobex_start_watchdog_timer( self, 500);
X
@@ -528,31 +537,28 @@
X self->daddr, NULL, SAR_DISABLE,
X NULL);
X
- /*
- * Go to sleep and wait for connection!
- */
- DEBUG( 0, __FUNCTION__ "(): Waiting for connection!\n");
- interruptible_sleep_on( &self->connect_wait);
-
+ /* Go to sleep and wait for connection! */
+ interruptible_sleep_on( &self->write_wait);
X del_timer( &self->watchdog_timer);
X

- if ( !self->connected) {

+ if ( self->state != OBEX_DATA) {

X DEBUG( 0, __FUNCTION__
X "(), Unable to connect to remote device!\n");
X return -ENOTTY;
X }
-
+
X break;
X case IROBEX_IOCSDISCONNECT:
- DEBUG( 0, __FUNCTION__ "(): IROBEX_IOCSDISCONNECT!\n");


- if ( !self->connected)

+ DEBUG( 4, __FUNCTION__ "(): IROBEX_IOCSDISCONNECT!\n");
+


+ if ( self->state != OBEX_DATA)

X return 0;
X
X irttp_disconnect_request( self->tsap, NULL, P_NORMAL);
X
X /* Reset values for this instance */
- self->connected = FALSE;
- self->eof = 0;
+ self->state = OBEX_IDLE;
+ self->eof = LM_USER_REQUEST;
X self->daddr = 0;
X self->dtsap_sel = 0;
X self->rx_flow = FLOW_START;
@@ -569,14 +575,14 @@
X /*
X * Function irobex_dev_open (inode, file)
X *
- *
+ * Device opened by user process
X *
X */


X static int irobex_dev_open( struct inode * inode, struct file *file)

X {
X struct irobex_cb *self;
X

- DEBUG( 4, "open_irobex:\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X
X self = irobex;
X

@@ -589,18 +595,28 @@
X self->count--;
X return -EBUSY;
X }
-
+
+ irobex_register_server( self);
+
+ /* Reset values for this instance */
+ self->state = OBEX_IDLE;


+ self->eof = FALSE;

+ self->daddr = 0;
+ self->dtsap_sel = 0;
+ self->rx_flow = FLOW_START;
+ self->tx_flow = FLOW_START;


+
X MOD_INC_USE_COUNT;
X
X return 0;

X }
X
-static int irobex_dev_close( struct inode *inode, struct file *file)
+static int irobex_dev_close( struct inode *inode, struct file *file)


X {
X struct irobex_cb *self;

X struct sk_buff *skb;
X

- DEBUG( 4, "close_irobex()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X
X self = irobex;
X

@@ -613,11 +629,17 @@
X dev_kfree_skb( skb);
X }
X
- /* if ( self->tsap) { */
-/* irttp_close_tsap( self->tsap); */
-/* self->tsap = NULL; */
-/* self->connected = FALSE; */
-/* } */
+ /* Close TSAP is its still there */
+ if ( self->tsap) {
+ irttp_close_tsap( self->tsap);
+ self->tsap = NULL;
+ }
+ self->state = OBEX_IDLE;


+ self->eof = FALSE;

+ self->daddr = 0;
+ self->dtsap_sel = 0;
+ self->rx_flow = FLOW_START;
+ self->tx_flow = FLOW_START;
X
X /* Remove this filp from the asynchronously notified filp's */
X irobex_fasync( -1, file, 0);
@@ -647,16 +669,19 @@
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == IROBEX_MAGIC, return;);
X
+ /* Remember address and time if was discovered */
X self->daddr = discovery->daddr;
X self->time_discovered = jiffies;
X
- wake_up_interruptible( &self->discover_wait);
+ /* Wake up process if its waiting for device to be discovered */
+ if ( self->state == OBEX_DISCOVER)
+ wake_up_interruptible( &self->write_wait);
X }
X
X /*
X * Function irobex_disconnect_indication (handle, reason, priv)
X *
- *
+ * Link has been disconnected
X *
X */
X void irobex_disconnect_indication( void *instance, void *sap,
@@ -664,35 +689,27 @@


X {
X struct irobex_cb *self;
X

- DEBUG( 0, __FUNCTION__ "(), reason=%d\n", reason);
-
+ DEBUG( 4, __FUNCTION__ "(), reason=%d\n", reason);
+
X self = ( struct irobex_cb *) instance;
-
+
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == IROBEX_MAGIC, return;);
-
-/* save_flags(flags); */
-/* cli(); */
X
- self->connected = FALSE;
+ self->state = OBEX_IDLE;
X self->eof = reason;
X self->daddr = 0;
X self->dtsap_sel = 0;


X self->rx_flow = self->tx_flow = FLOW_START;

-
-/* restore_flags(flags); */
X
X wake_up_interruptible( &self->read_wait);
- wake_up_interruptible( &self->connect_wait);
X wake_up_interruptible( &self->write_wait);
X
- DEBUG( 4, "irobex_disconnect_indication: skb_queue_len=%d\n",
+ DEBUG( 4, __FUNCTION__ "(), skb_queue_len=%d\n",
X skb_queue_len( &irobex->rx_queue));
X
- if ( userdata) {
+ if ( userdata)
X dev_kfree_skb( userdata);
-
- }
X }
X
X /*
@@ -706,7 +723,7 @@


X {
X struct irobex_cb *self;
X

- DEBUG( 0, __FUNCTION__ "()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X

X self = ( struct irobex_cb *) instance;
X
@@ -714,18 +731,20 @@
X ASSERT( self->magic == IROBEX_MAGIC, return;);


X ASSERT( qos != NULL, return;);
X

- DEBUG( 0, __FUNCTION__ "(), IrLAP data size=%d\n",
+ DEBUG( 4, __FUNCTION__ "(), IrLAP data size=%d\n",
X qos->data_size.value);
X
X self->irlap_data_size = qos->data_size.value;
- self->connected = TRUE;
X
X /*
X * Wake up any blocked process wanting to write. Finally this process
X * can start writing since the connection is now open :-)
X */
- wake_up_interruptible( &self->connect_wait);
-
+ if (self->state == OBEX_CONN) {
+ self->state = OBEX_DATA;


+ wake_up_interruptible( &self->write_wait);
+ }
+

X if ( userdata) {
X dev_kfree_skb( userdata);
X
@@ -743,18 +762,16 @@
X struct sk_buff *skb;
X /* __u8 *frame; */
X
- DEBUG( 4, "irobex_connect_response()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X

X ASSERT( self != NULL, return;);
X ASSERT( self->magic == IROBEX_MAGIC, return;);
X
- self->connected = TRUE;
+ self->state = OBEX_DATA;
X

X skb = dev_alloc_skb( 64);
X if (skb == NULL) {

- DEBUG( 0,"irobex_connect_response: "


- "Could not allocate an sk_buff of length %d\n",

- 64);
+ DEBUG( 0, __FUNCTION__ "() Could not allocate sk_buff!\n");
X return;
X }
X
@@ -777,7 +794,7 @@
X struct irmanager_event mgr_event;


X struct irobex_cb *self;
X

- DEBUG( 0, "irobex_connect_indication()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X

X self = ( struct irobex_cb *) instance;
X
@@ -787,22 +804,23 @@
X
X self->eof = FALSE;
X
- DEBUG( 0, "irobex_connect_indication, skb_len = %d\n",
+ DEBUG( 4, __FUNCTION__ "(), skb_len = %d\n",
X (int) userdata->len);
X
- DEBUG( 0, __FUNCTION__ "(), IrLAP data size=%d\n",
+ DEBUG( 4, __FUNCTION__ "(), IrLAP data size=%d\n",
X qos->data_size.value);
X
X ASSERT( qos->data_size.value >= 64, return;);
X
X self->irlap_data_size = qos->data_size.value;
X
+ /* We just accept the connection */
X irobex_connect_response( self);
-
+#if 1
X mgr_event.event = EVENT_IROBEX_START;
X sprintf( mgr_event.devname, "%s", self->devname);
X irmanager_notify( &mgr_event);
-
+#endif
X wake_up_interruptible( &self->read_wait);
X
X if ( userdata) {
@@ -862,7 +880,7 @@


X {
X struct irobex_cb *self;
X

- DEBUG( 0, __FUNCTION__ "()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X

X self = ( struct irobex_cb *) instance;
X
@@ -877,7 +895,7 @@
X case FLOW_START:
X self->tx_flow = flow;
X DEBUG( 0, __FUNCTION__ "(), IrTTP wants us to start again\n");
- wake_up_interruptible( &self->discover_wait);
+ wake_up_interruptible( &self->write_wait);
X break;
X default:
X DEBUG( 0, __FUNCTION__ "(), Unknown flow command!\n");
@@ -895,7 +913,7 @@


X {
X struct irobex_cb *self;
X

- DEBUG( 4, "irobex_get_value_confirm()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X

X ASSERT( priv != NULL, return;);
X self = ( struct irobex_cb *) priv;
@@ -907,8 +925,7 @@
X
X switch ( value->type) {
X case IAS_INTEGER:
- DEBUG( 0, "irobex_get_value_confirm() int=%d\n",
- value->t.integer);
+ DEBUG( 4, __FUNCTION__ "() int=%d\n", value->t.integer);
X
X if ( value->t.integer != -1) {
X self->dtsap_sel = value->t.integer;
@@ -920,24 +937,22 @@
X * process that wants to make a connection, so we
X * just let that process do the connect itself
X */
- wake_up_interruptible( &self->ias_wait);
+ if ( self->state == OBEX_QUERY)
+ wake_up_interruptible( &self->write_wait);
X } else
X self->dtsap_sel = 0;
X break;
X case IAS_STRING:
- DEBUG( 0, "irlan_get_value_confirm(), got string %s\n",
- value->t.string);
+ DEBUG( 0, __FUNCTION__ "(), got string %s\n", value->t.string);
X break;
X case IAS_OCT_SEQ:
- DEBUG( 0, "irobex_get_value_confirm(), "
- "OCT_SEQ not implemented\n");
+ DEBUG( 0, __FUNCTION__ "(), OCT_SEQ not implemented\n");
X break;
X case IAS_MISSING:
- DEBUG( 0, "irobex_get_value_confirm(), "
- "MISSING not implemented\n");
+ DEBUG( 0, __FUNCTION__ "(), MISSING not implemented\n");
X break;
X default:
- DEBUG( 0, "irobex_get_value_confirm(), unknown type!\n");
+ DEBUG( 0, __FUNCTION__ "(), unknown type!\n");
X break;
X }
X }
@@ -1004,8 +1019,7 @@
X self->tsap = irttp_open_tsap( TSAP_IROBEX, DEFAULT_INITIAL_CREDIT,
X &notify);
X if ( self->tsap == NULL) {
- DEBUG( 0, "irobex_register_server(), "
- "Unable to allocate TSAP!\n");
+ DEBUG( 0, __FUNCTION__ "(), Unable to allocate TSAP!\n");
X return;
X }
X
@@ -1015,23 +1029,26 @@
X obj = irias_new_object( "OBEX", 0x42343);
X irias_add_integer_attrib( obj, "IrDA:TinyTP:LsapSel", TSAP_IROBEX);
X irias_insert_object( obj);
-
X }


X
X void irobex_watchdog_timer_expired( unsigned long data)

X {
X struct irobex_cb *self = ( struct irobex_cb *) data;
X
- DEBUG( 0, __FUNCTION__ "()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X

X ASSERT( self != NULL, return;);
X ASSERT( self->magic == IROBEX_MAGIC, return;);
X
- wake_up_interruptible( &self->discover_wait);
- wake_up_interruptible( &self->ias_wait);
- wake_up_interruptible( &self->connect_wait);
-
- /* irlmp_do_lsap_event( self, LM_WATCHDOG_TIMEOUT, NULL); */
+ switch (self->state) {
+ case OBEX_CONN: /* FALLTROUGH */
+ case OBEX_DISCOVER: /* FALLTROUGH */
+ case OBEX_QUERY: /* FALLTROUGH */
+ wake_up_interruptible( &self->write_wait);


+ break;
+ default:
+ break;
+ }

X }
X
X #ifdef CONFIG_PROC_FS
@@ -1053,8 +1070,7 @@
X len = 0;
X
X len += sprintf( buf+len, "ifname: %s ",self->devname);
- len += sprintf( buf+len, "connected: %s ",
- self->connected ? "TRUE": "FALSE");
+ len += sprintf( buf+len, "state: %s ", irobex_state[ self->state]);
X len += sprintf( buf+len, "EOF: %s\n", self->eof ? "TRUE": "FALSE");
X
X return len;
@@ -1075,12 +1091,8 @@
X */
X int init_module(void)
X {
- DEBUG( 4, "--> irobex: init_module\n");
-
X irobex_init();
X
- DEBUG( 4, "irobex: init_module -->\n");

-
X return 0;
X }
X

@@ -1092,15 +1104,12 @@
X */
X void cleanup_module(void)
X {
- DEBUG( 4, "--> irobex, cleanup_module\n");
X /*
X * No need to check MOD_IN_USE, as sys_delete_module() checks.
X */
X
X /* Free some memory */
- irobex_cleanup();
-
- DEBUG( 4, "irobex, cleanup_module -->\n");
+ irobex_cleanup();
X }
X
X #endif /* MODULE */
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irproc.c linux/net/irda/irproc.c
--- v2.2.0-pre8/linux/net/irda/irproc.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irproc.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.

X * Author: Thomas Davis, <rat...@radiks.net>
X * Created at: Sat Feb 21 21:33:24 1998
- * Modified at: Wed Dec 9 02:26:45 1998
+ * Modified at: Tue Dec 15 09:21:50 1998


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>,
@@ -330,7 +330,6 @@
X return len;
X
X len = sprintf(buf, "IrLMP: Discovery log:\n\n");
-


X
X save_flags(flags);
X cli();

diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irqueue.c linux/net/irda/irqueue.c
--- v2.2.0-pre8/linux/net/irda/irqueue.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irqueue.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Tue Jun 9 13:29:31 1998
- * Modified at: Mon Dec 14 20:11:07 1998
+ * Modified at: Wed Jan 13 21:21:22 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (C) 1998, Aage Kvalnes <aa...@cs.uit.no>
@@ -49,7 +49,7 @@
X {
X hashbin_t* hashbin;
X
- DEBUG( 4, "hashbin_create()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X

X /*
X * Allocate new hashbin
@@ -353,19 +353,19 @@
X }
X
X
-/*
- * Function hashbin_remove (hashbin, name)
+/*
+ * Function hashbin_remove (hashbin, hashv, name)
X *
X * Remove entry with the given name
X *
X */
X void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name)
X {
- int bin, found = FALSE;
+ int bin, found = FALSE;
X unsigned long flags = 0;
X QUEUE* entry;
X
- DEBUG( 4, "hashbin_remove()\n");


+ DEBUG( 4, __FUNCTION__ "()\n");
X

X ASSERT( hashbin != NULL, return NULL;);
X ASSERT( hashbin->magic == HB_MAGIC, return NULL;);
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irsysctl.c linux/net/irda/irsysctl.c
--- v2.2.0-pre8/linux/net/irda/irsysctl.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/irsysctl.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun May 24 22:12:06 1998
- * Modified at: Wed Dec 9 01:29:22 1998
+ * Modified at: Thu Jan 7 10:35:02 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1997 Dag Brattli, All Rights Reserved.

@@ -27,13 +27,19 @@
X #include <linux/sysctl.h>
X #include <asm/segment.h>
X
+#include <net/irda/irda.h>
+
X #define NET_IRDA 412 /* Random number */
-enum { DISCOVERY=1, DEVNAME, COMPRESSION };
+enum { DISCOVERY=1, DEVNAME, COMPRESSION, DEBUG };
X
X extern int sysctl_discovery;
X int sysctl_compression = 0;
X extern char sysctl_devname[];
X
+#ifdef CONFIG_IRDA_DEBUG
+extern unsigned int irda_debug;
+#endif
+
X /* One file */
X static ctl_table irda_table[] = {
X { DISCOVERY, "discovery", &sysctl_discovery,
@@ -42,6 +48,10 @@
X 65, 0644, NULL, &proc_dostring, &sysctl_string},
X { COMPRESSION, "compression", &sysctl_compression,
X sizeof(int), 0644, NULL, &proc_dointvec },
+#ifdef CONFIG_IRDA_DEBUG
+ { DEBUG, "debug", &irda_debug,
+ sizeof(int), 0644, NULL, &proc_dointvec },
+#endif
X { 0 }
X };
X
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/irttp.c linux/net/irda/irttp.c
--- v2.2.0-pre8/linux/net/irda/irttp.c Wed Jan 13 15:00:44 1999
+++ linux/net/irda/irttp.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun Aug 31 20:14:31 1997
- * Modified at: Mon Dec 14 11:53:19 1998
+ * Modified at: Tue Jan 19 23:56:58 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,
@@ -290,8 +290,6 @@
X ASSERT( self->magic == TTP_TSAP_MAGIC, return -1;);
X ASSERT( skb != NULL, return -1;);
X
- IS_SKB( skb, return -1;);
-
X /* Check that nothing bad happens */
X if (( skb->len == 0) || ( !self->connected)) {
X DEBUG( 4, __FUNCTION__ "(), No data, or not connected\n");
@@ -1044,12 +1042,12 @@
X DEBUG( 4, "irttp_disconnect_indication()\n");
X
X self = ( struct tsap_cb *) instance;
-
+
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == TTP_TSAP_MAGIC, return;);
-
+
X self->connected = FALSE;
-
+
X /*
X * Use callback to notify layer above
X */
@@ -1207,7 +1205,6 @@
X {
X struct sk_buff *skb, *frag;
X int n = 0; /* Fragment index */
- int i = 1; /* Fragment nr */
X
X ASSERT( self != NULL, return NULL;);
X ASSERT( self->magic == TTP_TSAP_MAGIC, return NULL;);
@@ -1227,11 +1224,9 @@
X * Copy all fragments to a new buffer
X */
X while (( frag = skb_dequeue( &self->rx_fragments)) != NULL) {
- DEBUG( 4, __FUNCTION__ "(), copying fragment %d with len=%d\n",
- i++, (int) frag->len);
X memcpy( skb->data+n, frag->data, frag->len);
X n += frag->len;
-
+
X dev_kfree_skb( frag);
X }
X DEBUG( 4, __FUNCTION__ "(), frame len=%d\n", n);
@@ -1256,7 +1251,6 @@
X {
X struct sk_buff *frag;
X __u8 *frame;
- int i = 0;


X
X DEBUG( 4, __FUNCTION__ "()\n");
X

@@ -1306,10 +1300,6 @@
X /* Hide the copied data from the original skb */
X skb_pull( skb, self->max_seg_size);
X
- /* Queue segment */
- DEBUG( 4, __FUNCTION__ "(), queuing segment %d with len=%d\n",
- i++, (int) frag->len);
-
X skb_queue_tail( &self->tx_queue, frag);
X }
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/net/irda/wrapper.c linux/net/irda/wrapper.c
--- v2.2.0-pre8/linux/net/irda/wrapper.c Tue Dec 22 14:16:59 1998
+++ linux/net/irda/wrapper.c Wed Jan 20 11:05:33 1999


@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Mon Aug 4 20:40:53 1997
- * Modified at: Wed Dec 9 01:35:53 1998
+ * Modified at: Sat Jan 16 22:05:45 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,
@@ -110,18 +110,16 @@
X #endif
X tx_buff[n++] = EOF;
X
- DEBUG( 6, "async_wrap() -->\n");
-
X return n;
X }
X
X /*
- * Function async_bump (irdev)
+ * Function async_bump (idev)
X *
X * Got a frame, make a copy of it, and pass it up the stack!
X *
X */
-static __inline__ void async_bump( struct irda_device *irdev, __u8 *buf,
+static __inline__ void async_bump( struct irda_device *idev, __u8 *buf,
X int len)


X {
X struct sk_buff *skb;

@@ -130,36 +128,31 @@


X if (skb == NULL) {

X printk( KERN_INFO __FUNCTION__ "() memory squeeze, "
X "dropping frame.\n");
- irdev->stats.rx_dropped++;
+ idev->stats.rx_dropped++;
X return;
X }
X
X /* Align to 20 bytes */
X skb_reserve( skb, 1);
X
- /* For finding out how much time we use to
- send a frame */
- do_gettimeofday( &skb->stamp);
-
X ASSERT( len-2 > 0, return;);
X
X /* Copy data without CRC */
X skb_put( skb, len-2);
X memcpy( skb->data, buf, len-2);
X
- irdev->rx_buff.len = 0;
+ idev->rx_buff.len = 0;
X /*
X * Feed it to IrLAP layer
X */
X /* memcpy(skb_put(skb,count), ax->rbuff, count); */
- skb->dev = &irdev->netdev;


+ skb->dev = &idev->netdev;

X skb->mac.raw = skb->data;
X skb->protocol = htons(ETH_P_IRDA);
X
X netif_rx( skb);
- irdev->stats.rx_packets++;
-
- /* irlap_input( skb, skb->dev, NULL); */
+ idev->stats.rx_packets++;
+ idev->stats.rx_bytes += skb->len;
X }
X
X /*
@@ -168,18 +161,16 @@
X * Parse and de-stuff frame received from the IR-port
X *
X */
-void async_unwrap_char( struct irda_device *irdev, __u8 byte)
+void async_unwrap_char( struct irda_device *idev, __u8 byte)
X {
- DEBUG( 6, "async_unwrap()\n");
-
X /* State machine for receiving frames */
- switch( irdev->rx_buff.state) {
+ switch( idev->rx_buff.state) {
X case OUTSIDE_FRAME:
X if ( byte == BOF) {
- irdev->rx_buff.state = BEGIN_FRAME;
- irdev->rx_buff.in_frame = TRUE;
+ idev->rx_buff.state = BEGIN_FRAME;
+ idev->rx_buff.in_frame = TRUE;
X } else if ( byte == EOF) {
- irda_device_set_media_busy( irdev, TRUE);
+ irda_device_set_media_busy( idev, TRUE);
X }
X break;
X case BEGIN_FRAME:
@@ -189,20 +180,22 @@
X break;
X case CE:
X /* Stuffed byte */
- irdev->rx_buff.state = LINK_ESCAPE;
+ idev->rx_buff.state = LINK_ESCAPE;
X break;
X case EOF:
X /* Abort frame */
- DEBUG( 0, "Frame abort (1)\n");
- irdev->rx_buff.state = OUTSIDE_FRAME;
+ idev->rx_buff.state = OUTSIDE_FRAME;
+
+ idev->stats.rx_errors++;
+ idev->stats.rx_frame_errors++;
X break;
X default:
X /* Got first byte of frame */
- if ( irdev->rx_buff.len < irdev->rx_buff.truesize) {
- irdev->rx_buff.data[ irdev->rx_buff.len++] = byte;
+ if ( idev->rx_buff.len < idev->rx_buff.truesize) {
+ idev->rx_buff.data[ idev->rx_buff.len++] = byte;
X
- irdev->rx_buff.fcs = IR_FCS ( INIT_FCS, byte);
- irdev->rx_buff.state = INSIDE_FRAME;
+ idev->rx_buff.fcs = IR_FCS( INIT_FCS, byte);
+ idev->rx_buff.state = INSIDE_FRAME;
X } else
X printk( "Rx buffer overflow\n");
X break;
@@ -213,9 +206,9 @@
X case BOF:
X /* New frame? */
X DEBUG( 4, "New frame?\n");
- irdev->rx_buff.state = BEGIN_FRAME;
- irdev->rx_buff.len = 0;
- irda_device_set_media_busy( irdev, TRUE);
+ idev->rx_buff.state = BEGIN_FRAME;
+ idev->rx_buff.len = 0;
+ irda_device_set_media_busy( idev, TRUE);
X break;
X case CE:
X DEBUG( 4, "WARNING: State not defined\n");
@@ -223,8 +216,8 @@
X case EOF:
X /* Abort frame */
X DEBUG( 0, "Abort frame (2)\n");
- irdev->rx_buff.state = OUTSIDE_FRAME;
- irdev->rx_buff.len = 0;
+ idev->rx_buff.state = OUTSIDE_FRAME;
+ idev->rx_buff.len = 0;
X break;
X default:
X /*
@@ -232,11 +225,11 @@
X * following CE, IrLAP p.114
X */
X byte ^= IR_TRANS;
- if ( irdev->rx_buff.len < irdev->rx_buff.truesize) {
- irdev->rx_buff.data[ irdev->rx_buff.len++] = byte;
+ if ( idev->rx_buff.len < idev->rx_buff.truesize) {
+ idev->rx_buff.data[ idev->rx_buff.len++] = byte;
X
- irdev->rx_buff.fcs = IR_FCS( irdev->rx_buff.fcs, byte);
- irdev->rx_buff.state = INSIDE_FRAME;
+ idev->rx_buff.fcs = IR_FCS( idev->rx_buff.fcs, byte);
+ idev->rx_buff.state = INSIDE_FRAME;
X } else
X printk( "Rx buffer overflow\n");
X break;
@@ -246,41 +239,40 @@
X switch ( byte) {
X case BOF:
X /* New frame? */
- DEBUG( 4, "New frame?\n");
- irdev->rx_buff.state = BEGIN_FRAME;
- irdev->rx_buff.len = 0;
- irda_device_set_media_busy( irdev, TRUE);
+ idev->rx_buff.state = BEGIN_FRAME;
+ idev->rx_buff.len = 0;
+ irda_device_set_media_busy( idev, TRUE);
X break;
X case CE:
X /* Stuffed char */
- irdev->rx_buff.state = LINK_ESCAPE;
+ idev->rx_buff.state = LINK_ESCAPE;
X break;
X case EOF:
X /* End of frame */
- irdev->rx_buff.state = OUTSIDE_FRAME;
- irdev->rx_buff.in_frame = FALSE;
+ idev->rx_buff.state = OUTSIDE_FRAME;
+ idev->rx_buff.in_frame = FALSE;
X
X /*
X * Test FCS and deliver frame if it's good
X */
- if ( irdev->rx_buff.fcs == GOOD_FCS) {
- async_bump( irdev, irdev->rx_buff.data,
- irdev->rx_buff.len);
+ if ( idev->rx_buff.fcs == GOOD_FCS) {
+ async_bump( idev, idev->rx_buff.data,
+ idev->rx_buff.len);
X } else {
- /*
- * Wrong CRC, discard frame!
- */
- DEBUG( 0, "Received frame has wrong CRC\n");
- irda_device_set_media_busy( irdev, TRUE);
- irdev->rx_buff.len = 0;
+ /* Wrong CRC, discard frame! */
+ irda_device_set_media_busy( idev, TRUE);
+ idev->rx_buff.len = 0;
+
+ idev->stats.rx_errors++;
+ idev->stats.rx_crc_errors++;


X }
X break;
X default:

X /* Next byte of frame */
- if ( irdev->rx_buff.len < irdev->rx_buff.truesize) {
- irdev->rx_buff.data[ irdev->rx_buff.len++] = byte;
+ if ( idev->rx_buff.len < idev->rx_buff.truesize) {
+ idev->rx_buff.data[ idev->rx_buff.len++] = byte;
X
- irdev->rx_buff.fcs = IR_FCS( irdev->rx_buff.fcs, byte);
+ idev->rx_buff.fcs = IR_FCS( idev->rx_buff.fcs, byte);
X } else
X printk( "Rx buffer overflow\n");
X break;
diff -u --recursive --new-file v2.2.0-pre8/linux/net/sunrpc/xprt.c linux/net/sunrpc/xprt.c
--- v2.2.0-pre8/linux/net/sunrpc/xprt.c Tue Jan 19 11:32:53 1999
+++ linux/net/sunrpc/xprt.c Wed Jan 20 13:44:53 1999
@@ -655,10 +655,7 @@
X reclen = ntohl(xprt->tcp_reclen);
X dprintk("RPC: reclen %08x\n", reclen);
X xprt->tcp_more = (reclen & 0x80000000)? 0 : 1;
- if (!(reclen &= 0x7fffffff)) {
- printk(KERN_NOTICE "RPC: empty TCP record.\n");
- return -ENOTCONN; /* break connection */
- }
+ reclen &= 0x7fffffff;
X xprt->tcp_total += reclen;
X xprt->tcp_reclen = reclen;
X
diff -u --recursive --new-file v2.2.0-pre8/linux/scripts/tkcond.c linux/scripts/tkcond.c
--- v2.2.0-pre8/linux/scripts/tkcond.c Mon Jan 4 15:08:18 1999
+++ linux/scripts/tkcond.c Wed Jan 20 10:05:49 1999
@@ -1,544 +1,359 @@
-/* parser config.in
- *
- * Version 1.0
- * Eric Youngdale
- * 10/95
- *
- * The general idea here is that we want to parse a config.in file and
- * from this, we generate a wish script which gives us effectively the
- * same functionality that the original config.in script provided.
- *
- * This task is split roughly into 3 parts. The first parse is the parse
- * of the input file itself. The second part is where we analyze the
- * #ifdef clauses, and attach a linked list of tokens to each of the
- * menu items. In this way, each menu item has a complete list of
- * dependencies that are used to enable/disable the options.
- * The third part is to take the configuration database we have build,
- * and build the actual wish script.
- *
- * This file contains the code to further process the conditions from
- * the "ifdef" clauses.
+/*
+ * tkcond.c
X *
- * The conditions are assumed to be one of the following formats
+ * Eric Youngdale was the original author of xconfig.
+ * Michael Elizabeth Chastain (m...@shout.net) is the current maintainer.
X *
- * simple_condition:= "$VARIABLE" == y/n/m
- * simple_condition:= "$VARIABLE != y/n/m
+ * This file takes the tokenized statement list and transforms 'if ...'
+ * statements. For each simple statement, I find all of the 'if' statements
+ * that enclose it, and attach the aggregate conditionals of those 'if'
+ * statements to the cond list of the simple statement.
X *
- * simple_condition -a simple_condition
+ * 14 January 1999, Michael Elizabeth Chastain, <m...@shout.net>
+ * - Steam-clean this file. I tested this by generating kconfig.tk for
+ * every architecture and comparing it character-for-character against
+ * the output of the old tkparse.
X *
- * If the input condition contains '(' or ')' it would screw us up, but for now
- * this is not a problem.
+ * TO DO:
+ * - xconfig is at the end of its life cycle. Contact <m...@shout.net> if
+ * you are interested in working on the replacement.
X */
-#include <stdlib.h>
+
X #include <stdio.h>
+#include <stdlib.h>
X #include <string.h>
-#include "tkparse.h"
-
-
-/*
- * Walk a condition chain and invert it so that the logical result is
- * inverted.
- */
-static void invert_condition(struct condition * cnd)
-{
- /*
- * This is simple. Just walk through the list, and invert
- * all of the operators.
- */
- for(;cnd; cnd = cnd->next)
- {
- switch(cnd->op)
- {
- case op_and:
- cnd->op = op_or;
- break;
- case op_or:
- /*
- * This is not turned into op_and - we need to keep track
- * of what operators were used here since we have an optimization
- * later on to remove duplicate conditions, and having
- * inverted ors in there would make it harder if we did not
- * distinguish an inverted or from an and we inserted because
- * of nested ifs.
- */
- cnd->op = op_and1;
- break;
- case op_neq:
- cnd->op = op_eq;
- break;
- case op_eq:
- cnd->op = op_neq;
- break;
- default:
- break;
- }
- }
-}
X
-/*
- * Walk a condition chain, and free the memory associated with it.
- */
-static void free_condition(struct condition * cnd)
-{
- struct condition * next;
- for(;cnd; cnd = next)
- {
- next = cnd->next;
+#include "tkparse.h"
X
- if( cnd->variable.str != NULL )
- free(cnd->variable.str);
X
- free(cnd);
- }
-}
X
X /*
- * Walk all of the conditions, and look for choice values. Convert
- * the tokens into something more digestible.
+ * Transform op_variable to op_kvariable.
+ *
+ * This works, but it's gross, speed-wise. It would benefit greatly
+ * from a simple hash table that maps names to cfg.
+ *
+ * Note well: this is actually better than the loop structure xconfig
+ * has been staggering along with for three years, which performs
+ * this whole procedure inside *another* loop on active conditionals.
X */
-void fix_choice_cond(void)
+void transform_to_kvariable( struct kconfig * scfg )
X {
- struct condition * cond;
- struct condition * cond2;
- struct kconfig * cfg;
- char tmpbuf[255];
+ struct kconfig * cfg;
X
- for(cfg = config;cfg != NULL; cfg = cfg->next)
+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {
- if( cfg->cond == NULL )
- {
- continue;
- }
+ struct condition * cond;
X
- for(cond = cfg->cond; cond != NULL; cond = cond->next)
+ for ( cond = cfg->cond; cond != NULL; cond = cond->next )
X {
- if( cond->op != op_kvariable )
- continue;
-
- if( cond->variable.cfg->tok != tok_choice )
- continue;
-
- /*
- * Look ahead for what we are comparing this to. There should
- * be one operator in between.
- */
- cond2 = cond->next->next;
- strcpy(tmpbuf, cond->variable.cfg->label);
-
- if( strcmp(cond2->variable.str, "y") == 0 )
+ if ( cond->op == op_variable )
X {
- cond->variable.cfg = cond->variable.cfg->choice_label;
- cond2->variable.str = strdup(tmpbuf);
+ /* Here's where it gets DISGUSTING. */
+ struct kconfig * cfg1;
+
+ for ( cfg1 = scfg; cfg1 != NULL; cfg1 = cfg1->next )
+ {
+ if ( cfg1->token == token_bool
+ || cfg1->token == token_choice_item
+ || cfg1->token == token_dep_tristate
+ || cfg1->token == token_hex
+ || cfg1->token == token_int
+ || cfg1->token == token_string
+ || cfg1->token == token_tristate )
+ {
+ if ( strcmp( cond->str, cfg1->optionname ) == 0 )
+ {
+ cond->op = op_kvariable;
+ cond->str = NULL;
+ cond->cfg = cfg1;


+ break;
+ }
+ }
+ }

X }
- else


+
+#if 0
+ /*

+ * Maybe someday this will be useful, but right now it
+ * gives a lot of false positives on files like
+ * drivers/video/Config.in that are meant for more
+ * than one architecture. Turn it on if you want to play
+ * with it though; it does work. -- mec
+ */
+ if ( cond->op == op_variable )
X {
- fprintf(stderr,"tkparse can't handle this conditional\n");
- exit(1);
+ if ( strcmp( cond->str, "ARCH" ) != 0
+ && strcmp( cond->str, "CONSTANT_Y" ) != 0
+ && strcmp( cond->str, "CONSTANT_M" ) != 0
+ && strcmp( cond->str, "CONSTANT_N" ) != 0 )
+ {
+ fprintf( stderr, "warning: $%s used but not defined\n",
+ cond->str );
+ }
X }
+#endif
X }
-
X }
X }
X
+
+
X /*
- * Walk the stack of conditions, and clone all of them with "&&" operators
- * gluing them together. The conditions from each level of the stack
- * are wrapped in parenthesis so as to guarantee that the results
- * are logically correct.
+ * Make a new condition chain by joining the current condition stack with
+ * the "&&" operator for glue.
X */
-struct condition * get_token_cond(struct condition ** cond, int depth)
+struct condition * join_condition_stack( struct condition * conditions [],
+ int depth )
X {
- int i;
- struct condition * newcond;
- struct condition * tail;
- struct condition * new;
- struct condition * ocond;
- struct kconfig * cfg;
+ struct condition * cond_list;
+ struct condition * cond_last;
+ int i;
X
- newcond = tail = NULL;
- for(i=0; i<depth; i++, cond++)
+ cond_list = cond_last = NULL;
+ for ( i = 0; i < depth; i++ )
X {
- /*
- * First insert the left parenthesis
- */
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = op_lparen;
- if( tail == NULL )
- {
- newcond = tail = new;
- }
- else
- {
- tail->next = new;
- tail = new;
+ struct condition * cond;
+ struct condition * cnew;
+
+ /* add a '(' */
+ cnew = malloc( sizeof(*cnew) );
+ memset( cnew, 0, sizeof(*cnew) );
+ cnew->op = op_lparen;
+ if ( cond_last == NULL )
+ { cond_list = cond_last = cnew; }
+ else
+ { cond_last->next = cnew; cond_last = cnew; }
+
+ /* duplicate the chain */
+ for ( cond = conditions [i]; cond != NULL; cond = cond->next )
+ {
+ cnew = malloc( sizeof(*cnew) );
+ cnew->next = NULL;
+ cnew->op = cond->op;
+ cnew->str = cond->str ? strdup( cond->str ) : NULL;
+ cnew->cfg = cond->cfg;
+ cond_last->next = cnew;
+ cond_last = cnew;
+ }
+
+ /* add a ')' */
+ cnew = malloc( sizeof(*cnew) );
+ memset( cnew, 0, sizeof(*cnew) );
+ cnew->op = op_rparen;
+ cond_last->next = cnew;
+ cond_last = cnew;
+
+ /* if i have another condition, add an '&&' operator */
+ if ( i < depth - 1 )
+ {
+ cnew = malloc( sizeof(*cnew) );
+ memset( cnew, 0, sizeof(*cnew) );
+ cnew->op = op_and;
+ cond_last->next = cnew;
+ cond_last = cnew;
X }
+ }
X
- /*
- * Now duplicate the chain.
- */
- ocond = *cond;
- for(;ocond != NULL; ocond = ocond->next)
+ /*
+ * Remove duplicate conditions.
+ */
+ {
+ struct condition *cond1, *cond1b, *cond1c, *cond1d, *cond1e, *cond1f;
+
+ for ( cond1 = cond_list; cond1 != NULL; cond1 = cond1->next )
X {
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = ocond->op;
- if( ocond->variable.str != NULL )
+ if ( cond1->op == op_lparen )
X {
- if( ocond->op == op_variable )
+ cond1b = cond1 ->next; if ( cond1b == NULL ) break;
+ cond1c = cond1b->next; if ( cond1c == NULL ) break;
+ cond1d = cond1c->next; if ( cond1d == NULL ) break;
+ cond1e = cond1d->next; if ( cond1e == NULL ) break;
+ cond1f = cond1e->next; if ( cond1f == NULL ) break;
+
+ if ( cond1b->op == op_kvariable
+ && ( cond1c->op == op_eq || cond1c->op == op_neq )
+ && cond1d->op == op_constant
+ && cond1e->op == op_rparen )
X {
- /*
- * Search for structure to insert here.
- */
- for(cfg = config;cfg != NULL; cfg = cfg->next)
+ struct condition *cond2, *cond2b, *cond2c, *cond2d, *cond2e, *cond2f;
+
+ for ( cond2 = cond1f->next; cond2 != NULL; cond2 = cond2->next )
X {
- if( cfg->tok != tok_bool
- && cfg->tok != tok_int
- && cfg->tok != tok_hex
- && cfg->tok != tok_string
- && cfg->tok != tok_tristate
- && cfg->tok != tok_choice
- && cfg->tok != tok_dep_tristate)
+ if ( cond2->op == op_lparen )
X {
- continue;
+ cond2b = cond2 ->next; if ( cond2b == NULL ) break;
+ cond2c = cond2b->next; if ( cond2c == NULL ) break;
+ cond2d = cond2c->next; if ( cond2d == NULL ) break;
+ cond2e = cond2d->next; if ( cond2e == NULL ) break;
+ cond2f = cond2e->next;
+
+ /* look for match */
+ if ( cond2b->op == op_kvariable
+ && cond2b->cfg == cond1b->cfg
+ && cond2c->op == cond1c->op
+ && cond2d->op == op_constant
+ && strcmp( cond2d->str, cond1d->str ) == 0
+ && cond2e->op == op_rparen )
+ {
+ /* one of these must be followed by && */
+ if ( cond1f->op == op_and
+ || ( cond2f != NULL && cond2f->op == op_and ) )
+ {
+ /* nuke the first duplicate */
+ cond1 ->op = op_nuked;
+ cond1b->op = op_nuked;
+ cond1c->op = op_nuked;
+ cond1d->op = op_nuked;
+ cond1e->op = op_nuked;
+ if ( cond1f->op == op_and )
+ cond1f->op = op_nuked;
+ else
+ cond2f->op = op_nuked;
+ }
+ }
X }
- if( strcmp(cfg->optionname, ocond->variable.str) == 0)
- {
- new->variable.cfg = cfg;
- new->op = op_kvariable;
- break;
- }
- }
- if( cfg == NULL )
- {
- new->variable.str = strdup(ocond->variable.str);
X }
X }
- else
- {
- new->variable.str = strdup(ocond->variable.str);
- }
X }
- tail->next = new;
- tail = new;
X }
-
- /*
- * Next insert the left parenthesis
- */
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = op_rparen;
- tail->next = new;
- tail = new;
-
- /*
- * Insert an and operator, if we have another condition.
- */
- if( i < depth - 1 )
- {
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = op_and;
- tail->next = new;
- tail = new;
- }
-
X }
X
- return newcond;
+ return cond_list;
X }
X
-/*
- * Walk a single chain of conditions and clone it. These are assumed
- * to be created/processed by get_token_cond in a previous pass.
- */
-struct condition * get_token_cond_frag(struct condition * cond,
- struct condition ** last)
-{
- struct condition * newcond;
- struct condition * tail;
- struct condition * new;
- struct condition * ocond;
-
- newcond = tail = NULL;
-
- /*
- * Now duplicate the chain.
- */
- for(ocond = cond;ocond != NULL; ocond = ocond->next)
- {
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = ocond->op;
- new->variable.cfg = ocond->variable.cfg;
- if( tail == NULL )
- {
- newcond = tail = new;
- }
- else
- {
- tail->next = new;
- tail = new;
- }
- }
X
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = op_and;
- tail->next = new;
- tail = new;
-
- *last = tail;
- return newcond;
-}
X
X /*
- * Walk through the if conditionals and maintain a chain.
+ * This is the main transformation function.
X */
-void fix_conditionals(struct kconfig * scfg)
+void fix_conditionals( struct kconfig * scfg )
X {
- int depth = 0;
- int i;
- struct kconfig * cfg;
- struct kconfig * cfg1;
- struct condition * conditions[25];
- struct condition * cnd;
- struct condition * cnd1;
- struct condition * cnd2;
- struct condition * cnd3;
- struct condition * newcond;
- struct condition * last;
-
- /*
- * Start by walking the chain. Every time we see an ifdef, push
- * the condition chain on the stack. When we see an "else", we invert
- * the condition at the top of the stack, and when we see an "endif"
- * we free all of the memory for the condition at the top of the stack
- * and remove the condition from the top of the stack.
- *
- * For any other type of token (i.e. a bool), we clone a new condition chain
- * by anding together all of the conditions that are currently stored on
- * the stack. In this way, we have a correct representation of whatever
- * conditions govern the usage of each option.
- */
- memset(conditions, 0, sizeof(conditions));
- for(cfg=scfg;cfg != NULL; cfg = cfg->next)
- {
- switch(cfg->tok)
- {
- case tok_if:
- /*
- * Push this condition on the stack, and nuke the token
- * representing the ifdef, since we no longer need it.
- */
- conditions[depth] = cfg->cond;
- depth++;
- cfg->tok = tok_nop;
- cfg->cond = NULL;
- break;
- case tok_else:
- /*
- * For an else, we just invert the condition at the top of
- * the stack. This is done in place with no reallocation
- * of memory taking place.
- */
- invert_condition(conditions[depth-1]);
- cfg->tok = tok_nop;
- break;
- case tok_fi:
- depth--;
- free_condition(conditions[depth]);
- conditions[depth] = NULL;
- cfg->tok = tok_nop;
- break;
- case tok_comment:
- case tok_define:
- case tok_menuoption:
- case tok_bool:
- case tok_tristate:
- case tok_int:
- case tok_hex:
- case tok_string:
- case tok_choice:
- /*
- * We need to duplicate the chain of conditions and attach them to
- * this token.
- */
- cfg->cond = get_token_cond(&conditions[0], depth);
- break;
- case tok_dep_tristate:
- /*
- * Same as tok_tristate et al except we have a temporary
- * conditional. (Sort of a hybrid tok_if, tok_tristate, tok_fi
- * option)
- */
- conditions[depth] = cfg->cond;
- depth++;
- cfg->cond = get_token_cond(&conditions[0], depth);
- depth--;
- free_condition(conditions[depth]);
- conditions[depth] = NULL;
- default:
- break;
- }
- }
+ struct kconfig * cfg;
X
- /*
- * Fix any conditions involving the "choice" operator.
- */
- fix_choice_cond();
-
- /*
- * Walk through and see if there are multiple options that control the
- * same kvariable. If there are we need to treat them a little bit
- * special.
- */
- for(cfg=scfg;cfg != NULL; cfg = cfg->next)
+ /*
+ * Transform op_variable to op_kvariable.
+ */
+ transform_to_kvariable( scfg );
+
+ /*
+ * Transform conditions that use variables from "choice" statements.
+ * Choice values appear to the user as a collection of booleans, and the
+ * script can test the individual booleans. But internally, all I have is
+ * the N-way value of an unnamed temporary for the whole statement. So I
+ * have to tranform '"$CONFIG_M386" != "y"'
+ * into '"$tmpvar_N" != "CONFIG_M386"'.
+ */
+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {
- switch(cfg->tok)
+ struct condition * cond;
+
+ for ( cond = cfg->cond; cond != NULL; cond = cond->next )
X {
- case tok_bool:
- case tok_tristate:
- case tok_dep_tristate:
- case tok_int:
- case tok_hex:
- case tok_string:
- for(cfg1=cfg;cfg1 != NULL; cfg1 = cfg1->next)
+ if ( cond->op == op_kvariable && cond->cfg->token == token_choice_item )
X {
- switch(cfg1->tok)
+ /*
+ * Look two more tokens down for the comparison token.
+ * It has to be "y" for this trick to work.
+ *
+ * If you get this error, don't even think about relaxing the
+ * strcmp test. You will produce incorrect TK code. Instead,
+ * look for the place in your Config.in script where you are
+ * comparing a 'choice' variable to a value other than 'y',
+ * and rewrite the comparison to be '= "y"' or '!= "y"'.
+ */
+ struct condition * cond2 = cond->next->next;
+ const char * label;
+
+ if ( strcmp( cond2->str, "y" ) != 0 )
X {
- case tok_define:
- case tok_bool:
- case tok_tristate:
- case tok_dep_tristate:
- case tok_int:
- case tok_hex:
- case tok_string:
- if( strcmp(cfg->optionname, cfg1->optionname) == 0)
- {
- cfg->flags |= CFG_DUP;
- cfg1->flags |= CFG_DUP;
- }
- break;
- default:
- break;
+ fprintf( stderr, "tkparse choked in fix_choice_cond\n" );
+ exit( 1 );
X }
+
+ label = cond->cfg->label;
+ cond->cfg = cond->cfg->cfg_parent;
+ cond2->str = strdup( label );
X }
- break;
- default:
- break;
X }
X }
X
- /*
- * Now go through the list, and every time we see a kvariable, check
- * to see whether it also has some dependencies. If so, then
- * append it to our list. The reason we do this is that we might have
- * option CONFIG_FOO which is only used if CONFIG_BAR is set. It may
- * turn out that in config.in that the default value for CONFIG_BAR is
- * set to "y", but that CONFIG_BAR is not enabled because CONFIG_XYZZY
- * is not set. The current condition chain does not reflect this, but
- * we can fix this by searching for the tokens that this option depends
- * upon and cloning the conditions and merging them with the list.
- */
- for(cfg=scfg;cfg != NULL; cfg = cfg->next)
+ /*
+ * Walk the statement list, maintaining a stack of current conditions.
+ * token_if push its condition onto the stack.
+ * token_else invert the condition on the top of the stack.
+ * token_endif pop the stack.
+ *
+ * For a simple statement, create a condition chain by joining together
+ * all of the conditions on the stack.
+ */
X {
- /*
- * Search for a token that has a condition list.
- */
- if(cfg->cond == NULL) continue;
- for(cnd = cfg->cond; cnd; cnd=cnd->next)
- {
- /*
- * Now search the condition list for a known configuration variable
- * that has conditions of its own.
- */
- if(cnd->op != op_kvariable) continue;
- if(cnd->variable.cfg->cond == NULL) continue;
-
- if(cnd->variable.cfg->flags & CFG_DUP) continue;
- /*
- * OK, we have some conditions to append to cfg. Make a clone
- * of the conditions,
- */
- newcond = get_token_cond_frag(cnd->variable.cfg->cond, &last);
-
- /*
- * Finally, we splice it into our list.
- */
- last->next = cfg->cond;
- cfg->cond = newcond;
+ struct condition * cond_stack [32];
+ int depth = 0;
X
- }
- }
-
- /*
- * There is a strong possibility that we have duplicate conditions
- * in here. It would make the script more efficient and readable to
- * remove these. Here is where we assume here that there are no
- * parenthesis in the input script.
- */
- for(cfg=scfg;cfg != NULL; cfg = cfg->next)
- {
- /*
- * Search for configuration options that have conditions.
- */
- if(cfg->cond == NULL) continue;
- for(cnd = cfg->cond; cnd; cnd=cnd->next)
+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {
- /*
- * Search for a left parenthesis.
- */
- if(cnd->op != op_lparen) continue;
- for(cnd1 = cnd->next; cnd1; cnd1=cnd1->next)
+ switch ( cfg->token )
X {
- /*
- * Search after the previous left parenthesis, and try
- * and find a second left parenthesis.
- */
- if(cnd1->op != op_lparen) continue;
-
- /*
- * Now compare the next 5 tokens to see if they are
- * identical. We are looking for two chains that
- * are like: '(' $VARIABLE operator constant ')'.
- */
- cnd2 = cnd;
- cnd3 = cnd1;
- for(i=0; i<5; i++, cnd2=cnd2->next, cnd3=cnd3->next)
- {
- if(!cnd2 || !cnd3) break;
- if(cnd2->op != cnd3->op) break;
- if(i == 1 && (cnd2->op != op_kvariable
- || cnd2->variable.cfg != cnd3->variable.cfg) ) break;
- if(i==2 && cnd2->op != op_eq && cnd2->op != op_neq) break;
- if(i == 3 && cnd2->op != op_constant &&
- strcmp(cnd2->variable.str, cnd3->variable.str) != 0)
- break;
- if(i==4 && cnd2->op != op_rparen) break;
- }
- /*
- * If these match, and there is an and gluing these together,
- * then we can nuke the second one.
- */
- if(i==5 && ((cnd3 && cnd3->op == op_and)
- ||(cnd2 && cnd2->op == op_and)))


+ default:
+ break;
+

+ case token_if:
+ cond_stack [depth++] = cfg->cond;
+ cfg->cond = NULL;
+ break;
+
+ case token_else:
X {
- /*
- * We have a duplicate. Nuke 5 ops.
- */
- cnd3 = cnd1;
- for(i=0; i<5; i++, cnd3=cnd3->next)
+ /*
+ * Invert the condition chain.
+ *
+ * Be careful to transfrom op_or to op_and1, not op_and.
+ * I will need this later in the code that removes
+ * duplicate conditions.
+ */
+ struct condition * cond;
+
+ for ( cond = cond_stack [depth-1];
+ cond != NULL;
+ cond = cond->next )
X {
- cnd3->op = op_nuked;
+ switch( cond->op )
+ {
+ default: break;
+ case op_and: cond->op = op_or; break;
+ case op_or: cond->op = op_and1; break;
+ case op_neq: cond->op = op_eq; break;
+ case op_eq: cond->op = op_neq; break;
+ }
X }
- /*
- * Nuke the and that glues the conditions together.
- */
- if(cnd3 && cnd3->op == op_and) cnd3->op = op_nuked;
- else if(cnd2 && cnd2->op == op_and) cnd2->op = op_nuked;
X }
+ break;
+
+ case token_fi:
+ --depth;
+ break;
+
+ case token_bool:
+ case token_choice_item:
+ case token_comment:
+ case token_define_bool:
+ case token_hex:
+ case token_int:
+ case token_mainmenu_option:
+ case token_string:
+ case token_tristate:
+ cfg->cond = join_condition_stack( cond_stack, depth );
+ break;
+
+ case token_dep_tristate:
+ /*
+ * Same as the other simple statements, plus an additional
+ * condition for the dependency.
+ */
+ cond_stack [depth] = cfg->cond;
+ cfg->cond = join_condition_stack( cond_stack, depth+1 );
+ break;
X }
X }
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/scripts/tkgen.c linux/scripts/tkgen.c
--- v2.2.0-pre8/linux/scripts/tkgen.c Tue Jan 19 11:32:53 1999
+++ linux/scripts/tkgen.c Wed Jan 20 10:05:49 1999
@@ -77,1095 +77,970 @@
X * 8 January 1999, Michael Elizabeth Chastain <m...@shout.net>
X * - Emit menus_per_column
X *
- * 1999 01 04
- * Michael Elizabeth Chastain <m...@shout.net>
- * - Call clear_globalflags when writing out update_mainmenu.
- * This fixes the missing global/vfix lines for ARCH=alpha on 2.2.0-pre4.
- *
- * TO DO:
- * - clean up - there are useless ifdef's everywhere.
- * - better comments throughout - C code generating tcl is really cryptic.
- * - eliminate silly "update idletasks" hack to improve display speed and
- * reduce flicker. But how?
- * - make canvas contents resize with the window (good luck).
- * - some way to make submenus inside of submenus (ie. Main->Networking->IP)
- * (perhaps a button where the description would be)
- * - make the main menu use the same tcl code as the submenus.
- * - make choice and int/hex input types line up vertically with
- * bool/tristate.
- * - general speedups - how? The canvas seems to slow it down a lot.
- * - clean up +/- 16 confusion for enabling/disabling variables; causes
- * (theoretical, at the moment) problems with dependencies.
- *
+ * 14 January 1999, Michael Elizabeth Chastain <m...@shout.net>
+ * - Steam-clean this file. I tested this by generating kconfig.tk for every
+ * architecture and comparing it character-for-character against the output
+ * of the old tkparse.
+ * - Fix flattening of nested menus. The old code simply assigned items to
+ * the most recent token_mainmenu_option, without paying attention to scope.
+ * For example: "menu-1 bool-a menu-2 bool-b endmenu bool-c bool-d endmenu".
+ * The old code would put bool-a in menu-1, bool-b in menu-2, and bool-c
+ * and bool-d in *menu-2*. This hosed the nested submenus in
+ * drives/net/Config.in and other places.
+ * - Fix menu line wraparound at 128 menus (some fool used a 'char' for
+ * a counter).
X */
+
X #include <stdio.h>
X #include <unistd.h>
X #include "tkparse.h"
X
-#ifndef TRUE
-#define TRUE (1)
-#endif
X
-#ifndef FALSE
-#define FALSE (0)
-#endif
X
X /*
- * This is the total number of submenus that we have.
+ * Total number of menus.
X */
-static int tot_menu_num =0;
+static int tot_menu_num = 0;
+
+
X
X /*
X * Generate portion of wish script for the beginning of a submenu.
X * The guts get filled in with the various options.
X */
-static void start_proc(char * label, int menu_num, int flag)
+static void start_proc( char * label, int menu_num, int flag )
X {
- if( flag )
- printf("menu_option menu%d %d \"%s\"\n", menu_num, menu_num, label);
- printf("proc menu%d {w title} {\n", menu_num);
- printf("\tcatch {destroy $w}\n");
- printf("\ttoplevel $w -class Dialog\n");
- printf("\twm withdraw $w\n");
- printf("\tmessage $w.m -width 400 -aspect 300 -text \\\n");
- printf("\t\t\"%s\" -relief raised\n",label);
- printf("\tpack $w.m -pady 10 -side top -padx 10\n");
- printf("\twm title $w \"%s\" \n\n", label);
-
- /*
- * Attach the "Prev", "Next" and "OK" buttons at the end of the window.
- */
- printf("\tset oldFocus [focus]\n");
- printf("\tframe $w.f\n");
- printf("\tbutton $w.f.back -text \"Main Menu\" \\\n"
- "\t\t-width 15 -command \"destroy $w; focus $oldFocus; update_mainmenu $w\"\n");
- printf("\tbutton $w.f.next -text \"Next\" \\\n"
- "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n",
- menu_num+1, menu_num+1);
- if (menu_num == tot_menu_num)
- printf("\t$w.f.next configure -state disabled\n");
- printf("\tbutton $w.f.prev -text \"Prev\" \\\n"
- "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n",
- menu_num-1, menu_num-1);
- if (1 == menu_num)
- printf("\t$w.f.prev configure -state disabled\n");
- printf("\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n");
- printf("\tpack $w.f -pady 10 -side bottom -anchor w -fill x\n");
-
- /*
- * Lines between canvas and other areas of the window.
- */
- printf("\tframe $w.topline -relief ridge -borderwidth 2 -height 2\n");
- printf("\tpack $w.topline -side top -fill x\n\n");
- printf("\tframe $w.botline -relief ridge -borderwidth 2 -height 2\n");
- printf("\tpack $w.botline -side bottom -fill x\n\n");
-
- /*
- * The "config" frame contains the canvas and a scrollbar.
- */
- printf("\tframe $w.config\n");
- printf("\tpack $w.config -fill y -expand on\n\n");
- printf("\tscrollbar $w.config.vscroll -command \"$w.config.canvas yview\"\n");
- printf("\tpack $w.config.vscroll -side right -fill y\n\n");


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 13'
echo 'File patch-2.2.0-pre9 is continued in part 14'
echo 14 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part14

#!/bin/sh
# this is part 14 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 14; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

-
- /*
- * The scrollable canvas itself, where the real work (and mess) gets done.
- */
- printf("\tcanvas $w.config.canvas -height 1\\\n"
- "\t\t-relief flat -borderwidth 0 -yscrollcommand \"$w.config.vscroll set\" \\\n"
- "\t\t-width [expr [winfo screenwidth .] * 1 / 2] \n");
- printf("\tframe $w.config.f\n");
- printf("\tpack $w.config.canvas -side right -fill y\n");
-
- printf("\n\n");
+ if ( flag )
+ printf( "menu_option menu%d %d \"%s\"\n", menu_num, menu_num, label );
+ printf( "proc menu%d {w title} {\n", menu_num );
+ printf( "\tcatch {destroy $w}\n" );
+ printf( "\ttoplevel $w -class Dialog\n" );
+ printf( "\twm withdraw $w\n" );
+ printf( "\tmessage $w.m -width 400 -aspect 300 -text \\\n" );
+ printf( "\t\t\"%s\" -relief raised\n", label );
+ printf( "\tpack $w.m -pady 10 -side top -padx 10\n" );
+ printf( "\twm title $w \"%s\" \n\n", label );
+
+ /*
+ * Attach the "Prev", "Next" and "OK" buttons at the end of the window.
+ */
+ printf( "\tset oldFocus [focus]\n" );
+ printf( "\tframe $w.f\n" );
+ printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" );
+ printf( "\t\t-width 15 -command \"destroy $w; focus $oldFocus; update_mainmenu $w\"\n" );
+ printf( "\tbutton $w.f.next -text \"Next\" \\\n" );
+ printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num+1, menu_num+1 );
+ if ( menu_num == tot_menu_num )
+ printf( "\t$w.f.next configure -state disabled\n" );
+ printf( "\tbutton $w.f.prev -text \"Prev\" \\\n" );
+ printf( "\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num-1, menu_num-1 );
+ if ( menu_num == 1 )
+ printf( "\t$w.f.prev configure -state disabled\n" );
+ printf( "\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n" );
+ printf( "\tpack $w.f -pady 10 -side bottom -anchor w -fill x\n" );
+
+ /*
+ * Lines between canvas and other areas of the window.
+ */
+ printf( "\tframe $w.topline -relief ridge -borderwidth 2 -height 2\n" );
+ printf( "\tpack $w.topline -side top -fill x\n\n" );
+ printf( "\tframe $w.botline -relief ridge -borderwidth 2 -height 2\n" );
+ printf( "\tpack $w.botline -side bottom -fill x\n\n" );
+
+ /*
+ * The "config" frame contains the canvas and a scrollbar.
+ */
+ printf( "\tframe $w.config\n" );
+ printf( "\tpack $w.config -fill y -expand on\n\n" );
+ printf( "\tscrollbar $w.config.vscroll -command \"$w.config.canvas yview\"\n" );
+ printf( "\tpack $w.config.vscroll -side right -fill y\n\n" );
+
+ /*
+ * The scrollable canvas itself, where the real work (and mess) gets done.
+ */
+ printf( "\tcanvas $w.config.canvas -height 1\\\n" );
+ printf( "\t\t-relief flat -borderwidth 0 -yscrollcommand \"$w.config.vscroll set\" \\\n" );
+ printf( "\t\t-width [expr [winfo screenwidth .] * 1 / 2] \n" );
+ printf( "\tframe $w.config.f\n" );
+ printf( "\tpack $w.config.canvas -side right -fill y\n" );
+ printf("\n\n");


X }
X
+
+
X /*

X * Each proc we create needs a global declaration for any global variables we
X * use. To minimize the size of the file, we set a flag each time we output
X * a global declaration so we know whether we need to insert one for a
X * given function or not.
X */
-void clear_globalflags(struct kconfig * cfg)
+void clear_globalflags( struct kconfig * scfg )
X {
- for(; cfg != NULL; cfg = cfg->next)
- {
- cfg->flags &= ~GLOBAL_WRITTEN;


- }
+ struct kconfig * cfg;

+


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )

+ cfg->global_written = 0;


X }
X
+
+
X /*

X * Output a "global" line for a given variable. Also include the
X * call to "vfix". (If vfix is not needed, then it's fine to just printf
X * a "global" line).
X */
-void inline global(char *var)
+void global( const char *var )
X {
- printf("\tglobal %s; vfix %s\n", var, var);
+ printf( "\tglobal %s; vfix %s\n", var, var );


X }
X
+
+
X /*

- * This function walks the chain of conditions that we got from cond.c,
- * and creates a wish conditional to enable/disable a given widget.
+ * This function walks the chain of conditions that we got from cond.c
+ * and creates a TCL conditional to enable/disable a given widget.
X */
-void generate_if(struct kconfig * item,
- struct condition * cond,
- int menu_num,
- int line_num)
+void generate_if( struct kconfig * cfg, struct condition * ocond,
+ int menu_num, int line_num )
X {
- struct condition * ocond;


+ struct condition * cond;
X

- ocond = cond;
-
- /*
- * First write any global declarations we need for this conditional.
- */
- while(cond != NULL )
+ /*
+ * First write any global declarations we need for this conditional.
+ */
+ for ( cond = ocond; cond != NULL; cond = cond->next )
X {
- switch(cond->op){
- case op_variable:
- global(cond->variable.str);
- break;
- case op_kvariable:
- if(cond->variable.cfg->flags & GLOBAL_WRITTEN) break;
- cond->variable.cfg->flags |= GLOBAL_WRITTEN;
- global(cond->variable.cfg->optionname);


- break;
- default:
- break;
- }

- cond = cond->next;
+ switch ( cond->op )
+ {
+ default:
+ break;
+
+ case op_variable:
+ global( cond->str );
+ break;
+
+ case op_kvariable:
+ if ( ! cond->cfg->global_written )
+ {
+ cond->cfg->global_written = 1;
+ global( cond->cfg->optionname );
+ }
+ break;
+ }
X }
-
- /*
- * Now write this option.
- */
- if( (item->flags & GLOBAL_WRITTEN) == 0
- && (item->optionname != NULL) )
+
+ /*
+ * Now write this option.
+ */
+ if ( ! cfg->global_written && cfg->optionname != NULL )
X {
- global(item->optionname);
- item->flags |= GLOBAL_WRITTEN;
+ cfg->global_written = 1;
+ global( cfg->optionname );
X }
- /*
- * Now generate the body of the conditional.
- */
- printf("\tif {");
- cond = ocond;
- while(cond != NULL )
+
+ /*
+ * Generate the body of the conditional.
+ */
+ printf( "\tif {" );
+ for ( cond = ocond; cond != NULL; cond = cond->next )
X {
- switch(cond->op){
- case op_bang:
- printf(" ! ");


- break;
- case op_eq:

- printf(" == ");


- break;
- case op_neq:

- printf(" != ");
- break;
- case op_and:
- case op_and1:
- printf(" && ");


- break;
- case op_or:

- printf(" || ");
- break;
- case op_lparen:
- printf("(");
- break;
- case op_rparen:
- printf(")");
- break;
- case op_variable:
- printf("$%s", cond->variable.str);
- break;
- case op_kvariable:
- printf("$%s", cond->variable.cfg->optionname);
- break;
- case op_shellcmd:
- printf("[exec %s]", cond->variable.str);
- break;
- case op_constant:
- if( strcmp(cond->variable.str, "y") == 0 )
- printf("1");
- else if( strcmp(cond->variable.str, "n") == 0 )
- printf("0");
- else if( strcmp(cond->variable.str, "m") == 0 )
- printf("2");
- else
- printf("\"%s\"", cond->variable.str);


- break;
- default:
- break;
- }

- cond = cond->next;
- }
+ switch ( cond->op )
+ {
+ default:
+ break;
X
- /*
- * Now we generate what we do depending upon the value of the conditional.
- * Depending upon what the token type is, there are different things
- * we must do to enable/disable the given widget - this code needs to
- * be closely coordinated with the widget creation procedures in header.tk.
- */
- switch(item->tok)
+ case op_bang: printf( " ! " ); break;
+ case op_eq: printf( " == " ); break;
+ case op_neq: printf( " != " ); break;
+ case op_and: printf( " && " ); break;
+ case op_and1: printf( " && " ); break;
+ case op_or: printf( " || " ); break;
+ case op_lparen: printf( "(" ); break;
+ case op_rparen: printf( ")" ); break;
+
+ case op_variable:
+ printf( "$%s", cond->str );
+ break;
+
+ case op_kvariable:
+ printf( "$%s", cond->cfg->optionname );
+ break;
+
+ case op_constant:
+ if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" );
+ else if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" );
+ else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" );
+ else
+ printf( "\"%s\"", cond->str );
+ break;
+ }
+ }
+ printf( "} then { " );
+
+ /*
+ * Generate a procedure call to write the value.
+ * This code depends on procedures in header.tk.
+ */


+ switch ( cfg->token )
X {

- case tok_define:
- printf("} then { set %s %s } \n", item->optionname, item->value);
- break;
- case tok_menuoption:
- printf("} then { .f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n",
- menu_num, menu_num);
- break;


- case tok_int:
- case tok_hex:
- case tok_string:

- printf("} then { ");
- printf(".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ", menu_num, line_num);
- printf(".menu%d.config.f.x%d.l configure -state normal; ", menu_num, line_num);
- printf("} else { ");
- printf(".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ];", menu_num, line_num );
- printf(".menu%d.config.f.x%d.l configure -state disabled;", menu_num, line_num );
- printf("}\n");
- break;
- case tok_bool:
-#ifdef BOOL_IS_BUTTON
- /*
- * If a bool is just a button, then use this definition.
- */
- printf("} then { .menu%d.config.f.x%d configure -state normal } else { .menu%d.config.f.x%d configure -state disabled }\n",
- menu_num, line_num,
- menu_num, line_num );
-#else
- /*
- * If a bool is a radiobutton, then use this instead.
- */
- printf("} then { ");
- printf(".menu%d.config.f.x%d.y configure -state normal;",menu_num, line_num);
- printf(".menu%d.config.f.x%d.n configure -state normal;",menu_num, line_num);
- printf(".menu%d.config.f.x%d.l configure -state normal;",menu_num, line_num);
- printf("set %s [expr $%s&15];", item->optionname, item->optionname);
- printf("} else { ");
- printf(".menu%d.config.f.x%d.y configure -state disabled;",menu_num, line_num);
- printf(".menu%d.config.f.x%d.n configure -state disabled;",menu_num, line_num);
- printf(".menu%d.config.f.x%d.l configure -state disabled;",menu_num, line_num);
- printf("set %s [expr $%s|16];", item->optionname, item->optionname);
- printf("}\n");
-#endif
- break;


- case tok_tristate:
- case tok_dep_tristate:

- printf("} then { ");
- if( item->tok == tok_dep_tristate )
- {
- global(item->depend.str);
- printf("if { $%s != 1 && $%s != 0 } then {",
- item->depend.str,item->depend.str);
- printf(".menu%d.config.f.x%d.y configure -state disabled;",menu_num, line_num);
- printf("} else {");
- printf(".menu%d.config.f.x%d.y configure -state normal;",menu_num, line_num);
- printf("}; ");
- }
- else
- {
- printf(".menu%d.config.f.x%d.y configure -state normal;",menu_num, line_num);
- }
-
- printf(".menu%d.config.f.x%d.n configure -state normal;",menu_num, line_num);
- printf("global CONFIG_MODULES; if {($CONFIG_MODULES == 1)} then { .menu%d.config.f.x%d.m configure -state normal };",menu_num, line_num);
- printf(".menu%d.config.f.x%d.l configure -state normal;",menu_num, line_num);
- /*
- * Or in a bit to the variable - this causes all of the radiobuttons
- * to be deselected (i.e. not be red).
- */
- printf("set %s [expr $%s&15];", item->optionname, item->optionname);
- printf("} else { ");
- printf(".menu%d.config.f.x%d.y configure -state disabled;",menu_num, line_num);
- printf(".menu%d.config.f.x%d.n configure -state disabled;",menu_num, line_num);
- printf(".menu%d.config.f.x%d.m configure -state disabled;",menu_num, line_num);
- printf(".menu%d.config.f.x%d.l configure -state disabled;",menu_num, line_num);
- /*
- * Clear the disable bit - this causes the correct radiobutton
- * to appear selected (i.e. turn red).
- */
- printf("set %s [expr $%s|16];", item->optionname, item->optionname);
- printf("}\n");
- break;
- case tok_choose:
- case tok_choice:
- fprintf(stderr,"Fixme\n");
- exit(0);
X default:
- break;
+ printf( " }\n" );
+ break;
+
+ case token_bool:
+ printf( ".menu%d.config.f.x%d.y configure -state normal;",
+ menu_num, line_num );
+ printf( ".menu%d.config.f.x%d.n configure -state normal;",
+ menu_num, line_num );
+ printf( ".menu%d.config.f.x%d.l configure -state normal;",
+ menu_num, line_num );
+ printf( "set %s [expr $%s&15];",
+ cfg->optionname, cfg->optionname );
+ printf( "} else { ");
+ printf( ".menu%d.config.f.x%d.y configure -state disabled;",
+ menu_num, line_num );
+ printf( ".menu%d.config.f.x%d.n configure -state disabled;",
+ menu_num, line_num );
+ printf( ".menu%d.config.f.x%d.l configure -state disabled;",
+ menu_num, line_num );
+ printf( "set %s [expr $%s|16];}\n",
+ cfg->optionname, cfg->optionname );
+ break;
+
+ case token_choice_header:
+ fprintf( stderr, "Internal error on token_choice_header\n" );
+ exit( 1 );
+
+ case token_choice_item:
+ fprintf( stderr, "Internal error on token_choice_item\n" );
+ exit( 1 );
+
+ case token_define_bool:
+ printf( "set %s %s } \n",
+ cfg->optionname, cfg->value );


+ break;
+
+ case token_dep_tristate:

+ case token_tristate:
+ if ( cfg->token == token_dep_tristate )
+ {
+ global( cfg->depend );
+ printf( "if { $%s != 1 && $%s != 0 } then {",
+ cfg->depend, cfg->depend );
+ printf( ".menu%d.config.f.x%d.y configure -state disabled;",
+ menu_num, line_num );
+ printf( "} else {" );
+ printf( ".menu%d.config.f.x%d.y configure -state normal;",
+ menu_num, line_num);
+ printf( "}; " );
+ }
+ else
+ {
+ printf( ".menu%d.config.f.x%d.y configure -state normal;",
+ menu_num, line_num );
+ }
+
+ printf( ".menu%d.config.f.x%d.n configure -state normal;",
+ menu_num, line_num );
+ printf( "global CONFIG_MODULES; if {($CONFIG_MODULES == 1)} then { .menu%d.config.f.x%d.m configure -state normal };",
+ menu_num, line_num );
+ printf( ".menu%d.config.f.x%d.l configure -state normal;",
+ menu_num, line_num );
+
+ /*
+ * Or in a bit to the variable - this causes all of the radiobuttons
+ * to be deselected (i.e. not be red).
+ */
+ printf( "set %s [expr $%s&15];",
+ cfg->optionname, cfg->optionname );
+ printf( "} else { " );
+ printf( ".menu%d.config.f.x%d.y configure -state disabled;",
+ menu_num, line_num );
+ printf( ".menu%d.config.f.x%d.n configure -state disabled;",
+ menu_num, line_num );
+ printf( ".menu%d.config.f.x%d.m configure -state disabled;",
+ menu_num, line_num );
+ printf( ".menu%d.config.f.x%d.l configure -state disabled;",
+ menu_num, line_num );
+
+ /*
+ * Clear the disable bit to enable the correct radiobutton.
+ */
+ printf( "set %s [expr $%s|16];}\n",
+ cfg->optionname, cfg->optionname );
+ break;
+


+ case token_hex:
+ case token_int:

+ case token_string:
+ printf( ".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ",
+ menu_num, line_num);
+ printf( ".menu%d.config.f.x%d.l configure -state normal; ",
+ menu_num, line_num);
+ printf( "} else { " );
+ printf( ".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ];",
+ menu_num, line_num );
+ printf( ".menu%d.config.f.x%d.l configure -state disabled;}\n",
+ menu_num, line_num );
+ break;
+
+ case token_mainmenu_option:
+ printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n",
+ menu_num, menu_num );


+ break;
X }
X }
X

+
+
X /*
- * Similar to generate_if, except we come here when generating an
- * output file. Thus instead of enabling/disabling a widget, we
- * need to decide whether to write out a given configuration variable
- * to the output file.
+ * Generate a line that writes a variable to the output file.
X */
-void generate_if_for_outfile(struct kconfig * item,
- struct condition * cond)
+void generate_writeconfig( struct kconfig * cfg )
X {
- struct condition * ocond;


+ struct condition * cond;
X

- /*
- * First write any global declarations we need for this conditional.
- */
- ocond = cond;
- for(; cond != NULL; cond = cond->next )
+ /*
+ * Generate global declaration for this symbol.
+ */
+ if ( cfg->token != token_comment )
X {
- switch(cond->op){
- case op_variable:
- global(cond->variable.str);
- break;
- case op_kvariable:
- if(cond->variable.cfg->flags & GLOBAL_WRITTEN) break;
- cond->variable.cfg->flags |= GLOBAL_WRITTEN;
- global(cond->variable.cfg->optionname);


- break;
- default:
- break;
- }

+ if ( ! cfg->global_written )
+ {
+ cfg->global_written = 1;
+ printf( "\tglobal %s\n", cfg->optionname );
+ }
X }
X
- /*
- * Now generate the body of the conditional.
- */
- printf("\tif {");
- cond = ocond;
- while(cond != NULL )
+ /*
+ * Generate global declarations for the condition chain.
+ */


+ for ( cond = cfg->cond; cond != NULL; cond = cond->next )
X {

- switch(cond->op){
- case op_bang:
- printf(" ! ");


- break;
- case op_eq:

- printf(" == ");


- break;
- case op_neq:

- printf(" != ");
- break;
- case op_and:
- case op_and1:
- printf(" && ");


- break;
- case op_or:

- printf(" || ");
- break;
- case op_lparen:
- printf("(");
- break;
- case op_rparen:
- printf(")");
- break;
- case op_variable:
- printf("$%s", cond->variable.str);
- break;
- case op_shellcmd:
- printf("[exec %s]", cond->variable.str);
- break;
- case op_kvariable:
- printf("$%s", cond->variable.cfg->optionname);
- break;
- case op_constant:
- if( strcmp(cond->variable.str, "y") == 0 )
- printf("1");
- else if( strcmp(cond->variable.str, "n") == 0 )
- printf("0");
- else if( strcmp(cond->variable.str, "m") == 0 )
- printf("2");
- else
- printf("\"%s\"", cond->variable.str);


- break;
- default:
- break;
- }

- cond = cond->next;
- }


+ switch( cond->op )
+ {
+ default:

+ break;
X
- /*
- * Now we generate what we do depending upon the value of the
- * conditional. Depending upon what the token type is, there are
- * different things we must do write the value the given widget -
- * this code needs to be closely coordinated with the widget
- * creation procedures in header.tk.
- */
- switch(item->tok)
- {
- case tok_define:
- printf("} then {write_tristate $cfg $autocfg %s %s $notmod }\n", item->optionname, item->value);


- break;
- case tok_comment:

- printf("} then {write_comment $cfg $autocfg \"%s\"}\n", item->label);


- break;
- case tok_dep_tristate:

- printf("} then { write_tristate $cfg $autocfg %s $%s $%s } \n",
- item->optionname, item->optionname, item->depend.str);
- break;
- case tok_tristate:
- case tok_bool:
- printf("} then { write_tristate $cfg $autocfg %s $%s $notmod }\n",
- item->optionname, item->optionname);
- break;
- case tok_int:
- printf("} then { write_int $cfg $autocfg %s $%s $notmod }\n",
- item->optionname, item->optionname);
- break;
- case tok_hex:
- printf("} then { write_hex $cfg $autocfg %s $%s $notmod }\n",
- item->optionname, item->optionname);
- break;
- case tok_string:
- printf("} then { write_string $cfg $autocfg %s $%s $notmod }\n",
- item->optionname, item->optionname);
- break;
- case tok_choose:
- case tok_choice:
- fprintf(stderr,"Fixme\n");
- exit(0);
- default:
- break;
+ case op_variable:
+ global( cond->str );
+ break;
+
+ case op_kvariable:
+ if ( ! cond->cfg->global_written )
+ {
+ cond->cfg->global_written = 1;
+ global( cond->cfg->optionname );
+ }
+ break;
+ }
X }
-}
X
-/*
- * Generates a fragment of wish script that closes out a submenu procedure.
- */
-static void end_proc(int menu_num)
-{


- struct kconfig * cfg;

+ /*
+ * Generate indentation.
+ */
+ if ( cfg->token != token_choice_header )
+ printf( "\t" );
X
- printf("\n\n\n");
- printf("\tfocus $w\n");
- printf("\tupdate_menu%d $w.config.f\n", menu_num);
- printf("\tglobal winx; global winy\n");
- printf("\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n");
- printf("\twm geometry $w +$winx+$winy\n");
-
- /*
- * Now that the whole window is in place, we need to wait for an "update"
- * so we can tell the canvas what its virtual size should be.
- *
- * Unfortunately, this causes some ugly screen-flashing because the whole
- * window is drawn, and then it is immediately resized. It seems
- * unavoidable, though, since "frame" objects won't tell us their size
- * until after an update, and "canvas" objects can't automatically pack
- * around frames. Sigh.
- */
- printf("\tupdate idletasks\n");
- printf("\t$w.config.canvas create window 0 0 -anchor nw -window $w.config.f\n\n");
- printf("\t$w.config.canvas configure \\\n"
- "\t\t-width [expr [winfo reqwidth $w.config.f] + 1]\\\n"
- "\t\t-scrollregion \"-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \\\n"
- "\t\t\t [expr [winfo reqheight $w.config.f] + 1]\"\n\n");
-
- /*
- * If the whole canvas will fit in 3/4 of the screen height, do it;
- * otherwise, resize to around 1/2 the screen and let us scroll.
- */
- printf("\tset winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]]\n");
- printf("\tset scry [expr [winfo screenh $w] / 2]\n");
- printf("\tset maxy [expr [winfo screenh $w] * 3 / 4]\n");
- printf("\tset canvtotal [expr [winfo reqh $w.config.f] + 2]\n");
- printf("\tif [expr $winy + $canvtotal < $maxy] {\n"
- "\t\t$w.config.canvas configure -height $canvtotal\n"
- "\t} else {\n"
- "\t\t$w.config.canvas configure -height [expr $scry - $winy]\n"
- "\t}\n");
-
- /*
- * Limit the min/max window size. Height can vary, but not width,
- * because of the limitations of canvas and our laziness.
- */
- printf("\tupdate idletasks\n");
- printf("\twm maxsize $w [winfo width $w] [winfo screenheight $w]\n");
- printf("\twm minsize $w [winfo width $w] 100\n\n");
- printf("\twm deiconify $w\n");
-
- printf("}\n\n\n");
-
- /*
- * Now we generate the companion procedure for the menu we just
- * generated. This procedure contains all of the code to
- * disable/enable widgets based upon the settings of the other
- * widgets, and will be called first when the window is mapped,
- * and each time one of the buttons in the window are clicked.
- */
- printf("proc update_menu%d {w} {\n", menu_num);
-
- printf("\tupdate_define\n");
- clear_globalflags(config);


- for(cfg = config;cfg != NULL; cfg = cfg->next)

+ /*
+ * Generate the conditional.
+ */
+ if ( cfg->cond != NULL )
X {
- /*
- * Skip items not for this menu, or ones having no conditions.
- */
- if (cfg->menu_number != menu_num ) continue;
- if (cfg->tok != tok_define) continue;
- /*
- * Clear all of the booleans that are defined in this menu.
- */
- if( (cfg->flags & GLOBAL_WRITTEN) == 0
- && (cfg->optionname != NULL) )
- {
- printf("\tglobal %s\n", cfg->optionname);
- cfg->flags |= GLOBAL_WRITTEN;
- printf("\tset %s 0\n", cfg->optionname);
- }
+ printf( "if {" );


+ for ( cond = cfg->cond; cond != NULL; cond = cond->next )

+ {
+ switch ( cond->op )
+ {
+ default: break;
+ case op_bang: printf( " ! " ); break;
+ case op_eq: printf( " == " ); break;
+ case op_neq: printf( " != " ); break;
+ case op_and: printf( " && " ); break;
+ case op_and1: printf( " && " ); break;
+ case op_or: printf( " || " ); break;
+ case op_lparen: printf( "(" ); break;
+ case op_rparen: printf( ")" ); break;
X
+ case op_variable:
+ printf( "$%s", cond->str );
+ break;
+
+ case op_kvariable:
+ printf( "$%s", cond->cfg->optionname );
+ break;
+
+ case op_constant:
+ if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" );
+ else if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" );
+ else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" );
+ else
+ printf( "\"%s\"", cond->str );
+ break;
+ }
+ }
+ printf( "} then {" );


X }
- for(cfg = config;cfg != NULL; cfg = cfg->next)
+

+ /*
+ * Generate a procedure call to write the value.
+ * This code depends on the write_* procedures in header.tk.
+ */


+ switch ( cfg->token )
X {
- /*

- * Skip items not for this menu, or ones having no conditions.
- */
- if (cfg->menu_number != menu_num ) continue;
- if (cfg->tok == tok_menuoption) continue;
- if (cfg->cond != NULL )
- generate_if(cfg, cfg->cond, menu_num, cfg->menu_line);
- else
- {
- /*
- * If this token has no conditionals, check to see whether
- * it is a tristate - if so, then generate the conditional
- * to enable/disable the "y" button based upon the setting
- * of the option it depends upon.
- */
- if(cfg->tok == tok_dep_tristate)
+ default:
+ if ( cfg->cond != NULL )
+ printf( " }" );
+ printf( "\n" );
+ break;
+
+ case token_bool:
+ case token_tristate:
+ if ( cfg->cond )
+ printf( " " );
+ printf( "write_tristate $cfg $autocfg %s $%s $notmod",
+ cfg->optionname, cfg->optionname );
+ if ( cfg->cond != NULL )
+ printf( " }" );
+ printf( "\n" );
+ break;
+
+ case token_choice_header:
+ /*
+ * This is funky code -- it fails if there were any conditionals.
+ * Fortunately all the conditionals got stripped off somewhere
+ * else.
+ */
+ {
+ struct kconfig * cfg1;
+ for ( cfg1 = cfg->next;
+ cfg1 != NULL && cfg1->token == token_choice_item;
+ cfg1 = cfg1->next )
X {
- global(cfg->depend.str);
- printf("\tif {$%s != 1 && $%s != 0 } then { .menu%d.config.f.x%d.y configure -state disabled } else { .menu%d.config.f.x%d.y configure -state normal}\n",
- cfg->depend.str,cfg->depend.str,
- menu_num, cfg->menu_line,
- menu_num, cfg->menu_line);
+ printf("\tif { $%s == \"%s\" } then { write_tristate $cfg $autocfg %s 1 $notmod } else { write_tristate $cfg $autocfg %s 0 $notmod }\n",
+ cfg->optionname, cfg1->label,
+ cfg1->optionname,
+ cfg1->optionname );
X }
X }
+ break;
X
- }
+ case token_choice_item:
+ fprintf( stderr, "Internal error on token_choice_item\n" );


+ exit( 1 );
X

+ case token_comment:
+ printf( "write_comment $cfg $autocfg \"%s\"",
+ cfg->label );
+ if ( cfg->cond != NULL )
+ printf( "}" );
+ printf( "\n" );
+ break;
+
+ case token_define_bool:
+ if ( cfg->cond == NULL )
+ {
+ printf( "write_tristate $cfg $autocfg %s $%s $notmod\n",
+ cfg->optionname, cfg->optionname );
+ }
+ else
+ {
+ printf( "write_tristate $cfg $autocfg %s %s $notmod }\n",
+ cfg->optionname, cfg->value );
+ }
+ break;
X
- printf("}\n\n\n");
+ case token_dep_tristate:
+ if ( cfg->cond )
+ printf( " " );
+ printf( "write_tristate $cfg $autocfg %s $%s $%s",
+ cfg->optionname, cfg->optionname, cfg->depend );
+ if ( cfg->cond != NULL )
+ printf( " }" );
+ printf( " \n" );
+ break;
+
+ case token_hex:
+ if ( cfg->cond != NULL )
+ printf( " " );
+ printf( "write_hex $cfg $autocfg %s $%s $notmod",
+ cfg->optionname, cfg->optionname );
+ if ( cfg->cond != NULL )
+ printf( " }" );
+ printf( "\n" );
+ break;
+
+ case token_int:
+ if ( cfg->cond != NULL )
+ printf( " " );
+ printf( "write_int $cfg $autocfg %s $%s $notmod",
+ cfg->optionname, cfg->optionname );
+ if ( cfg->cond != NULL )
+ printf( " }" );
+ printf( "\n" );
+ break;
+
+ case token_string:
+ if ( cfg->cond != NULL )
+ printf( " " );
+ printf( "write_string $cfg $autocfg %s $%s $notmod",
+ cfg->optionname, cfg->optionname );
+ if ( cfg->cond != NULL )
+ printf( " }" );
+ printf( "\n" );


+ break;
+ }
X }
X

+
+
X /*
- * This function goes through and counts up the number of items in
- * each submenu. If there are too many options, we need to split it
- * into submenus. This function just calculates how many submenus,
- * and how many items go in each submenu.
+ * Generates the end of a menu procedure.
X */
-static void find_menu_size(struct kconfig *cfg,
- int *menu_max,
- int *menu_maxlines)
-
+static void end_proc( struct kconfig * scfg, int menu_num )
X {
- struct kconfig * pnt;
- int tot;
-
- /*
- * First count up the number of options in this menu.
- */
- tot = 0;
- for(pnt = cfg->next; pnt; pnt = pnt->next)
- {
- if( pnt->tok == tok_menuoption) break;
- switch (pnt->tok)
- {


- case tok_bool:
- case tok_tristate:
- case tok_dep_tristate:
- case tok_int:
- case tok_hex:
- case tok_string:

- case tok_choose:
- tot++;
- break;
- case tok_choice:


- default:
- break;
- }
- }
+ struct kconfig * cfg;
X

- *menu_max = cfg->menu_number;
- *menu_maxlines = tot;
+ printf( "\n\n\n" );
+ printf( "\tfocus $w\n" );
+ printf( "\tupdate_menu%d $w.config.f\n",
+ menu_num );
+ printf( "\tglobal winx; global winy\n" );
+ printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n" );
+ printf( "\twm geometry $w +$winx+$winy\n" );
+
+ /*
+ * Now that the whole window is in place, we need to wait for an "update"
+ * so we can tell the canvas what its virtual size should be.
+ *
+ * Unfortunately, this causes some ugly screen-flashing because the whole
+ * window is drawn, and then it is immediately resized. It seems
+ * unavoidable, though, since "frame" objects won't tell us their size
+ * until after an update, and "canvas" objects can't automatically pack
+ * around frames. Sigh.
+ */
+ printf( "\tupdate idletasks\n" );
+ printf( "\t$w.config.canvas create window 0 0 -anchor nw -window $w.config.f\n\n" );
+ printf( "\t$w.config.canvas configure \\\n" );
+ printf( "\t\t-width [expr [winfo reqwidth $w.config.f] + 1]\\\n" );
+ printf( "\t\t-scrollregion \"-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \\\n" );
+ printf( "\t\t\t [expr [winfo reqheight $w.config.f] + 1]\"\n\n" );
+
+ /*
+ * If the whole canvas will fit in 3/4 of the screen height, do it;
+ * otherwise, resize to around 1/2 the screen and let us scroll.
+ */
+ printf( "\tset winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]]\n" );
+ printf( "\tset scry [expr [winfo screenh $w] / 2]\n" );
+ printf( "\tset maxy [expr [winfo screenh $w] * 3 / 4]\n" );
+ printf( "\tset canvtotal [expr [winfo reqh $w.config.f] + 2]\n" );
+ printf( "\tif [expr $winy + $canvtotal < $maxy] {\n" );
+ printf( "\t\t$w.config.canvas configure -height $canvtotal\n" );
+ printf( "\t} else {\n" );
+ printf( "\t\t$w.config.canvas configure -height [expr $scry - $winy]\n" );
+ printf( "\t}\n" );
+
+ /*
+ * Limit the min/max window size. Height can vary, but not width,
+ * because of the limitations of canvas and our laziness.
+ */
+ printf( "\tupdate idletasks\n" );
+ printf( "\twm maxsize $w [winfo width $w] [winfo screenheight $w]\n" );
+ printf( "\twm minsize $w [winfo width $w] 100\n\n" );
+ printf( "\twm deiconify $w\n" );
+ printf( "}\n\n\n" );
+
+ /*
+ * Now we generate the companion procedure for the menu we just
+ * generated. This procedure contains all of the code to
+ * disable/enable widgets based upon the settings of the other
+ * widgets, and will be called first when the window is mapped,
+ * and each time one of the buttons in the window are clicked.
+ */
+ printf( "proc update_menu%d {w} {\n", menu_num );
+ printf( "\tupdate_define\n" );
+
+ /*
+ * Clear all of the booleans that are defined in this menu.
+ */
+ clear_globalflags( scfg );


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )

+ {
+ if ( cfg->menu_number == menu_num && cfg->token == token_define_bool
+ && cfg->optionname != NULL )
+ {
+ if ( ! cfg->global_written )
+ {
+ cfg->global_written = 1;
+ printf( "\tglobal %s\n", cfg->optionname );
+ printf( "\tset %s 0\n", cfg->optionname );
+ }
+ }
+ }
+


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )

+ {
+ if ( cfg->menu_number == menu_num
+ && cfg->token != token_mainmenu_option
+ && cfg->token != token_choice_item )
+ {
+ if ( cfg->cond != NULL )
+ generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line );
+ else
+ {
+ /*
+ * Treat tristate like conditional here.
+ */
+ if ( cfg->token == token_dep_tristate )
+ {
+ global( cfg->depend );
+ printf( "\tif {$%s != 1 && $%s != 0 } then { .menu%d.config.f.x%d.y configure -state disabled } else { .menu%d.config.f.x%d.y configure -state normal}\n",
+ cfg->depend, cfg->depend,
+ menu_num, cfg->menu_line,
+ menu_num, cfg->menu_line );
+ }
+ }
+ }
+ }
+
+ printf("}\n\n\n");


X }
X
+
+
X /*

X * This is the top level function for generating the tk script.
X */
-void dump_tk_script(struct kconfig *scfg)
+void dump_tk_script( struct kconfig * scfg )
X {
- int menu_num =0;
- int menu_max =0;
- int menu_min =0;
- int menu_line = 0;
- int menu_maxlines = 0;


- struct kconfig * cfg;

- struct kconfig * cfg1 = NULL;
- char * menulabel = "tkgen error";
-
- /*
- * Start by assigning menu numbers, and submenu numbers.
- */
- for(cfg = scfg;cfg != NULL; cfg = cfg->next)
+ int menu_depth;
+ int menu_num [64];
+ struct kconfig * menu_first [256];
+ struct kconfig * menu_last [256];
+ int imenu;


+ struct kconfig * cfg;

+ struct kconfig * cfg1 = NULL;
+ const char * name = "No Name";
+
+ /*
+ * Thread the menu pointers so I can walk each menu separately.
+ */
+ tot_menu_num = 0;
+ menu_depth = 0;


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {

- switch (cfg->tok)


+ switch ( cfg->token )
X {

- case tok_menuname:
- break;
- case tok_menuoption:
- /*
- * At the start of a new menu, calculate the number of items
- * we will put into each submenu so we know when to bump the
- * menu number. The submenus are really no different from a
- * normal menu, but the top level buttons only access the first
- * of the chain of menus, and the prev/next buttons are used
- * access the submenus.
- */
- cfg->menu_number = ++menu_num;
- find_menu_size(cfg, &menu_max, &menu_maxlines);
- cfg->submenu_start = menu_num;
- cfg->submenu_end = menu_max;
- menu_line = 0;
- break;


- case tok_bool:
- case tok_tristate:
- case tok_dep_tristate:
- case tok_int:
- case tok_hex:
- case tok_string:

- case tok_choose:
- /*
- * If we have overfilled the menu, then go to the next one.
- */
- if( menu_line == menu_maxlines )
- {
- menu_line = 0;
- menu_num++;
- }
- cfg->menu_number = menu_num;
- cfg->submenu_start = menu_min;
- cfg->submenu_end = menu_max;
- cfg->menu_line = menu_line++;
- break;
- case tok_define:
- cfg->menu_number = -1;
- case tok_choice:
X default:
- break;
- };
- }
+ break;
X
- /*
- * Record this so we can set up the prev/next buttons correctly.
- * Menus per column computation has extra button space as follows:
- * 4 for the save/quit/load/store buttons,
- * 1 for the blank space above save/quit/load/store
- * 2 to make the rounding work
- */
- tot_menu_num = menu_num;
- printf( "set menus_per_column %d\n\n", (tot_menu_num + 4 + 1 + 2) / 3 );
-
- /*
- * Now start generating the actual wish script that we will use.
- * We need to keep track of the menu numbers of the min/max menu
- * for a range of submenus so that we can correctly limit the
- * prev and next buttons so that they don't go over into some other
- * category.
- */
- for(cfg = scfg; cfg != NULL; cfg = cfg->next)
- {
- switch (cfg->tok)
- {
- case tok_menuname:
- printf("mainmenu_name \"%s\"\n", cfg->label);
- break;
- case tok_menuoption:
- /*
- * We are at the start of a new menu. If we had one that
- * we were working on before, close it out, and then generate
- * the script to start the new one.
- */
- if( cfg->menu_number > 1 )
- {
- end_proc(menu_num);
- }
- menulabel = cfg->label;
- start_proc(cfg->label, cfg->menu_number, TRUE);
- menu_num = cfg->menu_number;
- menu_max = cfg->submenu_end;
- menu_min = cfg->submenu_start;
- break;
- case tok_bool:
- /*
- * If we reached the point where we need to switch over
- * to the next submenu, then bump the menu number and generate
- * the code to close out the old menu and start the new one.
- */
- if( cfg->menu_number != menu_num )
- {
- end_proc(menu_num);
- start_proc(menulabel, cfg->menu_number, FALSE);
- menu_num = cfg->menu_number;
- }
- printf("\tbool $w.config.f %d %d \"%s\" %s\n",
- cfg->menu_number,
- cfg->menu_line,
- cfg->label,
- cfg->optionname);
- break;
-
- case tok_choice:
- printf("\t$w.config.f.x%d.x.menu add radiobutton -label \"%s\" -variable %s -value \"%s\" -command \"update_menu%d .menu%d.config.f\"\n",
- cfg1->menu_line,
- cfg->label,
- cfg1->optionname,
- cfg->label,
- cfg1->menu_number, cfg1->menu_number);
- break;
- case tok_choose:
- if( cfg->menu_number != menu_num )
- {
- end_proc(menu_num);
- start_proc(menulabel, cfg->menu_number, FALSE);
- menu_num = cfg->menu_number;
- }
- printf("\tglobal %s\n",cfg->optionname);
- printf("\tminimenu $w.config.f %d %d \"%s\" %s %s\n",
- cfg->menu_number,
- cfg->menu_line,
- cfg->label,
- cfg->optionname,
- /*
- * We rely on the fact that the first tok_choice corresponding
- * to the current tok_choose is cfg->next (compare parse() in
- * tkparse.c). We need its name to pick out the right help
- * text from Configure.help.
- */
- cfg->next->optionname);
- printf("\tmenu $w.config.f.x%d.x.menu\n", cfg->menu_line);
- cfg1 = cfg;
- break;
- case tok_tristate:
- if( cfg->menu_number != menu_num )
- {
- end_proc(menu_num);
- start_proc(menulabel, cfg->menu_number, FALSE);
- menu_num = cfg->menu_number;
- }
- printf("\ttristate $w.config.f %d %d \"%s\" %s\n",
- cfg->menu_number,
- cfg->menu_line,
- cfg->label,
- cfg->optionname);


- break;
- case tok_dep_tristate:

- if( cfg->menu_number != menu_num )
- {
- end_proc(menu_num);
- start_proc(menulabel, cfg->menu_number, FALSE);
- menu_num = cfg->menu_number;
- }
- printf("\tdep_tristate $w.config.f %d %d \"%s\" %s %s\n",
- cfg->menu_number,
- cfg->menu_line,
- cfg->label,
- cfg->optionname,
- cfg->depend.str);
- break;
- case tok_int:
- if( cfg->menu_number != menu_num )
- {
- end_proc(menu_num);
- start_proc(menulabel, cfg->menu_number, FALSE);
- menu_num = cfg->menu_number;
- }
- printf("\tint $w.config.f %d %d \"%s\" %s\n",
- cfg->menu_number,
- cfg->menu_line,
- cfg->label,
- cfg->optionname);
- break;
- case tok_hex:
- if( cfg->menu_number != menu_num )
- {
- end_proc(menu_num);
- start_proc(menulabel, cfg->menu_number, FALSE);
- menu_num = cfg->menu_number;
- }
- printf("\thex $w.config.f %d %d \"%s\" %s\n",
- cfg->menu_number,
- cfg->menu_line,
- cfg->label,
- cfg->optionname);
- break;
- case tok_string:
- if( cfg->menu_number != menu_num )
- {
- end_proc(menu_num);
- start_proc(menulabel, cfg->menu_number, FALSE);
- menu_num = cfg->menu_number;
- }
- printf("\tistring $w.config.f %d %d \"%s\" %s\n",
- cfg->menu_number,
- cfg->menu_line,
- cfg->label,
- cfg->optionname);


- break;
- default:
- break;
- }

+ case token_mainmenu_name:
+ name = cfg->label;
+ break;
+
+ case token_mainmenu_option:
+ if ( ++menu_depth >= 64 )
+ { fprintf( stderr, "menus too deep\n" ); exit( 1 ); }
+ if ( ++tot_menu_num >= 256 )
+ { fprintf( stderr, "too many menus\n" ); exit( 1 ); }
+ menu_num [menu_depth] = tot_menu_num;
+ menu_first [tot_menu_num] = cfg;
+ menu_last [tot_menu_num] = cfg;
+ break;
+
+ case token_endmenu:
+#if ! defined(BUG_COMPATIBLE)
+ /* flatten menus with proper scoping */
+ if ( --menu_depth < 0 )
+ { fprintf( stderr, "unmatched endmenu\n" ); exit( 1 ); }
+#endif
+ break;
X
+ case token_bool:
+ case token_choice_header:
+ case token_choice_item:
+ case token_dep_tristate:


+ case token_hex:
+ case token_int:

+ case token_string:
+ case token_tristate:

+ if ( menu_depth == 0 )
+ { fprintf( stderr, "statement not in menu\n" ); exit( 1 ); }
+ menu_last [menu_num [menu_depth]]->menu_next = cfg;
+ menu_last [menu_num [menu_depth]] = cfg;
+ cfg->menu_next = NULL;
+ break;
+
+ case token_define_bool:


+ break;
+ }
+ }
+

+ /*
+ * Generate menus per column setting.
+ * There are:
+ * four extra buttons for save/quit/load/store;
+ * one blank button
+ * add two to round up for division
+ */
+ printf( "set menus_per_column %d\n\n", (tot_menu_num + 4 + 1 + 2) / 3 );
+
+ /*
+ * Generate the menus.
+ */
+ printf( "mainmenu_name \"%s\"\n", name );
+ for ( imenu = 1; imenu <= tot_menu_num; ++imenu )
+ {
+ int menu_line = 0;
+
+ clear_globalflags( scfg );
+ start_proc( menu_first[imenu]->label, imenu, 1 );
+
+ for ( cfg = menu_first[imenu]; cfg != NULL; cfg = cfg->menu_next )
+ {
+ cfg->menu_number = imenu;
+


+ switch ( cfg->token )

+ {


+ default:
+ break;
+

+ case token_bool:
+ cfg->menu_line = menu_line++;
+ printf( "\tbool $w.config.f %d %d \"%s\" %s\n",
+ cfg->menu_number, cfg->menu_line, cfg->label,
+ cfg->optionname );
+ break;
+
+ case token_choice_header:
+ /*
+ * I need the first token_choice_item to pick out the right
+ * help text from Documentation/Configure.help.
+ */
+ cfg->menu_line = menu_line++;
+ printf( "\tglobal %s\n", cfg->optionname );
+ printf( "\tminimenu $w.config.f %d %d \"%s\" %s %s\n",
+ cfg->menu_number, cfg->menu_line, cfg->label,
+ cfg->optionname, cfg->next->optionname );
+ printf( "\tmenu $w.config.f.x%d.x.menu\n", cfg->menu_line );
+ cfg1 = cfg;
+ break;
+
+ case token_choice_item:
+ /* note: no menu line; uses choice header menu line */
+ printf( "\t$w.config.f.x%d.x.menu add radiobutton -label \"%s\" -variable %s -value \"%s\" -command \"update_menu%d .menu%d.config.f\"\n",
+ cfg1->menu_line, cfg->label, cfg1->optionname,
+ cfg->label, cfg1->menu_number, cfg1->menu_number );


+ break;
+
+ case token_dep_tristate:

+ cfg->menu_line = menu_line++;
+ printf( "\tdep_tristate $w.config.f %d %d \"%s\" %s %s\n",
+ cfg->menu_number, cfg->menu_line, cfg->label,
+ cfg->optionname, cfg->depend );
+ break;
+
+ case token_hex:
+ cfg->menu_line = menu_line++;
+ printf( "\thex $w.config.f %d %d \"%s\" %s\n",
+ cfg->menu_number, cfg->menu_line, cfg->label,
+ cfg->optionname );
+ break;
+
+ case token_int:
+ cfg->menu_line = menu_line++;
+ printf( "\tint $w.config.f %d %d \"%s\" %s\n",
+ cfg->menu_number, cfg->menu_line, cfg->label,
+ cfg->optionname );
+ break;
+
+ case token_string:
+ cfg->menu_line = menu_line++;
+ printf( "\tistring $w.config.f %d %d \"%s\" %s\n",
+ cfg->menu_number, cfg->menu_line, cfg->label,
+ cfg->optionname );
+ break;
+
+ case token_tristate:
+ cfg->menu_line = menu_line++;
+ printf( "\ttristate $w.config.f %d %d \"%s\" %s\n",
+ cfg->menu_number, cfg->menu_line, cfg->label,
+ cfg->optionname );
+ break;
+ }
+ }
+
+ end_proc( scfg, imenu );
+ }
+
+ /*
+ * The top level menu also needs an update function. When we exit a
+ * submenu, we may need to disable one or more of the submenus on
+ * the top level menu, and this procedure will ensure that things are
+ * correct.
+ */
+ clear_globalflags( scfg );
+ printf( "proc update_mainmenu {w} {\n" );


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )

+ {
+ if ( cfg->token == token_mainmenu_option && cfg->cond != NULL )
+ generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line );
X }
+ printf( "}\n\n\n" );
X
- /*
- * Generate the code to close out the last menu.
- */
- end_proc(menu_num);
- clear_globalflags(config);
-
- /*
- * The top level menu also needs an update function. When we exit a
- * submenu, we may need to disable one or more of the submenus on
- * the top level menu, and this procedure will ensure that things are
- * correct.
- */
- clear_globalflags(scfg);
- printf("proc update_mainmenu {w} {\n");
- for(cfg = scfg; cfg != NULL; cfg = cfg->next)
+#if 0
+ /*
+ * Generate code to set the variables that are "defined".
+ */
+ for ( cfg = config; cfg != NULL; cfg = cfg->next )
X {
- switch (cfg->tok)
+ if ( cfg->token == token_define_bool )
X {
- case tok_menuoption:
- if (cfg->cond != NULL )
- generate_if(cfg, cfg->cond, cfg->menu_number, cfg->menu_line);


- break;
- default:
- break;

+ if ( cfg->cond != NULL )
+ generate_if( cfg, cfg->cond, menu_num, cfg->menu_line );
+ else
+ printf( "\twrite_define %s %s\n", cfg->optionname, cfg->value );
X }
X }
+ #endif
X
- printf("}\n\n\n");
-
-#if 0
- /*
- * Generate some code to set the variables that are "defined".


- */
- for(cfg = config;cfg != NULL; cfg = cfg->next)

+ /*
+ * Generate code to load the default settings into the variables.
+ * The script in tail.tk will attempt to load .config,
+ * which may override these settings, but that's OK.


+ */
+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {

- /*
- * Skip items not for this menu, or ones having no conditions.
- */
- if( cfg->tok != tok_define) continue;
- if (cfg->cond != NULL )
- generate_if(cfg, cfg->cond, menu_num, cfg->menu_line);
- else


+ switch ( cfg->token )
X {

- printf("\twrite_define %s %s\n", cfg->optionname, cfg->value);
- }
+ default:
+ break;
X

+ case token_bool:
+ case token_choice_item:

+ case token_dep_tristate:
+ case token_tristate:
+ printf( "set %s 0\n", cfg->optionname );
+ break;
+
+ case token_choice_header:
+ printf( "set %s \"(not set)\"\n", cfg->optionname );
+ break;
+


+ case token_hex:
+ case token_int:

+ case token_string:
+ printf( "set %s %s\n", cfg->optionname, cfg->value );
+ break;
+ }
X }
-#endif
X
- /*
- * Now generate code to load the default settings into the variables.
- * Note that the script in tail.tk will attempt to load .config,
- * which may override these settings, but that's OK.
- */
- for(cfg = scfg; cfg != NULL; cfg = cfg->next)
+ /*
+ * Generate a function to write all of the variables to a file.
+ */
+ printf( "proc writeconfig {file1 file2} {\n" );
+ printf( "\tset cfg [open $file1 w]\n" );
+ printf( "\tset autocfg [open $file2 w]\n" );
+ printf( "\tset notmod 1\n" );
+ printf( "\tset notset 0\n" );
+ printf( "\tputs $cfg \"#\"\n");
+ printf( "\tputs $cfg \"# Automatically generated make config: don't edit\"\n");
+ printf( "\tputs $cfg \"#\"\n" );
+
+ printf( "\tputs $autocfg \"/*\"\n" );
+ printf( "\tputs $autocfg \" * Automatically generated C config: don't edit\"\n" );
+ printf( "\tputs $autocfg \" */\"\n" );
+ printf( "\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n" );
+
+ clear_globalflags( scfg );


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {

- switch (cfg->tok)


+ switch ( cfg->token )
X {

- case tok_bool:
- case tok_tristate:
- case tok_dep_tristate:

- case tok_choice:
- printf("set %s 0\n", cfg->optionname);
- break;


- case tok_int:
- case tok_hex:
- case tok_string:

- printf("set %s %s\n", cfg->optionname, cfg->value);
- break;
- case tok_choose:
- printf("set %s \"(not set)\"\n",cfg->optionname);
X default:
- break;


+ break;
+
+ case token_bool:

+ case token_choice_header:


+ case token_comment:
+ case token_define_bool:

+ case token_dep_tristate:


+ case token_hex:
+ case token_int:

+ case token_string:
+ case token_tristate:

+ generate_writeconfig( cfg );
+ break;
X }
X }
+ printf( "\tclose $cfg\n" );
+ printf( "\tclose $autocfg\n" );
+ printf( "}\n\n\n" );
X
- /*
- * Next generate a function that can be called from the main menu that will
- * write all of the variables out. This also serves double duty - we can
- * save configuration to a file using this.
- */
- printf("proc writeconfig {file1 file2} {\n");
- printf("\tset cfg [open $file1 w]\n");
- printf("\tset autocfg [open $file2 w]\n");
- printf("\tset notmod 1\n");
- printf("\tset notset 0\n");
- clear_globalflags(config);
- printf("\tputs $cfg \"#\"\n");
- printf("\tputs $cfg \"# Automatically generated make config: don't edit\"\n");
- printf("\tputs $cfg \"#\"\n");
-
- printf("\tputs $autocfg \"/*\"\n");
- printf("\tputs $autocfg \" * Automatically generated C config: don't edit\"\n");
- printf("\tputs $autocfg \" */\"\n");
- printf("\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n");
- for(cfg = scfg; cfg != NULL; cfg = cfg->next)
+ /*
+ * Generate a simple function that updates the master choice
+ * variable depending upon what values were loaded from a .config
+ * file.
+ */
+ printf( "proc clear_choices { } {\n" );


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {

- switch (cfg->tok)
+ if ( cfg->token == token_choice_header )
X {


- case tok_int:
- case tok_hex:
- case tok_string:

- case tok_bool:
- case tok_tristate:
- case tok_dep_tristate:

- case tok_define:
- case tok_choose:
- if(!(cfg->flags & GLOBAL_WRITTEN))
+ for ( cfg1 = cfg->next;
+ cfg1 != NULL && cfg1->token == token_choice_item;
+ cfg1 = cfg1->next )
X {
- cfg->flags |= GLOBAL_WRITTEN;
- printf("\tglobal %s\n", cfg->optionname);
+ printf( "\tglobal %s; set %s 0\n",
+ cfg1->optionname, cfg1->optionname );
X }
- /* fall through */
- case tok_comment:
- if (cfg->cond != NULL )
- generate_if_for_outfile(cfg, cfg->cond);
- else
- {
- if(cfg->tok == tok_dep_tristate)
- {
- printf("\tif {$%s == 0 } then {\n"
- "\t\twrite_tristate $cfg $autocfg %s $notset $notmod\n"
- "\t} else {\n"
- "\t\twrite_tristate $cfg $autocfg %s $%s $%s\n"
- "\t}\n",
- cfg->depend.str,
- cfg->optionname,
- cfg->optionname,
- cfg->optionname,
- cfg->depend.str);
- }
- else if(cfg->tok == tok_comment)
- {
- printf("\twrite_comment $cfg $autocfg \"%s\"\n", cfg->label);
- }
-#if 0
- else if(cfg->tok == tok_define)
- {
- printf("\twrite_define %s %s\n", cfg->optionname,
- cfg->value);
- }
-#endif
- else if (cfg->tok == tok_choose )
- {
- for(cfg1 = cfg->next;
- cfg1 != NULL && cfg1->tok == tok_choice;
- cfg1 = cfg1->next)
- {
- printf("\tif { $%s == \"%s\" } then { write_tristate $cfg $autocfg %s 1 $notmod } else { write_tristate $cfg $autocfg %s 0 $notmod }\n",
- cfg->optionname,
- cfg1->label,
- cfg1->optionname,
- cfg1->optionname);
- }
- }
- else if (cfg->tok == tok_int )
- {
- printf("\twrite_int $cfg $autocfg %s $%s $notmod\n",
- cfg->optionname,
- cfg->optionname);
- }
- else if (cfg->tok == tok_hex )
- {
- printf("\twrite_hex $cfg $autocfg %s $%s $notmod\n",
- cfg->optionname,
- cfg->optionname);
- }
- else if (cfg->tok == tok_string )
- {
- printf("\twrite_string $cfg $autocfg %s $%s $notmod\n",
- cfg->optionname,
- cfg->optionname);
- }
- else
- {
- printf("\twrite_tristate $cfg $autocfg %s $%s $notmod\n",
- cfg->optionname,
- cfg->optionname);
- }


- }
- break;
- default:
- break;

X }
X }
- printf("\tclose $cfg\n");
- printf("\tclose $autocfg\n");
- printf("}\n\n\n");
-
- /*
- * Finally write a simple function that updates the master choice
- * variable depending upon what values were loaded from a .config
- * file.
- */
- printf("proc clear_choices { } {\n");
- for(cfg = scfg; cfg != NULL; cfg = cfg->next)
+ printf( "}\n\n\n" );
+
+ printf( "proc update_choices { } {\n" );


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {

- if( cfg->tok != tok_choose ) continue;
- for(cfg1 = cfg->next;
- cfg1 != NULL && cfg1->tok == tok_choice;
- cfg1 = cfg1->next)
+ if ( cfg->token == token_choice_header )
X {
- printf("\tglobal %s; set %s 0\n",cfg1->optionname,cfg1->optionname);
+ printf( "\tglobal %s\n", cfg->optionname );
+ for ( cfg1 = cfg->next;
+ cfg1 != NULL && cfg1->token == token_choice_item;
+ cfg1 = cfg1->next )
+ {
+ printf( "\tglobal %s\n", cfg1->optionname );
+ printf( "\tif { $%s == 1 } then { set %s \"%s\" }\n",
+ cfg1->optionname, cfg->optionname, cfg1->label );
+ }
X }
X }
- printf("}\n\n\n");
+ printf( "}\n\n\n" );
X
- printf("proc update_choices { } {\n");
- for(cfg = scfg; cfg != NULL; cfg = cfg->next)
+ printf( "proc update_define { } {\n" );
+ clear_globalflags( scfg );


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {

- if( cfg->tok != tok_choose ) continue;
- printf("\tglobal %s\n", cfg->optionname);
- for(cfg1 = cfg->next;
- cfg1 != NULL && cfg1->tok == tok_choice;
- cfg1 = cfg1->next)
- {
- printf("\tglobal %s\n", cfg1->optionname);
- printf("\tif { $%s == 1 } then { set %s \"%s\" }\n",
- cfg1->optionname,
- cfg->optionname,
- cfg1->label);
+ if ( cfg->token == token_define_bool )
+ {
+ cfg->global_written = 1;
+ printf( "\tglobal %s\n", cfg->optionname );
X }
X }
- printf("}\n\n\n");
X
- printf("proc update_define { } {\n");
- clear_globalflags(config);
- for(cfg = scfg; cfg != NULL; cfg = cfg->next)


+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
X {

- if( cfg->tok != tok_define ) continue;
- printf("\tglobal %s\n", cfg->optionname);
- cfg->flags |= GLOBAL_WRITTEN;
- }
- for(cfg = scfg; cfg != NULL; cfg = cfg->next)
- {
- if( cfg->tok != tok_define ) continue;
- if (cfg->cond != NULL )
- generate_if(cfg, cfg->cond, -1, 0);
- else
+ if( cfg->token == token_define_bool )
X {
- printf("\tset %s %s\n",
- cfg->optionname, cfg->value);
+ if ( cfg->cond == NULL )
+ printf( "\tset %s %s\n", cfg->optionname, cfg->value );
+ else
+ generate_if( cfg, cfg->cond, -1, 0 );
X }
X }
- printf("}\n\n\n");
- /*
- * That's it. We are done. The output of this file will have header.tk
- * prepended and tail.tk appended to create an executable wish script.
- */
+ printf( "}\n\n\n" );
+
+ /*
+ * That's it. We are done. The output of this file will have header.tk
+ * prepended and tail.tk appended to create an executable wish script.
+ */
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/scripts/tkparse.c linux/scripts/tkparse.c
--- v2.2.0-pre8/linux/scripts/tkparse.c Tue Jan 19 11:32:53 1999
+++ linux/scripts/tkparse.c Wed Jan 20 10:05:49 1999
@@ -1,777 +1,622 @@


-/* parser config.in
- *
- * Version 1.0
- * Eric Youngdale
- * 10/95

+/*
+ * tkparse.c
X *


- * The general idea here is that we want to parse a config.in file and
- * from this, we generate a wish script which gives us effectively the
- * same functionality that the original config.in script provided.

+ * Eric Youngdale was the original author of xconfig.
+ * Michael Elizabeth Chastain (m...@shout.net) is the current maintainer.
X *

- * This task is split roughly into 3 parts. The first parse is the parse
- * of the input file itself. The second part is where we analyze the
- * #ifdef clauses, and attach a linked list of tokens to each of the
- * menu items. In this way, each menu item has a complete list of
- * dependencies that are used to enable/disable the options.
- * The third part is to take the configuration database we have build,
- * and build the actual wish script.

+ * Parse a config.in file and translate it to a wish script.
+ * This task has three parts:
X *
- * This file contains the code to do the first parse of config.in.
+ * tkparse.c tokenize the input
+ * tkcond.c transform 'if ...' statements
+ * tkgen.c generate output
X *
X * Change History
X *
- * 7 January 1999, Michael Elizabeth Chastain, <mailto:m...@shout.net>
- * Teach dep_tristate about a few literals, such as:
- * dep_tristate 'foo' CONFIG_FOO m
- * Also have it print an error message and exit on some parse failures.
+ * 7 January 1999, Michael Elizabeth Chastain, <m...@shout.net>
+ * - Teach dep_tristate about a few literals, such as:
+ * dep_tristate 'foo' CONFIG_FOO m
+ * Also have it print an error message and exit on some parse failures.
+ *


+ * 14 January 1999, Michael Elizabeth Chastain, <m...@shout.net>

+ * - Don't fclose stdin. Thanks to Tony Hoyle for nailing this one.
+ *


+ * 14 January 1999, Michael Elizabeth Chastain, <m...@shout.net>
+ * - Steam-clean this file. I tested this by generating kconfig.tk for
+ * every architecture and comparing it character-for-character against
+ * the output of the old tkparse.
X *

- * 14 January 1999, Michael Elizabeth Chastain, <mailto:m...@shout.net>
- * Don't fclose stdin. Thanks to Tony Hoyle for nailing this one.


+ * TO DO:
+ * - xconfig is at the end of its life cycle. Contact <m...@shout.net> if
+ * you are interested in working on the replacement.

SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'
fi

echo 'End of part 14'
echo 'File patch-2.2.0-pre9 is continued in part 15'
echo 15 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jan 21, 1999, 3:00:00 AM1/21/99
to
Archive-name: v2.1/patch-2.2.0-pre9/part15

#!/bin/sh
# this is part 15 of a 15 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.0-pre9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 15; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.0-pre9'
else
echo 'x - continuing with patch-2.2.0-pre9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.0-pre9' &&

X */
X
-#include <stdlib.h>


X #include <stdio.h>
+#include <stdlib.h>
X #include <string.h>

+
X #include "tkparse.h"
X
-struct kconfig * config = NULL;
-struct kconfig * clast = NULL;
-struct kconfig * koption = NULL;
+static struct kconfig * config_list = NULL;
+static struct kconfig * config_last = NULL;
+static const char * current_file = "<unknown file>";
X static int lineno = 0;
-static int menus_seen = 0;
-static char * current_file = NULL;
-static int do_source(char * filename);
-static char * get_string(char *pnt, char ** labl);
-static int choose_number = 0;
+
+static void do_source( const char * );
+
+#undef strcmp
+int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); }
+#define strcmp my_strcmp
+
X
X
X /*
- * Simple function just to skip over spaces and tabs in config.in.
+ * Report a syntax error.
X */
-static char * skip_whitespace(char * pnt)
+static void syntax_error( const char * msg )
X {
- while( *pnt && (*pnt == ' ' || *pnt == '\t')) pnt++;
- return pnt;
+ fprintf( stderr, "%s: %d: %s\n", current_file, lineno, msg );


+ exit( 1 );
X }

X
+
+
X /*

- * This function parses a conditional from a config.in (i.e. from an ifdef)
- * and generates a linked list of tokens that describes the conditional.
+ * Get a string.
X */
-static struct condition * parse_if(char * pnt)
+static const char * get_string( const char * pnt, char ** label )
X {
- char * opnt;
- struct condition *list;
- struct condition *last;
- struct condition *cpnt;
- char varname[64];
- char * pnt1;
-
- opnt = pnt;
-
- /*
- * We need to find the various tokens, and build the linked list.
- */
- pnt = skip_whitespace(pnt);
- if( *pnt != '[' ) return NULL;
- pnt++;
- pnt = skip_whitespace(pnt);
-
- list = last = NULL;
- while(*pnt && *pnt != ']') {
+ const char * word;
X
- pnt = skip_whitespace(pnt);
- if(*pnt== '\0' || *pnt == ']') break;
-
- /*
- * Allocate memory for the token we are about to parse, and insert
- * it in the linked list.
- */
- cpnt = (struct condition *) malloc(sizeof(struct condition));
- memset(cpnt, 0, sizeof(struct condition));
- if( last == NULL )
- {
- list = last = cpnt;
- }
- else
- {
- last->next = cpnt;
- last = cpnt;
- }
+ word = pnt;
+ for ( ; ; )
+ {
+ if ( *pnt == '\0' || *pnt == ' ' || *pnt == '\t' )
+ break;
+ pnt++;
+ }
X
- /*
- * Determine what type of operation this token represents.
- */
- if( *pnt == '-' && pnt[1] == 'a' )
- {
- cpnt->op = op_and;
- pnt += 2;
- continue;
- }
-
- if( *pnt == '-' && pnt[1] == 'o' )
- {
- cpnt->op = op_or;
- pnt += 2;
- continue;
- }
-
- if( *pnt == '!' && pnt[1] == '=' )
- {
- cpnt->op = op_neq;
- pnt += 2;
- continue;
- }
-
- if( *pnt == '=')
- {
- cpnt->op = op_eq;
- pnt += 1;
- continue;
- }
-
- if( *pnt == '!')
- {
- cpnt->op = op_bang;
- pnt += 1;
- continue;
- }
+ *label = malloc( pnt - word + 1 );
+ memcpy( *label, word, pnt - word );
+ (*label)[pnt - word] = '\0';
X
- if( *pnt != '"' ) goto error; /* This cannot be right. */
- pnt++;
- if( *pnt == '`' )
- {
- cpnt->op = op_shellcmd;
- pnt1 = varname;
- pnt++;
- while(*pnt && *pnt != '`') *pnt1++ = *pnt++;
- *pnt1++ = '\0';
- cpnt->variable.str = strdup(varname);
- if( *pnt == '`' ) pnt++;
- if( *pnt == '"' ) pnt++;
- continue;
- }
- if( *pnt == '$' )
- {
- cpnt->op = op_variable;
- pnt1 = varname;
+ if ( *pnt != '\0' )
X pnt++;
- while(*pnt && *pnt != '"') *pnt1++ = *pnt++;
- *pnt1++ = '\0';
- cpnt->variable.str = strdup(varname);
- if( *pnt == '"' ) pnt++;
- continue;
- }
-
- cpnt->op = op_constant;
- pnt1 = varname;
- while(*pnt && *pnt != '"') *pnt1++ = *pnt++;
- *pnt1++ = '\0';
- cpnt->variable.str = strdup(varname);
- if( *pnt == '"' ) pnt++;
- continue;
- }
-
- return list;
-
- error:
- if(current_file != NULL)
- fprintf(stderr,
- "Bad if clause at line %d(%s):%s\n", lineno, current_file, opnt);
- else
- fprintf(stderr,
- "Bad if clause at line %d:%s\n", lineno, opnt);
- return NULL;
+ return pnt;


X }
X
+
+
X /*

- * This function looks for a quoted string, from the input buffer, and
- * returns a pointer to a copy of this string. Any characters in
- * the string that need to be "quoted" have a '\' character inserted
- * in front - this way we can directly write these strings into
- * wish scripts.
+ * Get a quoted string.
+ * Insert a '\' before any characters that need quoting.
X */
-static char * get_qstring(char *pnt, char ** labl)
+static const char * get_qstring( const char * pnt, char ** label )
X {
- char quotechar;
- char newlabel[1024];
- char * pnt1;
- char * pnt2;
-
- while( *pnt && *pnt != '"' && *pnt != '\'') pnt++;
- if (*pnt == '\0') return pnt;
-
- quotechar = *pnt++;
- pnt1 = newlabel;
- while(*pnt && *pnt != quotechar && pnt[-1] != '\\')
- {
- /*
- * Quote the character if we need to.
- */
- if( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']')
- *pnt1++ = '\\';
-
- *pnt1++ = *pnt++;
- }
- *pnt1++ = '\0';
-
- pnt2 = (char *) malloc(strlen(newlabel) + 1);
- strcpy(pnt2, newlabel);
- *labl = pnt2;
-
- /*
- * Skip over last quote, and whitespace.
- */
- pnt++;
- pnt = skip_whitespace(pnt);
- return pnt;
-}
+ char quote_char;
+ char newlabel [1024];
+ char * pnt1;
X
-static char * parse_choices(struct kconfig * choice_kcfg, char * pnt)
-{
- struct kconfig * kcfg;
- int index = 1;
+ /* advance to the open quote */
+ for ( ; ; )
+ {
+ if ( *pnt == '\0' )
+ return pnt;
+ quote_char = *pnt++;
+ if ( quote_char == '"' || quote_char == '\'' )
+ break;
+ }
X
- /*
- * Choices appear in pairs of strings. The parse is fairly trivial.
- */
- while(1)
- {
- pnt = skip_whitespace(pnt);
- if(*pnt == '\0') break;
-
- kcfg = (struct kconfig *) malloc(sizeof(struct kconfig));
- memset(kcfg, 0, sizeof(struct kconfig));
- kcfg->tok = tok_choice;
- if( clast != NULL )
- {
- clast->next = kcfg;
- clast = kcfg;
- }
- else
- {
- clast = config = kcfg;
- }
+ /* copy into an intermediate buffer */
+ pnt1 = newlabel;
+ for ( ; ; )
+ {
+ if ( *pnt == '\0' )
+ syntax_error( "unterminated quoted string" );
+ if ( *pnt == quote_char && pnt[-1] != '\\' )
+ break;
X
- pnt = get_string(pnt, &kcfg->label);
- pnt = skip_whitespace(pnt);
- pnt = get_string(pnt, &kcfg->optionname);
- kcfg->choice_label = choice_kcfg;
- kcfg->choice_value = index++;
- if( strcmp(kcfg->label, choice_kcfg->value) == 0 )
- choice_kcfg->choice_value = kcfg->choice_value;
+ /* copy the character, quoting if needed */
+ if ( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']' )
+ *pnt1++ = '\\';
+ *pnt1++ = *pnt++;
X }
-
+
+ /* copy the label into a permanent location */
+ *pnt1++ = '\0';
+ *label = (char *) malloc( pnt1 - newlabel );
+ memcpy( *label, newlabel, pnt1 - newlabel );
+
+ /* skip over last quote and next whitespace */
+ pnt++;
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
X return pnt;
X }
X
X
X /*
- * This function grabs one text token from the input buffer
- * and returns a pointer to a copy of just the identifier.
- * This can be either a variable name (i.e. CONFIG_NET),
- * or it could be the default value for the option.
+ * Tokenize an 'if' statement condition.
X */
-static char * get_string(char *pnt, char ** labl)
+static struct condition * tokenize_if( const char * pnt )
X {
- char newlabel[1024];
- char * pnt1;
- char * pnt2;
+ struct condition * list;
+ struct condition * last;
X
- if (*pnt == '\0') return pnt;
+ /* eat the open bracket */
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
+ if ( *pnt != '[' )
+ syntax_error( "bad 'if' condition" );
+ pnt++;
X
- pnt1 = newlabel;
- while(*pnt && *pnt != ' ' && *pnt != '\t')
+ list = last = NULL;
+ for ( ; ; )
X {
- *pnt1++ = *pnt++;


+ struct condition * cond;

+
+ /* advance to the next token */
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
+ if ( *pnt == '\0' )
+ syntax_error( "unterminated 'if' condition" );
+ if ( *pnt == ']' )
+ return list;
+
+ /* allocate a new token */
+ cond = malloc( sizeof(*cond) );
+ memset( cond, 0, sizeof(*cond) );
+ if ( last == NULL )
+ { list = last = cond; }
+ else
+ { last->next = cond; last = cond; }
+
+ /* determine the token value */
+ if ( *pnt == '-' && pnt[1] == 'a' )
+ { cond->op = op_and; pnt += 2; continue; }
+
+ if ( *pnt == '-' && pnt[1] == 'o' )
+ { cond->op = op_or; pnt += 2; continue; }
+
+ if ( *pnt == '!' && pnt[1] == '=' )
+ { cond->op = op_neq; pnt += 2; continue; }
+
+ if ( *pnt == '=' )
+ { cond->op = op_eq; pnt += 1; continue; }
+
+ if ( *pnt == '!' )
+ { cond->op = op_bang; pnt += 1; continue; }
+
+ if ( *pnt == '"' )
+ {
+ const char * word;
+
+ /* advance to the word */
+ pnt++;
+ if ( *pnt == '$' )
+ { cond->op = op_variable; pnt++; }
+ else
+ { cond->op = op_constant; }
+
+ /* find the end of the word */
+ word = pnt;
+ for ( ; ; )
+ {
+ if ( *pnt == '\0' )
+ syntax_error( "unterminated double quote" );
+ if ( *pnt == '"' )
+ break;
+ pnt++;
+ }
+
+ /* store a copy of this word */
+ {
+ char * str = malloc( pnt - word + 1 );
+ memcpy( str, word, pnt - word );
+ str [pnt - word] = '\0';
+ cond->str = str;
+ }
+
+ pnt++;
+ continue;
+ }
+
+ /* unknown token */
+ syntax_error( "bad if condition" );
X }
- *pnt1++ = '\0';
+}
+
X
- pnt2 = (char *) malloc(strlen(newlabel) + 1);
- strcpy(pnt2, newlabel);
- *labl = pnt2;
X
- if( *pnt ) pnt++;
- return pnt;
+/*
+ * Tokenize a choice list. Choices appear as pairs of strings;
+ * note that I am parsing *inside* the double quotes. Ugh.
+ */
+static const char * tokenize_choices( struct kconfig * cfg_choose,
+ const char * pnt )
+{
+ for ( ; ; )
+ {
+ struct kconfig * cfg;
+
+ /* skip whitespace */
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
+ if ( *pnt == '\0' )
+ return pnt;
+
+ /* allocate a new kconfig line */
+ cfg = malloc( sizeof(*cfg) );
+ memset( cfg, 0, sizeof(*cfg) );
+ if ( config_last == NULL )
+ { config_last = config_list = cfg; }
+ else
+ { config_last->next = cfg; config_last = cfg; }
+
+ /* fill out the line */
+ cfg->token = token_choice_item;
+ cfg->cfg_parent = cfg_choose;
+ pnt = get_string( pnt, &cfg->label );
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
+ pnt = get_string( pnt, &cfg->optionname );
+ }
+
+ return pnt;


X }
X
X
+
+

+
X /*
- * Top level parse function. Input pointer is one complete line from config.in
- * and the result is that we create a token that describes this line
- * and insert it into our linked list.
+ * Tokenize one line.
X */
-void parse(char * pnt) {
- enum token tok;
- struct kconfig * kcfg;
- char tmpbuf[24],fake_if[1024];
+static void tokenize_line( const char * pnt )
+{
+ static struct kconfig * last_menuoption = NULL;
+ enum e_token token;


+ struct kconfig * cfg;
X

- /*
- * Ignore comments and leading whitespace.
- */
+ /* skip white space */
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
X
- pnt = skip_whitespace(pnt);
- while( *pnt && (*pnt == ' ' || *pnt == '\t')) pnt++;
- if(! *pnt ) return;
- if( *pnt == '#' ) return;
+ /*
+ * categorize the next token
+ */
X
- /*
- * Now categorize the next token.
- */
- tok = tok_unknown;
- if (strncmp(pnt, "mainmenu_name", 13) == 0)
- {
- tok = tok_menuname;
- pnt += 13;
- }
- else if (strncmp(pnt, "source", 6) == 0)
- {
- pnt += 7;
- pnt = skip_whitespace(pnt);
- do_source(pnt);
- return;
- }
- else if (strncmp(pnt, "mainmenu_option", 15) == 0)
- {
- menus_seen++;
- tok = tok_menuoption;
- pnt += 15;
- }
- else if (strncmp(pnt, "comment", 7) == 0)
- {
- tok = tok_comment;
- pnt += 7;
- }
- else if (strncmp(pnt, "choice", 6) == 0)
- {
- tok = tok_choose;
- pnt += 6;
- }
- else if (strncmp(pnt, "define_bool", 11) == 0)
- {
- tok = tok_define;
- pnt += 11;
- }
- else if (strncmp(pnt, "bool", 4) == 0)
- {
- tok = tok_bool;
- pnt += 4;
- }
- else if (strncmp(pnt, "tristate", 8) == 0)
- {
- tok = tok_tristate;
- pnt += 8;
- }
- else if (strncmp(pnt, "dep_tristate", 12) == 0)
- {
- tok = tok_dep_tristate;
- pnt += 12;
- }
- else if (strncmp(pnt, "int", 3) == 0)
- {
- tok = tok_int;
- pnt += 3;
- }
- else if (strncmp(pnt, "hex", 3) == 0)
- {
- tok = tok_hex;
- pnt += 3;
- }
- else if (strncmp(pnt, "string", 6) == 0)
- {
- tok = tok_string;
- pnt += 6;
- }
- else if (strncmp(pnt, "if", 2) == 0)
- {
- tok = tok_if;
- pnt += 2;
- }
- else if (strncmp(pnt, "else", 4) == 0)
- {
- tok = tok_else;
- pnt += 4;
- }
- else if (strncmp(pnt, "fi", 2) == 0)
- {
- tok = tok_fi;
- pnt += 2;
- }
- else if (strncmp(pnt, "endmenu", 7) == 0)
+#define match_token(t, s) \
+ if (strncmp(pnt, s, strlen(s)) == 0) { token = t; pnt += strlen(s); break; }
+
+ token = token_UNKNOWN;
+ switch ( *pnt )
X {
- tok = tok_endmenu;
- pnt += 7;


+ default:
+ break;
+

+ case '#':
+ case '\0':
+ return;
+
+ case 'b':
+ match_token( token_bool, "bool" );
+ break;
+
+ case 'c':
+ match_token( token_choice_header, "choice" );
+ match_token( token_comment, "comment" );
+ break;
+
+ case 'd':
+ match_token( token_define_bool, "define_bool" );
+ match_token( token_dep_tristate, "dep_tristate" );
+ break;
+
+ case 'e':
+ match_token( token_else, "else" );
+ match_token( token_endmenu, "endmenu" );
+ break;
+
+ case 'f':
+ match_token( token_fi, "fi" );
+ break;
+
+ case 'h':
+ match_token( token_hex, "hex" );
+ break;
+
+ case 'i':
+ match_token( token_if, "if" );
+ match_token( token_int, "int" );
+ break;
+
+ case 'm':
+ match_token( token_mainmenu_name, "mainmenu_name" );
+ match_token( token_mainmenu_option, "mainmenu_option" );
+ break;
+
+ case 's':
+ match_token( token_source, "source" );
+ match_token( token_string, "string" );
+ break;
+
+ case 't':
+ match_token( token_then, "then" );
+ match_token( token_tristate, "tristate" );
+ break;
+
+ case 'u':
+ match_token( token_unset, "unset" );
+ break;
X }
X
- if( tok == tok_unknown)
+#undef match_token
+
+ if ( token == token_source )
X {
- if( clast != NULL && clast->tok == tok_if
- && strcmp(pnt,"then") == 0) return;
- if( current_file != NULL )
- fprintf(stderr, "unknown command=%s(%s %d)\n", pnt,
- current_file, lineno);
- else
- fprintf(stderr, "unknown command=%s(%d)\n", pnt,lineno);
- return;
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
+ do_source( pnt );
+ return;
X }
X
- /*
- * Allocate memory for this item, and attach it to the end of the linked
- * list.
- */
- kcfg = (struct kconfig *) malloc(sizeof(struct kconfig));
- memset(kcfg, 0, sizeof(struct kconfig));
- kcfg->tok = tok;
- if( clast != NULL )
+ if ( token == token_then )
X {
- clast->next = kcfg;
- clast = kcfg;
+ if ( config_last != NULL && config_last->token == token_if )
+ return;
+ syntax_error( "bogus 'then'" );
X }
- else
+
+ if ( token == token_unset )
X {
- clast = config = kcfg;
+ fprintf( stderr, "Ignoring 'unset' command\n" );
+ return;
X }
X
- pnt = skip_whitespace(pnt);
+ if ( token == token_UNKNOWN )
+ syntax_error( "unknown command" );
X
- /*
- * Now parse the remaining parts of the option, and attach the results
- * to the structure.
- */
- switch (tok)
- {
- case tok_choose:
- pnt = get_qstring(pnt, &kcfg->label);
- pnt = get_qstring(pnt, &kcfg->optionname);
- pnt = get_string(pnt, &kcfg->value);
- /*
- * Now we need to break apart the individual options into their
- * own configuration structures.
- */
- parse_choices(kcfg, kcfg->optionname);
- free(kcfg->optionname);
- sprintf(tmpbuf, "tmpvar_%d", choose_number++);
- kcfg->optionname = strdup(tmpbuf);


- break;
- case tok_define:

- pnt = get_string(pnt, &kcfg->optionname);
- if(*pnt == 'y' || *pnt == 'Y' ) kcfg->value = "1";
- if(*pnt == 'n' || *pnt == 'N' ) kcfg->value = "0";
- if(*pnt == 'm' || *pnt == 'M' ) kcfg->value = "2";
- break;
- case tok_menuname:
- pnt = get_qstring(pnt, &kcfg->label);
- break;


- case tok_bool:
- case tok_tristate:

- pnt = get_qstring(pnt, &kcfg->label);
- pnt = get_string(pnt, &kcfg->optionname);


- break;
- case tok_int:
- case tok_hex:
- case tok_string:

- pnt = get_qstring(pnt, &kcfg->label);
- pnt = get_string(pnt, &kcfg->optionname);
- pnt = get_string(pnt, &kcfg->value);
- break;
- case tok_dep_tristate:
- pnt = get_qstring(pnt, &kcfg->label);
- pnt = get_string(pnt, &kcfg->optionname);
- pnt = skip_whitespace(pnt);
+ /*
+ * Allocate an item.
+ */
+ cfg = malloc( sizeof(*cfg) );
+ memset( cfg, 0, sizeof(*cfg) );
+ if ( config_last == NULL )
+ { config_last = config_list = cfg; }
+ else
+ { config_last->next = cfg; config_last = cfg; }
X
- if ( ( pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' )
- && ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) {
- if ( pnt[0] == 'y' ) kcfg->depend.str = strdup( "CONSTANT_Y" );
- else if ( pnt[0] == 'm' ) kcfg->depend.str = strdup( "CONSTANT_M" );
- else kcfg->depend.str = strdup( "CONSTANT_N" );
- pnt++;
- } else if ( *pnt == '$' ) {
+ /*
+ * Tokenize the arguments.
+ */
+ while ( *pnt == ' ' || *pnt == '\t' )
X pnt++;
- pnt = get_string(pnt, &kcfg->depend.str);
- } else {
- fprintf( stderr, "Can't handle dep_tristate condition\n" );
- exit( 1 );
- }
-
- /*
- * Create a conditional for this object's dependency.
- *
- * We can't use "!= n" because this is internally converted to "!= 0"
- * and if UMSDOS depends on MSDOS which depends on FAT, then when FAT
- * is disabled MSDOS has 16 added to its value, making UMSDOS fully
- * available. Whew.
- *
- * This is more of a hack than a fix. Nested "if" conditionals are
- * probably affected too - that +/- 16 affects things in too many
- * places. But this should do for now.
- */
- sprintf(fake_if,"[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then",
- kcfg->depend.str,kcfg->depend.str);
- kcfg->cond = parse_if(fake_if);
- if(kcfg->cond == NULL )
+
+ cfg->token = token;
+ switch ( token )
+ {
+ default:
+ syntax_error( "unknown token" );


+
+ case token_bool:
+ case token_tristate:

+ pnt = get_qstring ( pnt, &cfg->label );
+ pnt = get_string ( pnt, &cfg->optionname );


+ break;
+
+ case token_choice_header:

X {
- exit(1);
+ static int choose_number = 0;
+ char * choice_list;
+
+ pnt = get_qstring ( pnt, &cfg->label );
+ pnt = get_qstring ( pnt, &choice_list );
+ pnt = get_string ( pnt, &cfg->value );
+
+ cfg->optionname = malloc( 32 );
+ sprintf( cfg->optionname, "tmpvar_%d", choose_number++ );
+
+ tokenize_choices( cfg, choice_list );
+ free( choice_list );
X }


- break;
- case tok_comment:

- pnt = get_qstring(pnt, &kcfg->label);
- if( koption != NULL )
- {
- pnt = get_qstring(pnt, &kcfg->label);
- koption->label = kcfg->label;
- koption = NULL;
+ break;
+
+ case token_comment:
+ pnt = get_qstring(pnt, &cfg->label);
+ if ( last_menuoption != NULL )
+ {
+ pnt = get_qstring(pnt, &cfg->label);
+ last_menuoption->label = cfg->label;
+ last_menuoption = NULL;
+ }


+ break;
+
+ case token_define_bool:

+ pnt = get_string( pnt, &cfg->optionname );
+#if ! defined(BUG_COMPATIBLE)
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
+#endif
+ if ( *pnt == 'n' || *pnt == 'N' ) cfg->value = "0";
+ else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = "1";
+ else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = "2";
+ else
+ {
+#if ! defined(BUG_COMPATIBLE)
+ syntax_error( "unknown define_bool value" );
+#else
+ /*
+ * This ought to give the same output as printf'ing
+ * through the null pointer ... I don't want to be
+ * SIGSEGV compatible!
+ */
+ cfg->value = "(null)";
+#endif
X }


- break;
- case tok_menuoption:

- if( strncmp(pnt, "next_comment", 12) == 0)


+ break;
+
+ case token_dep_tristate:

+ pnt = get_qstring ( pnt, &cfg->label );
+ pnt = get_string ( pnt, &cfg->optionname );
+
+ while ( *pnt == ' ' || *pnt == '\t' )
+ pnt++;
+
+ if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N'
+ || pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' )
+ && ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) )
X {
- koption = kcfg;
+ /* dep_tristate 'foo' CONFIG_FOO m */
+ if ( pnt[0] == 'Y' || pnt[0] == 'y' )
+ cfg->depend = strdup( "CONSTANT_Y" );
+ else if ( pnt[0] == 'M' || pnt[0] == 'm' )
+ cfg->depend = strdup( "CONSTANT_M" );
+ else
+ cfg->depend = strdup( "CONSTANT_N" );
+ pnt++;
X }
- else
+ else if ( *pnt == '$' )
X {
- pnt = get_qstring(pnt, &kcfg->label);
+ pnt++;
+ pnt = get_string( pnt, &cfg->depend );
X }
- break;
- case tok_else:
- case tok_fi:
- case tok_endmenu:
- break;


- case tok_if:
- /*

- * Conditionals are different. For the first level parse, only
- * tok_if and tok_dep_tristate items have a ->cond chain attached.
- */
- kcfg->cond = parse_if(pnt);
- if(kcfg->cond == NULL )
+ else
X {
- exit(1);
+ syntax_error( "can't handle dep_tristate condition" );
X }
- break;
- default:
- exit(0);
- }
-
- return;
-}
X
-/*
- * Simple function to dump to the screen what the condition chain looks like.
- */
-void dump_if(struct condition * cond)
-{
- printf(" ");


- while(cond != NULL )

- {
- switch(cond->op){
- case op_eq:
- printf(" = ");


- break;
- case op_bang:
- printf(" ! ");
- break;

- case op_neq:
- printf(" != ");

+ /*
+ * Create a conditional for this object's dependency.
+ */
+ {
+ char fake_if [1024];
+ sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then",


+ cfg->depend, cfg->depend );

+ cfg->cond = tokenize_if( fake_if );
+ }
X break;
- case op_and:
- printf(" -a ");
+
+ case token_else:
+ case token_endmenu:
+ case token_fi:
X break;


- case op_lparen:
- printf("(");

+
+ case token_hex:
+ case token_int:
+ case token_string:

+ pnt = get_qstring ( pnt, &cfg->label );
+ pnt = get_string ( pnt, &cfg->optionname );
+ pnt = get_string ( pnt, &cfg->value );
X break;


- case op_rparen:
- printf(")");

+
+ case token_if:
+ cfg->cond = tokenize_if( pnt );
X break;


- case op_variable:
- printf("$%s", cond->variable.str);

+
+ case token_mainmenu_name:
+ pnt = get_qstring( pnt, &cfg->label );
X break;
- case op_constant:


- printf("'%s'", cond->variable.str);

+
+ case token_mainmenu_option:
+ if ( strncmp( pnt, "next_comment", 12 ) == 0 )
+ last_menuoption = cfg;
+ else
+ pnt = get_qstring( pnt, &cfg->label );
X break;


- default:
- break;
- }
- cond = cond->next;

X }
X
- printf("\n");
+ return;
X }
X
-static int do_source(char * filename)
+
+
+/*
+ * Implement the "source" command.
+ */
+static void do_source( const char * filename )
X {
- char buffer[1024];
- int offset;
- int old_lineno;
- char * old_file = 0; /* superfluous, just for gcc */
- char * pnt;
- FILE * infile;
-
- if( strcmp(filename, "-") == 0 )
- infile = stdin;
- else
- infile = fopen(filename,"r");
-
- /*
- * If our cwd was in the scripts directory, we might have to go up one
- * to find the sourced file.
- */
- if(!infile) {
- strcpy (buffer, "../");
- strcat (buffer, filename);
- infile = fopen(buffer,"r");
- }
-
- if(!infile) {
- fprintf(stderr,"Unable to open file %s\n", filename);
- return 1;
- }
- old_lineno = lineno;
- lineno = 0;
- if( infile != stdin ) {
- old_file = current_file;
- current_file = filename;
- }
- offset = 0;
- while(1)
- {
- fgets(&buffer[offset], sizeof(buffer) - offset, infile);
- if(feof(infile)) break;
-
- /*
- * Strip the trailing return character.
- */
- pnt = buffer + strlen(buffer) - 1;
- if( *pnt == '\n') *pnt-- = 0;
- lineno++;
- if( *pnt == '\\' )
- {
- offset = pnt - buffer;
- }
- else
- {
- parse(buffer);
- offset = 0;
- }
+ char buffer [1024];
+ FILE * infile;
+ const char * old_file;
+ int old_lineno;
+ int offset;
+
+ /* open the file */
+ if ( strcmp( filename, "-" ) == 0 )
+ infile = stdin;
+ else
+ infile = fopen( filename, "r" );
+
+ /* if that failed, try ../filename */
+ if ( infile == NULL )
+ {
+ sprintf( buffer, "../%s", filename );
+ infile = fopen( buffer, "r" );
X }
- if( infile != stdin ) {
- fclose(infile);
- current_file = old_file;
- }
- lineno = old_lineno;
- return 0;
-}
X
-int main(int argc, char * argv[])
-{
-#if 0
- char buffer[1024];
- char * pnt;


- struct kconfig * cfg;

- int i;
+ if ( infile == NULL )
+ {
+ sprintf( buffer, "unable to open %s", filename );
+#if defined(BUG_COMPATIBLE)
+ fprintf( stderr, "%s\n", buffer );
+ return;
+#else
+ syntax_error( buffer );
X #endif
+ }
+
+ /* push the new file name and line number */
+ old_file = current_file;
+ old_lineno = lineno;
+ current_file = filename;
+ lineno = 0;
X
- /*
- * Read stdin to get the top level script.
- */
- do_source("-");
-
- if( menus_seen == 0 )
- {
- fprintf(stderr,"The config.in file for this platform does not support\n");
- fprintf(stderr,"menus.\n");
- exit(1);
- }
- /*
- * Input file is now parsed. Next we need to go through and attach
- * the correct conditions to each of the actual menu items and kill
- * the if/else/endif tokens from the list. We also flag the menu items
- * that have other things that depend upon its setting.
- */
- fix_conditionals(config);
-
- /*
- * Finally, we generate the wish script.
- */
- dump_tk_script(config);


-
-#if 0
- /*

- * Now dump what we have so far. This is only for debugging so that
- * we can display what we think we have in the list.
- */
- for(cfg = config; cfg; cfg = cfg->next)
+ /* read and process lines */
+ for ( offset = 0; ; )
X {
+ char * pnt;
X
- if(cfg->cond != NULL && cfg->tok != tok_if)
- dump_if(cfg->cond);
+ /* read a line */
+ fgets( buffer + offset, sizeof(buffer) - offset, infile );
+ if ( feof( infile ) )
+ break;
+ lineno++;
X
- switch(cfg->tok)
- {
- case tok_menuname:
- printf("main_menuname ");


- break;
- case tok_bool:

- printf("bool ");
- break;
- case tok_tristate:
- printf("tristate ");
- break;
- case tok_dep_tristate:
- printf("dep_tristate ");
- break;
- case tok_int:
- printf("int ");
- break;
- case tok_hex:
- printf("hex ");
- break;
- case tok_string:
- printf("istring ");
- break;
- case tok_comment:
- printf("comment ");
- break;
- case tok_menuoption:
- printf("menuoption ");
- break;
- case tok_else:
- printf("else");


- break;
- case tok_fi:

- printf("fi");
- break;
- case tok_if:
- printf("if");


- break;
- default:
- }

+ /* strip the trailing return character */
+ pnt = buffer + strlen(buffer) - 1;
+ if ( *pnt == '\n' )
+ *pnt-- = '\0';
X
- switch(cfg->tok)
+ /* eat \ NL pairs */
+ if ( *pnt == '\\' )
X {
- case tok_menuoption:
- case tok_comment:
- case tok_menuname:
- printf("%s\n", cfg->label);
- break;


- case tok_bool:
- case tok_tristate:
- case tok_dep_tristate:
- case tok_int:
- case tok_hex:
- case tok_string:

- printf("%s %s\n", cfg->label, cfg->optionname);
- break;
- case tok_if:
- dump_if(cfg->cond);
- break;
- case tok_nop:
- case tok_endmenu:
- break;
- default:
- printf("\n");
+ offset = pnt - buffer;
+ continue;
X }
+
+ /* tokenize this line */
+ tokenize_line( buffer );
+ offset = 0;
X }
-#endif
X
- return 0;
+ /* that's all, folks */
+ if ( infile != stdin )
+ fclose( infile );
+ current_file = old_file;
+ lineno = old_lineno;
+ return;
+}
+
+
X
+/*
+ * Main program.
+ */
+int main( int argc, const char * argv [] )
+{
+ do_source ( "-" );
+ fix_conditionals ( config_list );
+ dump_tk_script ( config_list );
+ return 0;
X }
diff -u --recursive --new-file v2.2.0-pre8/linux/scripts/tkparse.h linux/scripts/tkparse.h
--- v2.2.0-pre8/linux/scripts/tkparse.h Tue Jan 19 11:32:54 1999
+++ linux/scripts/tkparse.h Wed Jan 20 10:05:49 1999
@@ -1,82 +1,112 @@
+/*
+ * tkparse.h
+ */
X
-enum token {
- tok_menuname,
- tok_menuoption,
- tok_comment,
- tok_bool,
- tok_tristate,
- tok_dep_tristate,
- tok_nop,
- tok_if,
- tok_else,
- tok_fi,
- tok_int,
- tok_hex,
- tok_string,
- tok_define,
- tok_choose,
- tok_choice,
- tok_endmenu,
- tok_unknown
-};
+/*
+ * Define this symbol to generate exactly the same output, byte for byte,
+ * as the previous version of xconfig. I need to do this to make sure I
+ * I don't break anything in my moby edit. -- mec
+ */
X
-enum operator {
- op_eq,
- op_neq,
- op_and,
- op_and1,
- op_or,
- op_bang,
- op_lparen,
- op_rparen,
- op_variable,
- op_kvariable,
- op_shellcmd,
- op_constant,
- op_nuked
+#define BUG_COMPATIBLE
+
+/*
+ * Token types (mostly statement types).
+ */
+
+enum e_token
+{
+ token_UNKNOWN,
+ token_bool,
+ token_choice_header,
+ token_choice_item,
+ token_comment,
+ token_define_bool,
+ token_dep_tristate,
+ token_else,
+ token_endmenu,
+ token_fi,
+ token_hex,
+ token_if,
+ token_int,
+ token_mainmenu_name,
+ token_mainmenu_option,
+ token_source,
+ token_string,
+ token_then,
+ token_tristate,
+ token_unset,
X };
X
-union var
+/*
+ * Operator types for conditionals.
+ */
+
+enum operator
X {
- char * str;


- struct kconfig * cfg;

+ op_eq,
+ op_neq,
+ op_and,
+ op_and1,
+ op_or,
+ op_bang,
+ op_lparen,
+ op_rparen,
+ op_constant,
+ op_variable,
+ op_kvariable,
+ op_nuked
X };
X
+/*
+ * Conditions come in linked lists.
+ * Some operators take strings:
+ *
+ * op_constant "foo"
+ * op_variable "$ARCH", "$CONFIG_PMAC"
+ * op_kvariable "$CONFIG_EXPERIMENTAL"
+ *
+ * Most "$..." constructs refer to a variable which is defined somewhere
+ * in the script, so they become op_kvariable's instead. Note that it
+ * is legal to test variables which are never defined, such as variables
+ * that are meaningful only on other architectures.
+ */
+
X struct condition
X {
- struct condition * next;
- enum operator op;
- union var variable;
+ struct condition * next;
+ enum operator op;
+ const char * str; /* op_constant, op_variable */
+ struct kconfig * cfg; /* op_kvariable */
X };
X
-#define GLOBAL_WRITTEN 1
-#define CFG_DUP 2
-#define UNSAFE 4
+/*
+ * A statement from a config.in file
+ */
X
X struct kconfig
X {
- struct kconfig * next;
- int flags;
- enum token tok;
- int menu_number;
- int menu_line;
- int submenu_start;
- int submenu_end;
- char * optionname;
- char * label;
- char * value;
- int choice_value;
- struct kconfig * choice_label;
- union var depend;


- struct condition * cond;

+ struct kconfig * next;
+ enum e_token token;
+ char * optionname;
+ char * label;
+ char * value;


+ struct condition * cond;

+ char * depend; /* token_dep_tristate */
+ struct kconfig * cfg_parent; /* token_choice_item */
+
+ /* used only in tkgen.c */
+ char global_written;
+ int menu_number;
+ int menu_line;
+ struct kconfig * menu_next;
X };
X
-extern struct kconfig * config;
-extern struct kconfig * clast;
-extern struct kconfig * koption;
+
X
X /*
X * Prototypes
X */
-void fix_conditionals(struct kconfig * scfg); /* tkcond.c */
-void dump_tk_script(struct kconfig *scfg); /* tkgen.c */
+
+extern void fix_conditionals ( struct kconfig * scfg ); /* tkcond.c */
+extern void dump_tk_script ( struct kconfig * scfg ); /* tkgen.c */


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre9 failed'

echo 'File patch-2.2.0-pre9 is complete' &&
chmod 644 patch-2.2.0-pre9 ||


echo 'restore of patch-2.2.0-pre9 failed'

Cksum="`cksum < 'patch-2.2.0-pre9'`"
if ! test " 778691712 838284" = "$Cksum"
then
echo 'patch-2.2.0-pre9: original Checksum 778691712 838284, current one' "$Cksum"
rm -f _shar_wnt_.tmp
rm -f _shar_seq_.tmp
exit 1
fi
rm -f _shar_wnt_.tmp
fi
rm -f _shar_seq_.tmp
echo 'You have unpacked the last part.'

0 new messages