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

11 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