diff -u --recursive --new-file v2.1.125/linux/CREDITS linux/CREDITS --- v2.1.125/linux/CREDITS Fri Oct 9 13:27:04 1998 +++ linux/CREDITS Tue Oct 20 14:17:45 1998 @@ -210,9 +210,11 @@ S: Australia N: Philip Blundell -E: Philip.Blundell@pobox.com -D: Device driver hacking -D: Some Linux/ARM stuff +E: philb@gnu.org +D: Linux/ARM hacker +D: Device driver hacker (eexpress, 3c505, c-qcam, ...) +D: m68k port to HP9000/300 +D: AUN network protocols D: Co-architect of the parallel port sharing system S: Nexus Electronics Ltd S: 10 St Barnabas Road, Cambridge CB1 2BY @@ -1304,7 +1306,7 @@ S: USA N: Johan Myreen -E: jem@vipunen.hut.fi +E: jem@iki.fi D: PS/2 mouse driver writer etc. S: Dragonvagen 1 A 13 S: FIN-00330 Helsingfors @@ -1852,6 +1854,18 @@ S: 90491 Nuernberg S: Germany +N: Geert Uytterhoeven +E: geert@linux-m68k.org +W: http://www.cs.kuleuven.ac.be/~geert/ +P: 1024/EC4A1EE1 8B 88 38 35 88 1E 95 A1 CD 9E AE DC 4B 4A 2F 41 +D: m68k/Amiga and PPC/CHRP Longtrail coordinator +D: Frame buffer device and XF68_FBDev maintainer +D: m68k IDE maintainer +D: Amiga Zorro maintainer +S: C. Huysmansstraat 12 +S: B-3128 Baal +S: Belgium + N: Petr Vandrovec E: vandrove@vc.cvut.cz D: Small contributions to ncpfs @@ -1991,14 +2005,15 @@ S: The Netherlands N: David Woodhouse +E: Dave@mvhi.com E: Dave@imladris.demon.co.uk D: Extensive ARCnet rewrite D: ARCnet COM20020, COM90xx IO-MAP drivers D: SO_BINDTODEVICE in 2.1.x (from Elliot Poger's code in 2.0.31) D: Contributed to NCPFS rewrite for 2.1.x dcache D: Alpha platforms: SX164, LX164 and Ruffian ported to 2.1.x -S: Robinson College, Grange Road -S: Cambridge. CB3 9AN +S: 29, David Bull Way +S: Milton, Cambridge. CB4 6DP S: England N: Frank Xia diff -u --recursive --new-file v2.1.125/linux/Documentation/Changes linux/Documentation/Changes --- v2.1.125/linux/Documentation/Changes Mon Oct 5 13:13:34 1998 +++ linux/Documentation/Changes Tue Oct 20 13:18:23 1998 @@ -33,7 +33,7 @@ Also, don't forget http://www.linuxhq.com/ for all your Linux kernel needs. -Last updated: September 3, 1998 +Last updated: October 9, 1998 Current Author: Chris Ricker (kaboom@gatech.edu or chris.ricker@m.cc.utah.edu). Current Minimal Requirements @@ -43,13 +43,14 @@ encountered a bug! If you're unsure what version you're currently running, the suggested command should tell you. -- Kernel modules 2.1.85 ; insmod -V +- Kernel modules 2.1.121 ; insmod -V - Gnu C 2.7.2.3 ; gcc --version - Binutils 2.8.1.0.23 ; ld -v -- Linux C Library 5.4.46 ; ls -l /lib/libc.so.* +- Linux libc5 C Library 5.4.46 ; ls -l /lib/libc.so.* +- Linux libc6 C Library 2.0.7pre6 ; ls -l /lib/libc.so.* - Dynamic Linker (ld.so) 1.9.9 ; ldd --version or ldd -v - Linux C++ Library 2.7.2.8 ; ls -l /usr/lib/libg++.so.* -- Procps 1.2.8 ; ps --version +- Procps 1.2.9 ; ps --version - Procinfo 14 ; procinfo -v - Psmisc 17 ; pstree -V - Mount 2.7l ; mount --version @@ -57,11 +58,12 @@ - Loadlin 1.6a - Sh-utils 1.16 ; basename --v - Autofs 0.3.11 ; automount --version -- NFS 0.4.21 ; showmount --version +- NFS 2.2beta37 ; showmount --version - Bash 1.14.7 ; bash -version - Ncpfs 2.2.0 ; ncpmount -v - Pcmcia-cs 3.0.5 ; cardmgr -V - PPP 2.3.5 ; pppd -v +- PCI Utilities 1.08 ; lspci --version Upgrade notes ************* @@ -114,8 +116,8 @@ more information, see the files in Documentation/fb/ ; you may also need to download the fbset utilities. -Libc -==== +Libc (libc5) +============ Linux-2.1.x is ELF-only. You can still compile a.out apps if you really want, but your kernel must be compiled ELF. If you can't @@ -144,11 +146,25 @@ accompanying release notes. The section about it breaking make is not a joke. +GNU libc (libc6) +================ + + Older versions of GNU libc (libc6) have a bug in the dynamic linker. +/etc/ld.so.cache gets mapped into memory and is never unmapped. If one +of your boot scripts calls ldconfig, /etc/ld.so.cache is deleted. Init, +however, still references that file; as of 2.1.122, the kernel will +consequently not be able to remount the root file system r/o at system +shutdown. To fix this, upgrade to at least the pre6 release of GNU +libc 2.0.7. As a temporary workaround, modify your boot scripts to do +the following before calling ldconfig: + + ln -f /etc/ld.so.cache /etc/ld.so.cache.old + Modules ======= - You need to upgrade to modutils-2.1.85 for kernels 2.1.85 and later. -This version will also work with 2.0.x kernels. + 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. As of 2.1.90-pre1, kerneld has been replaced by a kernel thread, kmod. See Documentation/kmod.txt for more information. The main @@ -222,12 +238,12 @@ features like IPv6. As of 2.1.102, the IP firewalling code has been replaced; ipfwadm -will no longer work. You need to optain "ipchains," available from +will no longer work. You need to obtain "ipchains," available from http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html, and use that instead of ipfwadm. - To use port forwarding and auto forwarding you will need 'ipmasqadm' -tool, available from http://juanjox.home.ml.org. + To use port forwarding and auto forwarding you will need to obtain +"ipmasqadm," available from http://juanjox.home.ml.org/. Memory ====== @@ -281,6 +297,13 @@ /dev/lp0 with the new Plug-and-Play driver. If printing breaks with the new driver, try checking your lpd configuration. +Setserial +========= + + If you experience random problems (stuck lines, lost characters, +etc.) with serial lines under recent kernels, upgrading setserial +should help. + Syncookies ========== @@ -351,35 +374,28 @@ ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.8.1.0.23 ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.8.1.0.23 -The 2.9.1.0.7 release: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.7-glibc.x86.tar.gz -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.7-libc5.x86.tar.gz -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.7.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.7-glibc.x86.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.7-libc5.x86.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.7.tar.gz +The 2.9.1.0.12 release: +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.12-glibc.x86.tar.gz +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.12-libc5.x86.tar.gz +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.12.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.12-glibc.x86.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.12-libc5.x86.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.12.tar.gz Installation notes: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.9.1.0.7 -ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.9.1.0.7 +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.9.1.0.12 +ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.9.1.0.12 Gnu C ===== -The 2.7.2.3 release: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/gcc-2.7.2.3.bin.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/gcc-2.7.2.3.bin.tar.gz -Installation notes: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.gcc-2.7.2.3 -ftp://sunsite.unc.edu/pub/Linux/GCC/release.gcc-2.7.2.3 - -The egcs-1.0.2 release: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/egcs-1.0.2-glibc.x86.tar.gz -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/egcs-1.0.2-libc5.x86.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/egcs-1.0.2-glibc.x86.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/egcs-1.0.2-libc5.x86.tar.gz +The egcs-1.0.3 release: +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/egcs-1.0.3-glibc.x86.tar.bz2 +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/egcs-1.0.3-libc5.x86.tar.bz2 +ftp://sunsite.unc.edu/pub/Linux/GCC/egcs-1.0.3-glibc.x86.tar.bz2 +ftp://sunsite.unc.edu/pub/Linux/GCC/egcs-1.0.3-libc5.x86.tar.bz2 Installation notes: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.egcs-1.0.2 -ftp://sunsite.unc.edu/pub/Linux/GCC/release.egcs-1.0.2 +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.egcs-1.0.3 +ftp://sunsite.unc.edu/pub/Linux/GCC/release.egcs-1.0.3 Gnu C 2.7.2.3 source: ftp://prep.ai.mit.edu/pub/gnu/gcc-2.7.2.3.tar.gz @@ -388,13 +404,17 @@ Linux C Library =============== -The 5.4.46 release: +The (libc5) 5.4.46 release: ftp://tsx-11.mit.edu/pub/linux/packages/GCC/libc-5.4.46.bin.tar.gz ftp://sunsite.unc.edu/pub/Linux/GCC/libc-5.4.46.bin.tar.gz Installation notes for 5.4.46: ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.libc-5.4.46 ftp://sunsite.unc.edu/pub/Linux/GCC/release.libc-5.4.46 +The (libc6) GNU libc 2.0.7pre6 release: +ftp://ftp.kernel.org/pub/software/libs/glibc/glibc-2.0.7pre6.tar.gz +ftp://ftp.kernel.org/pub/software/libs/glibc/glibc-2.0.7pre6.tar.bz2 + Linux C++ Library ================= @@ -415,15 +435,15 @@ Modules utilities ================= -The 2.1.85 release: -ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.85.tar.gz +The 2.1.121 release: +ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.121.tar.gz Procps utilities ================ The 1.2 release: -ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/procps-1.2.8.tar.gz -ftp://sunsite.unc.edu/pub/Linux/system/status/ps/procps-1.2.8.tgz +ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/procps-1.2.9.tar.gz +ftp://sunsite.unc.edu/pub/Linux/system/status/ps/procps-1.2.9.tgz Procinfo utilities ================== @@ -454,8 +474,9 @@ DOSEMU ====== -The 0.66.7 release: -ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu-0.66.7.tgz +The 0.98.1 release: +ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/dosemu-0.98.1.tgz +ftp://ftp.dosemu.org/dosemu/dosemu-0.98.1.tgz Loadlin ======= @@ -486,12 +507,13 @@ NFS === -The user-land 0.4.21 release: -ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/linux-nfs-0.4.21.tar.gz -ftp://linux.nrao.edu/mirrors/fb0429.mathematik.th-darmstadt.de/pub/linux/okir/linux-nfs-0.4.21.tar.gz - -The kernel-level 8/30/98 release: -ftp://ftp.yggdrasil.com/private/hjl/knfsd-980830.tar.gz +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 kernel-level 9/30/98 release: +ftp://ftp.yggdrasil.com/private/hjl/knfsd-980930.tar.gz +ftp://ftp.kernel.org/pub/linux/devel/gcc/knfsd-980930.tar.gz Net-tools ========= @@ -530,6 +552,13 @@ The 3.0.5 release: ftp://hyper.stanford.edu/pub/pcmcia/pcmcia-cs.3.0.5.tar.gz +Setserial +========= + +The 2.14 release: +ftp://tsx-11.mit.edu/pub/linux/sources/sbin/setserial-2.14.tar.gz +ftp://sunsite.unc.edu/pub/Linux/system/serial/setserial-2.14.tar.gz + PPP === @@ -545,6 +574,7 @@ IP Masq Adm =========== + The 0.4.1 release: http://juanjox.home.ml.org/ipmasqadm-0.4.1.tar.gz @@ -566,6 +596,13 @@ The 7/13/98 release: http://www.cs.kuleuven.ac.be/~geert/bin/fbset-2.0-pre-19980713.tar.gz +PCIutils +======== + +The 1.08 release: +ftp://atrey.karlin.mff.cuni.cz/pub/linux/pci/pciutils-1.08.tar.gz +ftp://sunsite.unc.edu/pub/Linux/hardware/pciutils-1.08.tar.gz + Other Info ========== @@ -581,12 +618,12 @@ your favorite Red Hat mirror site before installing the non-RPM version. Remember, you might need to use the -force option to get the upgrade to install. ftp://ftp.redhat.com/pub/contrib/ will have almost -everything you need, as does Red Hat 5.0. +everything you need, and Red Hat 5.1 ships with most necessary software. Those of you running Debian (or a different distribution that supports .deb packages) can look in the "unstable" and "project/experimental" directories of your favorite Debian mirror. The -Debian 2.0 release should have most packages you need as well. +Debian 2.0 release ships with most packages you need as well. For others, David Bourgin has put together a package of everything necessary to quickly and easily upgrade to 2.1.x. See diff -u --recursive --new-file v2.1.125/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.125/linux/Documentation/Configure.help Fri Oct 9 13:27:04 1998 +++ linux/Documentation/Configure.help Wed Oct 21 15:31:04 1998 @@ -850,6 +850,26 @@ here and read Documentation/modules.txt. The module will be called raid0.o. If unsure, say Y. +Are you using a crosscompiler +CONFIG_CROSSCOMPILE + Set this if you are using another architecture to compile the + kernel for your MIPS machine. + +Support for Acer PICA 1 chipset +CONFIG_ACER_PICA_61 + This is a machine with a R4400 133/150 MHz CPU. To compile a Linux + kernel that runs on these, say Y here. For details about Linux on + the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at + http://lena.fnet.fr/ (To browse the WWW, you need to have access to + a machine on the Internet that has a program like lynx or + netscape). + +Support for Algorithmics P4032 +CONFIG_ALGOR_P4032 + This is an evaluation board of the British company Algorithmics. The + board uses the R4300 and a R5230 CPUs. For more information about + this board see www.algor.co.uk. + RAID-1 (mirroring) mode CONFIG_MD_MIRRORING A RAID-1 set consists of several disk drives which are exact copies @@ -871,6 +891,11 @@ want to compile it as a module, say M here and read Documentation/modules.txt. If unsure, say Y. +Boot support (linear, striped) +CONFIG_MD_BOOT + To boot with an initial linear or striped md device you have to say + Y here. For lilo and loadlin options see Documentation/md.txt. + RAID-4/RAID-5 mode CONFIG_MD_RAID5 A RAID-5 set of N drives with a capacity of C MB per drive provides @@ -892,28 +917,6 @@ want to compile it as a module, say M here and read Documentation/modules.txt. If unsure, say Y. -Boot support (linear, striped) -CONFIG_MD_BOOT - To boot with an initial linear or striped md device you have to say - Y here. For lilo and loadlin options see Documentation/md.txt. - -Support for Deskstation RPC44 -CONFIG_DESKSTATION_RPC44 - This is a machine with a R4400 100 MHz CPU. To compile a Linux - kernel that runs on these, say Y here. For details about Linux - on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - http://lena.fnet.fr/ (To browse the WWW, you need to - have access to a machine on the Internet that has a program like - lynx or netscape). - -Support for Mips Magnum 3000 -CONFIG_MIPS_MAGNUM_3000 - To compile a Linux kernel that runs on these machines, say Y here. - For details about Linux on the MIPS architecture, check out the - Linux/MIPS FAQ on the WWW at http://lena.fnet.fr/ (To browse the - WWW, you need to have access to a machine on the Internet that has a - program like lynx or netscape). - Support for Mips Magnum 4000 CONFIG_MIPS_MAGNUM_4000 This is a machine with a R4000 100 MHz CPU. To compile a Linux @@ -930,39 +933,29 @@ http://lena.fnet.fr/ (To browse the WWW, you need to have access to a machine on the Internet that has a program like lynx or netscape). -Support for Deskstation Tyne -CONFIG_DESKSTATION_TYNE - This is a machine with a R4600 134 MHz CPU. The Linux port for this - system is idle right now because of hardware or documentation - problems. For details about Linux on the MIPS architecture, check - out the Linux/MIPS FAQ on the WWW at http://lena.fnet.fr/ (To browse - the WWW, you need to have access to a machine on the Internet that - has a program like lynx or netscape). - -Support for Acer PICA 1 chipset -CONFIG_ACER_PICA_61 - This is a machine with a R4400 134/150 MHz CPU. To compile a Linux - kernel that runs on these, say Y here. For details about Linux on - the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - http://lena.fnet.fr/ (To browse the WWW, you need to have access to - a machine on the Internet that has a program like lynx or - netscape). - -Support for DECstation -CONFIG_DECSTATION - The DECstation 3100 (with a MIPS R2000 series CPU) and DECstation - 5000/xxx (MIPS R3000 series CPU) are also sometimes labeled - PMAX. They often run the Ultrix operating system. To compile a Linux - kernel that runs on these, say Y here. For details about Linux on - the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - http://lena.fnet.fr/ (To browse the WWW, you need to have access to - a machine on the Internet that has a program like lynx or netscape). - CPU type CONFIG_CPU_R3000 Give the type of your machine's MIPS CPU. For this question, it suffices to give a unique prefix of the option you want to - choose. + choose. In case of doubt select the R3000 CPU. This kernel will + run on other MIPS machines but with slightly reduced performance. + +Compile the kernel into the ECOFF object format +CONFIG_ECOFF_KERNEL + Some machines require a kernel in the ECOFF format. You will have to + Choose this option for example if you want to a Mips Magnum 3000 or a + DECstation over network. + +Generate little endian code +CONFIG_CPU_LITTLE_ENDIAN + Some MIPS machines can be configured for either little or big endian + byte order. Both modes require different kernels. Say yes if your + machine is little endian, no if it's a big endian machine. + +Kernel support for IRIX binaries +CONFIG_BINFMT_IRIX + This option enables the kernel support for IRIX binaries. Running + IRIX binaries additionally requires IRIX libraries. Networking support CONFIG_NET @@ -1191,20 +1184,29 @@ servicing. Say Y here to enable the serial driver to take advantage of those special I/O ports. +SGI Zilog85C30 serial support +CONFIG_SGI_SERIAL + If you want to use your SGI's built-in serial ports under Linux, say Y. + +SGI graphics support +CONFIG_SGI_GRAPHICS + If you have an SGI machine and you want to compile the graphic drivers + select this option. This will include the code for the /dev/graphics + and /dev/gfx drivers into the kernel for supporting the virtualized + access to your graphics hardware. + +Remote GDB kernel debugging +CONFIG_REMOTE_DEBUG + This enables remote debugging support for the MIPS kernel. Enabling + this option enlarges you kernel image disk size by several megabytes + and requires a machine with more than 16mb, better 32mb RAM to avoid + excessive linking time. + Support the Bell Technologies HUB6 card CONFIG_HUB6 Say Y here to enable support in the dumb serial driver to support the HUB6 card. -TGA Console Support -CONFIG_TGA_CONSOLE - Many Alpha systems (e.g the Multia) are shipped with a graphics card - that implements the TGA interface (much like the VGA standard, but - older TGA adapters are *not* VGA compatible). On such systems, you - should say Y here so that the TGA driver rather than the standard - VGA driver is used. Note that, at this time, there is no X server - for these systems. If unsure, try N. - PCI support CONFIG_PCI Find out whether you have a PCI motherboard. PCI is the name of a @@ -1866,6 +1868,12 @@ be necessary to run older Mips systems, such as the Sony News and MIPS RC3xxx, in big endian mode. +Build fp execption handler module +CONFIG_MIPS_FPE_MODULE + Build the floating point exception handler module. This option is only + useful for people working on the floating point exception handler. If + you don't, say n. + Plug and Play support CONFIG_PNP Plug and Play support allows the kernel to automatically configure @@ -3217,6 +3225,16 @@ This is a backward compatibility option, choose Y for now. This option will be removed soon. +HIgh Performance Parallel Interface support (EXPERIMENTAL) +CONFIG_HIPPI + HIgh Performance Parallel Interface (HIPPI) is a 800Mbit/sec and + 1600Mbit/sec dual-simplex switched or point-to-point network. HIPPI + can run over copper (25m) or fiber (300m on multi-mode or 10km on + single-mode). If you are connected to a HIPPI network, and want + to enable HIPPI support in the kernel, say Y here (you must also + remember to enable the driver for your HIPPI card below). Most + people will say N here. + SCSI support? CONFIG_SCSI If you want to use a SCSI hard disk, SCSI tape drive, SCSI CDROM or @@ -4108,6 +4126,11 @@ your EPP chipset is from the SMC series, you are likely to have to set this value greater than 0. +SGI wd93 Scsi Driver +CONFIG_SCSI_SGIWD93 + This is the SCSI driver for WD33C93 / WD33C95 SCSI chips used in many + SGI machines. + SCSI Debug host simulator. CONFIG_SCSI_DEBUG This is a host adapter simulator that can be programmed to simulate @@ -5312,7 +5335,7 @@ This is yet another chipset driver for the COM90xx cards, but this time only using memory-mapped mode, and no IO ports at all. This driver is completely untested, so if you have one of these cards, - please mail dwmw2@cam.ac.uk, especially if it works! + please mail David.Woodhouse@mvhi.com, especially if it works! This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you @@ -5838,6 +5861,10 @@ This is support for the DIGITAL series of EISA (DEFEA) and PCI (DEFPA) controllers which can connect you to a local FDDI network. +SGI Seeq ethernet controller support + This is a driver for the Seeq based Ethernet adapters used in many + Silicon Graphics machines. + Acorn Ether1 card CONFIG_ARM_ETHER1 If you have an Acorn system with one of these (AKA25) network cards, @@ -6387,6 +6414,12 @@ The module is called nfsd.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. If unsure, say N. +Emulate Sun NFS daemon +CONFIG_NFSD_SUN + If you would like for the server to allow clients to access + directories that are mountpoints on the local filesystem (this is + how nfsd behaves on Sun systems), say yes here. If unsure, say N. + OS/2 HPFS filesystem support (read only) CONFIG_HPFS_FS OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS @@ -8187,7 +8220,7 @@ say more than an occasional beep, by programming the PC speaker. Kernel patches and programs to do that are in the pcsndrv package on ftp://sunsite.unc.edu/pub/Linux/kernel/patches/console/ and in the - pcsp patch at ftp://dwmw2.robinson.cam.ac.uk/pub/kernel/ . + pcsp patch at http://www.imladris.demon.co.uk/pcsp/ OSS sound modules CONFIG_SOUND_OSS @@ -9261,7 +9294,7 @@ Ariadne support CONFIG_ARIADNE - If you have a VillageTronics Ariadne Ethernet adapter, say Y. + If you have a Village Tronic Ariadne Ethernet adapter, say Y. Otherwise, say N. This driver is also available as a module ( = code which can be @@ -9271,7 +9304,7 @@ Ariadne II support CONFIG_ARIADNE2 - If you have a VillageTronics Ariadne II Ethernet adapter, say Y. + If you have a Village Tronic Ariadne II Ethernet adapter, say Y. Otherwise, say N. This driver is also available as a module ( = code which can be @@ -9745,6 +9778,46 @@ Say 'Y' here for ARM systems with the VIDC video controller and 16-bit Linear sound DACs. If unsure, say N. +Backward compatibility mode for Xpmac +CONFIG_FB_COMPAT_XPMAC + If you use the Xpmac X server (common with mklinux), you'll need + to enable this to use X. You should consider changing to XFree86 + which includes a server that supports the frame buffer device + directly (XF68_FBDev). + +Support for PowerMac keyboard +CONFIG_MAC_KEYBOARD + This option allows you to use an ADB keyboard attached to your + machine. Note that this disables any other (ie. PS/2) keyboard + support, even if your machine is physically capable of using both + at the same time. + + If you use an ADB keyboard (4 pin connector), say Y here. + If you use a PS/2 keyboard (6 pin connector), say N here. + +Support for PowerMac floppy +CONFIG_MAC_FLOPPY + If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple) + floppy controller, say Y here. Most commonly found in PowerMacs. + +Support for PowerMac serial ports +CONFIG_MAC_SERIAL + If you have Macintosh style serial ports (8 pin mini-DIN), this + is the driver for them. If you also have regular serial ports + and enable the driver for them, you can't currently use the + serial console feature. + +Support for PowerMac ADB mouse +CONFIG_ADBMOUSE + If you have an ADB mouse (4 pin connector) as is common on + Macintoshes, say Y here. + +Winbond SL82c105 support +CONFIG_BLK_DEV_SL82C105 + If you have a Winbond SL82c105 IDE controller, say Y here to + enable special configuration for this chip. This is common + on various CHRP motherboards, but could be used elsewhere. + If in doubt, say Y. # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DMA, FTP, Internet, Intel, IRQ, @@ -9853,7 +9926,7 @@ # LocalWords: INSNS Ataris AutoConfig ZORRO OCS AMIFB Agnus Denise ECS CDTV GB # LocalWords: AGA Cybervision CYBER GSP TMS DMI Zorro ACSI ROMs SLM BioNet GVP # LocalWords: PAMsNet TekMagic Cyberstorm MkI CYBERSTORMII MkII BLZ onboard cx -# LocalWords: VillageTronics ATARILANCE RieblCard PAMCard VME MFP sangoma LAPB +# LocalWords: Village Tronic ATARILANCE RieblCard PAMCard VME MFP sangoma LAPB # LocalWords: Rhotron BioData's Multiface AMIGAMOUSE COPCON Amiga's bitplanes # LocalWords: ATARIMOUSE MFPSER SCC's MegaSTE ESCC Atari's GVPIOEXT DMASOUND # LocalWords: fdutils cisco univercd rpcg htm iface lapb LAPBETHER tpqic qic diff -u --recursive --new-file v2.1.125/linux/Documentation/joystick-api.txt linux/Documentation/joystick-api.txt --- v2.1.125/linux/Documentation/joystick-api.txt Fri Oct 9 13:27:04 1998 +++ linux/Documentation/joystick-api.txt Wed Oct 21 08:43:33 1998 @@ -98,7 +98,7 @@ may work well if you handle JS_EVENT_INIT events separately, - if (js_event.type & ~JS_EVENT_INIT == JS_EVENT_BUTTON) { + if ((js_event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) { if (js_event.value) buttons_state |= (1 << js_event.number); else @@ -292,9 +292,12 @@ The axis values do not have a defined range in the original 0.x driver, except for that the values are non-negative. The 1.2.8+ drivers use a -fixed range for reporting the values, 0 being the minimum, 128 the +fixed range for reporting the values, 1 being the minimum, 128 the center, and 255 maximum value. +The v0.8.0.2 driver also had an interface for 'digital joysticks', (now +called Multisystem joystick in this driver), under /dev/djsX. This driver +doesn't try to be compatible with that interface. 6. Final Notes ~~~~~~~~~~~~~~ diff -u --recursive --new-file v2.1.125/linux/Documentation/joystick-parport.txt linux/Documentation/joystick-parport.txt --- v2.1.125/linux/Documentation/joystick-parport.txt Fri Oct 9 13:27:04 1998 +++ linux/Documentation/joystick-parport.txt Wed Oct 21 08:43:33 1998 @@ -231,7 +231,13 @@ (pin 7) -----> Button 2 -2.2.1 Multisystem joysticks using joy-console.c + And that's it. + + On a side note, if you have already built a different adapter for use with +the digital joystick driver 0.8.0.2, this is also supported by the joy-db9.c +driver, as device type 8. (See section 3.2) + +2.2.2 Multisystem joysticks using joy-console.c ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For some people just one joystick per parallel port is not enough, and/or want to use them on one parallel port together with NES/SNES/PSX pads. This @@ -440,21 +446,23 @@ more parallel ports. Changes: - v0.1 : First version (SNES only) - v0.2 : X/Y directions were exchanged... - v0.3 : Adaptation for kernel 2.1 - v0.4 : Adaptation for joystick-1.2.6 - - added open/close callbacks - v0.5 : Renamed to "joy-console" because I have added - PSX controller support. - v0.6 : NES support - v0.7V: Added "multi system" support - v0.8 : Bugfixed PSX driver... - v0.9V: Changed multi system support - Added Multi2 support - Fixed parport handling - Cleaned up - v0.10: Fixed PSX buttons 7 and 8 + v0.1 : First version (SNES only) + v0.2 : X/Y directions were exchanged... + v0.3 : Adaptation for kernel 2.1 + v0.4 : Adaptation for joystick-1.2.6 + - added open/close callbacks + v0.5 : Renamed to "joy-console" because I have added + PSX controller support. + v0.6 : NES support + v0.7V : Added "multi system" support + v0.8 : Bugfixed PSX driver... + v0.9V : Changed multi system support + Added Multi2 support + Fixed parport handling + Cleaned up + v0.10 : Fixed PSX buttons 8 and 9 + v0.11V: Switched to EXCL mode + Removed wakeup 3.2 joy-db9.c ~~~~~~~~~~~~~ @@ -478,6 +486,7 @@ 5 | Genesis pad (5+1 buttons) 6 | Genesis pad (6+1 buttons) 7 | Saturn pad + 8 | Multisystem 1-button joystick (v0.8.0.2 pin-out) Should you want to use more than one of these joysticks/pads at once, you can use js_db9_2 and js_db9_3 as additional command line parameters for two @@ -489,6 +498,9 @@ v0.3V: Added Sega Saturn support Fixed parport and PS/2 mode handling Cleaned up + v0.4V: Switched to EXCL mode + Removed wakeup + v0.5V: Added 0.8.0.2 HW compatibility for Multi sticks 3.3 joy-turbografx.c ~~~~~~~~~~~~~~~~~~~~ @@ -506,9 +518,6 @@ Should you want to use more than one of these interfaces at once, you can use js_tg_2 and js_tg_3 as additional command line parameters for two more interfaces. - - Changes: - v0.1V: First version 3.4 End ~~~~~~~ diff -u --recursive --new-file v2.1.125/linux/Documentation/joystick.txt linux/Documentation/joystick.txt --- v2.1.125/linux/Documentation/joystick.txt Fri Oct 9 13:27:04 1998 +++ linux/Documentation/joystick.txt Wed Oct 21 08:43:33 1998 @@ -1,12 +1,9 @@ - Linux Joystick driver v1.2.11 BETA + Linux Joystick driver v1.2.12 (c) 1996-1998 Vojtech Pavlik ---------------------------------------------------------------------------- 0. Disclaimer ~~~~~~~~~~~~~ - This is a BETA release. It probably will work well for you, but it doesn't -have to. - 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) @@ -25,7 +22,7 @@ - mail your message to , or by paper mail: Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic - For your convenience, the GNU General Public Licens version 2 is included + For your convenience, the GNU General Public License version 2 is included in the package: See the file COPYING. 1. Intro @@ -36,19 +33,19 @@ These currently include various analog joysticks (both variable resistor based and microswitch+resistor based), following IBM PC joystick standard, with extensions like additional hats and buttons compatible with CH -Flightstick Pro, ThrustMaster FCS or PC 6 or 8 button gamepads. +Flightstick Pro, ThrustMaster FCS or 6 and 8 button gamepads. In addition to these it also supports some of the new PC joysticks that -use porprietary digital protocols to communicate over the gameport, -currently by FPGaming, Genius, Gravis, Logitech, MadCatz and Microsoft. -ThrustMaster and Creative Labs protocols are in the works. +use proprietary digital protocols to communicate over the gameport, +currently by FPGaming, Genius, Gravis, Logitech, MadCatz, Microsoft and +ThrustMaster. Creative Labs protocol support is still to be done. The driver also includes support for many gamepads and joysticks that were used by various non-PC computers and game consoles. These include Multi system joysticks (Atari, Amiga, Commodore, Amstrad), Sega gamepads (Master System, Genesis, Saturn), Nintendo gamepads (NES, SNES), Sony gamepads (PSX). Support for N64, Atari Jaguar, Atari 2600, NES FourScore, SNES MultiTap, -Pegasus, PSX NegCon and others might be added later. +PSX NegCon and others might be added later. Last, but not least there is also native Amiga joystick support for the Amiga linux port. @@ -92,24 +89,23 @@ module at once, if you have more than one joystick installed. If you want to have the driver compiled into your kernel, you first need -to patch the kernel. For that, use either kernel-2.0.35.patch, or -kernel-2.1.115.patch files, that are included in the joystick package, and -using the command +to patch the kernel, so that it contains the current driver version. You do +that with a command: - patch -Esp1 < /usr/src/joystick-1.2.x/kernel-2.x.y.patch + patch -Esp1 < /usr/src/joystick-1.2.x/kernel-2.x.y.diff in /usr/src/linux -apply the patch to your kernel. To compile joystick support into the kernel, -use the kernel configuration scripts, and answer 'Y' to Joystick support and -also to at least one of the hardware specific options. - - After patching the kernel you can also compile it as a module, answering -'M' to all joystick support you want to have modules for. It is possible to -have the main joystick driver compiled into the kernel and the hardware -dependent drivers as modules. + To compile joystick support into the kernel, use the kernel configuration +scripts, and answer 'Y' to Joystick support and also to at least one of the +hardware specific options. + + You can also compile the driver as modules, answering 'M' to all joystick +support you want to have modules for. It is possible to have the main +joystick driver compiled into the kernel and the hardware dependent drivers +as modules. After you're done with installation of the driver itself, you'll need to create the joystick device files in /dev so that applications can use them. @@ -128,7 +124,7 @@ * 2-axis, 4-button joystick * 3-axis, 4-button joystick -* Two 2-axis, 2-buttons joysticks on an Y-cable +* Two 2-axis, 2-button joysticks on an Y-cable For other joystick types (more/less axes, hats, and buttons) support you'll need to specify the types either on the kernel command line or on the @@ -155,12 +151,12 @@ 9 | 512 | CHF Hat 1 10 | 1024 | CHF Hat 2 11 | 2048 | FCS Hat - 12 | 4096 | PXY Button X - 13 | 8192 | PXY Button Y - 14 | 16384 | PXY Button U - 15 | 32768 | PXY Button V + 12 | 4096 | Pad Button X + 13 | 8192 | Pad Button Y + 14 | 16384 | Pad Button U + 15 | 32768 | Pad Button V -(CHF = CH Flightstick Pro, FCS = ThrustMaster FCS, PXY - Pad with 6 or 8 buttons) +(CHF = CH Flightstick Pro, FCS = ThrustMaster FCS) Following is a table of joysticks for which the 'm' values are known. If you have any additions/corrections to it, e-mail me. @@ -176,6 +172,7 @@ Laing #1 PC SuperPad | 0xf0f3 Microsoft SideWinder Standard | 0x003b QuickShot QS-201 SuperWarrior | 0x00fb + Saitek Megapad XII | 0x30f3 In case you have one of the joystick in the table below, and it doesn't work with a specific driver in digital mode for some reason, you can use @@ -470,9 +467,9 @@ 1.1.3 Leslie F. Donaldson 1.2.0 Eng-Jon Ong 1.2.8 Ragnar Hojland Espinosa - 1.2.3-1.2.9 Andree Borrmann 1.1.0-1.2.9 Brian Gerst - 0.9.0-1.2.11 Vojtech Pavlik + 1.2.3-1.2.12 Andree Borrmann + 0.9.0-1.2.12 Vojtech Pavlik If you think you should be in this list and are not, it's possible that I forgot to include you - contact me and I'll correct the error. :) diff -u --recursive --new-file v2.1.125/linux/Documentation/mca.txt linux/Documentation/mca.txt --- v2.1.125/linux/Documentation/mca.txt Wed Jun 24 22:54:02 1998 +++ linux/Documentation/mca.txt Sat Oct 17 15:33:45 1998 @@ -31,8 +31,7 @@ mca_set_adapter_name( slot, "adapter name & description" ); mca_set_adapter_procfn( slot, dev_getinfo, dev ); - /* read the POS registers. Most devices only need - 2 and 3 */ + /* read the POS registers. Most devices only use 2 and 3 */ pos2 = mca_read_stored_pos( slot, 2 ); pos3 = mca_read_stored_pos( slot, 3 ); pos4 = mca_read_stored_pos( slot, 4 ); @@ -45,7 +44,8 @@ Loadable modules should modify this to test that the specified IRQ and IO ports (plus whatever other stuff) match. See 3c523.c for example -code. +code (actually, smc-mca.c has a slightly more complex example that can +handle a list of adapter ids). Keep in mind that devices should never directly access the POS registers (via inb(), outb(), etc). While it's generally safe, there is a small @@ -57,11 +57,11 @@ and mca_write_pos() are also available for (safer) direct POS access, but their use is _highly_ discouraged. mca_write_pos() is particularly dangerous, as it is possible for adapters to be put in inconsistent -states (e.g. sharing IO address, etc) and may result in crashes, toasted -hardware, and operator injury. +states (i.e. sharing IO address, etc) and may result in crashes, toasted +hardware, and blindness. -User level drivers (such as the AGX X server) can use /proc/mca to find -adapters (see below). +User level drivers (such as the AGX X server) can use /proc/mca/pos to +find adapters (see below). Some MCA adapters can also be detected via the usual ISA-style device probing (many SCSI adapters, for example). This sort of thing is highly @@ -91,8 +91,8 @@ /proc/mca ========= -I did a major rewrite of /proc/mca. It is now a directory containing -various files for adapters and other stuff. +/proc/mca is a directory containing various files for adapters and +other stuff. /proc/mca/pos Straight listing of POS registers /proc/mca/slot[1-8] Information on adapter in specific slot @@ -100,6 +100,8 @@ /proc/mca/scsi Same for integrated SCSI /proc/mca/machine Machine information +See Appendix A for a sample. + Device drivers can easily add their own information function for specific slots (including integrated ones) via the mca_set_adapter_procfn() call. Drivers that support this are ESDI, IBM @@ -132,10 +134,9 @@ Disable it with: mca_set_adapter_procfn( slot, NULL, NULL ); -It is also recommended, even if you don't write a proc function, to -set the name of the adapter (e.g. "PS/2 ESDI Controller") via -mca_set_adapter_name( int slot, char* name ). Up to 30 characters are -used. +It is also recommended that, even if you don't write a proc function, to +set the name of the adapter (i.e. "PS/2 ESDI Controller") via +mca_set_adapter_name( int slot, char* name ). MCA Device Drivers ================== @@ -146,65 +147,174 @@ drivers/block/ps2esdi.c include/linux/ps2esdi.h Uses major number 36, and should use /dev files /dev/eda, /dev/edb. - Supports two drives, but only one controller. Usually requires the - command-line args ed=cyl,head,sec + Supports two drives, but only one controller. May use the + command-line args "ed=cyl,head,sec" and "tp720". 2) PS/2 SCSI drivers/scsi/ibmmca.c drivers/scsi/ibmmca.h The driver for the IBM SCSI subsystem. Includes both integrated controllers and adapter cards. May require command-line arg - ibmmcascsi=pun to force detection of an adapter. + "ibmmcascsi=io_port" to force detection of an adapter. If you have a + machine with a front-panel display (i.e. model 95), you can use + "ibmmcascsi=display" to enable a drive activity indicator. 3) 3c523 drivers/net/3c523.c drivers/net/3c523.h - 3Com 3c523 Etherlink/MC Ethernet driver. + 3Com 3c523 Etherlink/MC ethernet driver. -4) SMC Ultra/MCA +4) SMC Ultra/MCA and IBM Adapter/A drivers/net/smc-mca.c drivers/net/smc-mca.h - Elite/A (8013EP/A) and Elite10T/A (8013WP/A) Ethernet driver + Driver for the MCA version of the SMC Ultra and various other + OEM'ed and work-alike cards (Elite, Adapter/A, etc). -As well, drivers/char/psaux.c was modified to support IRQ sharing (it's -#ifdef CONFIG_MCA'ed, for your convenience, although PCI users might be -able to use it...) +5) NE/2 + driver/net/ne2.c + driver/net/ne2.h + The NE/2 is the MCA version of the NE2000. This may not work + with clones that have a different adapter id than the original + NE/2. + +6) Future Domain MCS-600/700, OEM'd IBM Fast SCSI Aapter/A and + Reply Sound Blaster/SCSI (SCSI part) + Better support for these cards than the driver for ISA. + Supports multiple cards with IRQ sharing. + +Also added boot time option of scsi-probe, which can do reordering of +SCSI host adapters. This will direct the kernel on the order which +SCSI adapter should be detected. Example: + scsi-probe=ibmmca,fd_mcs,adaptec1542,buslogic The serial drivers were modified to support the extended IO port range of the typical MCA system (also #ifdef CONFIG_MCA). The following devices work with existing drivers: 1) Token-ring -2) Future Domain SCSI (MCS-600, MCS-700, not MCS-350) -3) Adaptec 1640 SCSI (aha1542 driver) -4) Buslogic SCSI (various) +2) Future Domain SCSI (MCS-600, MCS-700, not MCS-350, OEM'ed IBM SCSI) +3) Adaptec 1640 SCSI (using the aha1542 driver) +4) Bustek/Buslogic SCSI (various) +5) Probably all Arcnet cards. +6) Some, possibly all, MCA IDE controllers. +7) 3Com 3c529 (MCA version of 3c509) (patched) + +8) Intel EtherExpressMC (patched version) + You need to have CONFIG_MCA defined to have EtherExpressMC support. +9) Reply Sound Blaster/SCSI (SB part) (patched version) Bugs & Other Weirdness ====================== NMIs tend to occur with MCA machines because of various hardware -weirdness, bus timeouts, and many other non-critical things. Those of -you who have NMI problems should probably set the CONFIG_IGNORE_NMI flag -somewhere. NMIs seem to be particularly common on the model 70. - -Various Pentium machines have serious problems with the FPU test in -bugs.h. You may need to comment out the FPU test before you can even -boot. This occurs, as far as we know, on the Pentium-equipped 85s, 95s, -and some servers. The PCI/MCA PC 750s are fine as far as I can tell. +weirdness, bus timeouts, and many other non-critical things. Some basic +code to handle them (inspired by the NetBSD MCA code) has been added to +detect the guilty device, but it's pretty incomplete. If NMIs are a +persistent problem (on some model 70 or 80s, they occur every couple +shell commands), the CONFIG_IGNORE_NMI flag will take care of that. + +Various Pentium machines have had serious problems with the FPU test in +bugs.h. Basically, the machine hangs after the HLT test. This occurs, +as far as we know, on the Pentium-equipped 85s, 95s, and some PC Servers. +The PCI/MCA PC 750s are fine as far as I can tell. The ``mca-pentium'' +boot-prompt flag will disable the FPU bug check if this is a problem +with your machine. The model 80 has a raft of problems that are just too weird and unique to get into here. Some people have no trouble while others have nothing -but problems. I'd suspect the problems are related to the age of the -average 80 and accompanying hardware deterioration. +but problems. I'd suspect some problems are related to the age of the +average 80 and accompanying hardware deterioration, although others +are definitely design problems with the hardware. Among the problems +include SCSI controller problems, ESDI controller problems, and serious +screw-ups in the floppy controller. Oh, and the parallel port is also +pretty flaky. There were about 5 or 6 different model 80 motherboards +produced to fix various obscure problems. As far as I know, it's pretty +much impossible to tell which bugs a particular model 80 has (other than +triggering them, that is). + +Drivers are required for some MCA memory adapters. If you're suddenly +short a few megs of RAM, this might be the reason. The (I think) Enhanced +Memory Adapter commonly found on the model 70 is one. There's a very +alpha driver floating around, but it's pretty ugly (disassembled from +the DOS driver, actually). See the MCA Linux web page (URL below) +for more current memory info. + +The Thinkpad 700 and 720 will work, but various components are either +non-functional, flaky, or we don't know anything about them. The +graphics controller is supposed to be some WD, but we can't get things +working properly. The PCMCIA slots don't seem to work. Ditto for APM. +The serial ports work, but detection seems to be flaky. Credits ======= A whole pile of people have contributed to the MCA code. I'd include their names here, but I don't have a list handy. Check the MCA Linux -home page (URL below) for an out-of-date list. +home page (URL below) for a perpetually out-of-date list. ===================================================================== -http://glycerine.cetmm.uni.edu/mca +MCA Linux Home Page: http://glycerine.itsmm.uni.edu/mca/ -Chris Beauregard +Christophe Beauregard chrisb@truespectra.com +cpbeaure@calum.csclub.uwaterloo.ca + +===================================================================== +Appendix A: Sample /proc/mca + +This is from my model 8595. Slot 1 contains the standard IBM SCSI +adapter, slot 3 is an Adaptec AHA-1640, slot 5 is a XGA-1 video adapter, +and slot 7 is the 3c523 Etherlink/MC. + +/proc/mca/machine: +Model Id: 0xf8 +Submodel Id: 0x14 +BIOS Revision: 0x5 + +/proc/mca/pos: +Slot 1: ff 8e f1 fc a0 ff ff ff IBM SCSI Adapter w/Cache +Slot 2: ff ff ff ff ff ff ff ff +Slot 3: 1f 0f 81 3b bf b6 ff ff +Slot 4: ff ff ff ff ff ff ff ff +Slot 5: db 8f 1d 5e fd c0 00 00 +Slot 6: ff ff ff ff ff ff ff ff +Slot 7: 42 60 ff 08 ff ff ff ff 3Com 3c523 Etherlink/MC +Slot 8: ff ff ff ff ff ff ff ff +Video: ff ff ff ff ff ff ff ff +SCSI: ff ff ff ff ff ff ff ff + +/proc/mca/slot1: +Slot: 1 +Adapter Name: IBM SCSI Adapter w/Cache +Id: 8eff +Enabled: Yes +POS: ff 8e f1 fc a0 ff ff ff +Subsystem PUN: 7 +Detected at boot: Yes + +/proc/mca/slot3: +Slot: 3 +Adapter Name: Unknown +Id: 0f1f +Enabled: Yes +POS: 1f 0f 81 3b bf b6 ff ff + +/proc/mca/slot5: +Slot: 5 +Adapter Name: Unknown +Id: 8fdb +Enabled: Yes +POS: db 8f 1d 5e fd c0 00 00 + +/proc/mca/slot7: +Slot: 7 +Adapter Name: 3Com 3c523 Etherlink/MC +Id: 6042 +Enabled: Yes +POS: 42 60 ff 08 ff ff ff ff +Revision: 0xe +IRQ: 9 +IO Address: 0x3300-0x3308 +Memory: 0xd8000-0xdbfff +Transceiver: External +Device: eth0 +Hardware Address: 02 60 8c 45 c4 2a diff -u --recursive --new-file v2.1.125/linux/Documentation/powerpc/00-INDEX linux/Documentation/powerpc/00-INDEX --- v2.1.125/linux/Documentation/powerpc/00-INDEX Sat May 2 14:19:51 1998 +++ linux/Documentation/powerpc/00-INDEX Sat Oct 10 09:53:24 1998 @@ -11,4 +11,5 @@ - use and state info about Linux/PPC on MP machines sound.txt - info on sound support under Linux/PPC - +zImage_layout.txt + - info on the kernel images for Linux/PPC diff -u --recursive --new-file v2.1.125/linux/Documentation/powerpc/smp.txt linux/Documentation/powerpc/smp.txt --- v2.1.125/linux/Documentation/powerpc/smp.txt Thu Apr 23 20:21:27 1998 +++ linux/Documentation/powerpc/smp.txt Sat Oct 10 09:53:24 1998 @@ -5,7 +5,7 @@ (Cort Dougan, cort@cs.nmt.edu) please email me if you have questions, comments or corrections. -Last Change: 4.1.98 +Last Change: 10.8.98 SMP support for Linux/PPC is still in its early stages and likely to be buggy for a while. If you want to help by writing code or testing @@ -13,7 +13,7 @@ 1. State of Supported Hardware - PowerSurge Architecture - UMAX s900, Apple 9500/9600/8500/8600/7500/7600 + PowerSurge Architecture - tested on UMAX s900, Apple 9600 The second processor on this machine boots up just fine and enters its idle loop. Hopefully a completely working SMP kernel on this machine will be done shortly. @@ -22,7 +22,9 @@ necessary to work with any number would not be overly difficult but I don't have any machines with >2 processors so it's not high on my list of priorities. If anyone else would like do to the work email - me and I can point out the places that need changed. + me and I can point out the places that need changed. If you have >2 + processors and don't want to add support yourself let me know and I + can take a look into it. BeBox BeBox support hasn't been added to the 2.1.X kernels from 2.0.X diff -u --recursive --new-file v2.1.125/linux/Documentation/powerpc/sound.txt linux/Documentation/powerpc/sound.txt --- v2.1.125/linux/Documentation/powerpc/sound.txt Thu Apr 23 20:21:27 1998 +++ linux/Documentation/powerpc/sound.txt Sat Oct 10 09:53:24 1998 @@ -1,7 +1,7 @@ Information about PowerPC Sound support ===================================================================== -Please mail me me (Cort Dougan, cort@cs.nmt.edu) if you have questions, +Please mail me (Cort Dougan, cort@cs.nmt.edu) if you have questions, comments or corrections. Last Change: 3.24.98 diff -u --recursive --new-file v2.1.125/linux/Documentation/powerpc/zImage_layout.txt linux/Documentation/powerpc/zImage_layout.txt --- v2.1.125/linux/Documentation/powerpc/zImage_layout.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/powerpc/zImage_layout.txt Sat Oct 10 09:53:24 1998 @@ -0,0 +1,47 @@ + Information about the Linux/PPC kernel images +===================================================================== + +Please mail me me (Cort Dougan, cort@cs.nmt.edu) if you have questions, +comments or corrections. + +This document is meant to answer several questions I've had about how +the PReP system boots and how Linux/PPC interacts with that mechanism. +It would be nice if we could have information on how other architectures +boot here as well. If you have anything to contribute, please +let me know. + + +1. PReP boot file + + This is the file necessary to boot PReP systems from floppy or + hard drive. The firmware reads the PReP partition table entry + and will load the image accordingly. + + To boot the zImage, copy it onto a floppy with dd if=zImage of=/dev/fd0h1440 + or onto a PReP hard drive partition with dd if=zImage of=/dev/sda4 + assuming you've created a PReP partition (type 0x41) with fdisk on + /dev/sda4. + + The layout of the image format is: + + 0x0 +------------+ + | | PReP partition table entry + | | + 0x400 +------------+ + | | Bootstrap program code + data + | | + | | + +------------+ + | | compressed kernel, elf header removed + +------------+ + | | initrd (if loaded) + +------------+ + | | Elf section table for bootstrap program + +------------+ + + +2. MBX boot file + + The MBX boards can load an elf image, and relocate it to the + proper location in memory - it copies the image to the location it was + linked at. diff -u --recursive --new-file v2.1.125/linux/Documentation/sound/MultiSound linux/Documentation/sound/MultiSound --- v2.1.125/linux/Documentation/sound/MultiSound Tue Aug 18 22:02:01 1998 +++ linux/Documentation/sound/MultiSound Fri Oct 9 11:56:59 1998 @@ -1,180 +1,476 @@ -Getting Firmware -~~~~~~~~~~~~~~~~ - -See the end of this document on how to obtain and create the necessary -firmware files. - - -Supported Features -~~~~~~~~~~~~~~~~~~ - -Currently digital audio and mixer functionality is supported. (memory -mapped digital audio is not yet supported). Modular MultiSound -support is composed of the following modules: - -msnd - MultiSound base (requires soundcore) -msnd_classic - Base audio/mixer support for Classic, Monetery and - Tahiti cards -msnd_pinnacle - Base audio/mixer support for Pinnacle and Fiji cards - - -Important Notes - Read Before Using -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -* The firmware files are not included (may change in future). You -must obtain these images from Turtle Beach (they are included in the -MultiSound Development Kits), and place them in /etc/sound for -example, and give the full paths in the Linux configuration. Please -note these files must be binary files, not assembler. - -* You need the following information to use this driver: the card's -I/O base (i.e. 0x250), the IRQ (i.e. 5), and the shared memory area -(i.e. 0xd8000). - -* Probing is not currently implemented, and only the msnd_classic -driver will actually program the card's IRQ and SMA locations; the -msnd_pinnacle is primarily for use with the card in PnP mode, however -it should work if you know what the card's resource values are (this -will change in the future). - -* Note the Turtle Beach Pinnacle card contains a Kurzweil MA-1 -synthesizer with an MPU compatible interface, which should work with -the mpu401 module. You must know the resource values of the MA-1. - - -Examples -~~~~~~~~ - -* If you have a MultiSound Classic/Monterey/Tahiti: - -insmod soundcore -insmod msnd -insmod msnd_classic io=0x290 irq=7 mem=0xd0000 - -* If you have a MultiSound Pinnacle: - -insmod soundcore -insmod msnd -insmod msnd_pinnacle io=0x210 irq=5 mem=0xd8000 - -* To use the MPU-compatible Kurzweil synth on the Pinnacle, add the -following: - -insmod sound -insmod mpu401 io=0x330 irq=9 - - -msnd_classic, msnd_pinnacle Required Options -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If the following options are not given, the module will not load. -Examine the kernel message log for informative error messages. -WARNING--probing isn't supported so try to make sure you have the -correct shared memory area, otherwise you may experience problems. - -io I/O base of DSP, e.g. io=0x210 -irq IRQ number, e.g. irq=5 -mem Shared memory area, e.g. mem=0xd8000 - - -msnd_classic, msnd_pinnacle Additional Options -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -fifosize The digital audio FIFOs, in kilobytes. The - default is 64kB (two FIFOs are allocated, so - this uses up 128kB). - -calibrate_signal Setting this to one calibrates the ADCs to the - signal, zero calibrates to the card (defaults - to zero). - - -msnd_pinnacle Additional Options -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -digital Specify digital=1 to enable the S/PDIF input - if you have the digital daughterboard - adapter. This will enable access to the - DIGITAL1 input for the soundcard in the mixer. - Some mixer programs might have trouble setting - the DIGITAL1 source as an input. If you have - trouble, you can try the setdigital.c program - at the bottom of this document. - - -Obtaining and Creating Firmware Files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - For the Classic/Tahiti/Monterey - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Download to /tmp and unzip the following file from Turtle Beach: - - ftp://ftp.tbeach.com/pub/tbs/pinn/msndvkit.zip - -When unzipped, unzip the file named MsndFiles.zip. Then copy the -following firmware files to /etc/sound (note the file renaming): - - cp DSPCODE/MSNDINIT.BIN /etc/sound/msndinit.bin - cp DSPCODE/MSNDPERM.REB /etc/sound/msndperm.bin - -When configuring the Linux kernel, specify /etc/sound/msndinit.bin and -/etc/sound/msndperm.bin for the two firmware files (Linux kernel -versions older than 2.2 do not ask for firmware paths, and are -hardcoded to /etc/sound). - - - For the Pinnacle/Fiji - ~~~~~~~~~~~~~~~~~~~~~ - -Download to /tmp and unzip the following file from Turtle Beach (be -sure to use the entire URL; some have had trouble navigating to the -URL): - - ftp://ftp.tbeach.com/oldpub/tbs/pinn/pnddk100.zip - -Put the following lines into a file named conv.l (between the start -and end lines): - --- conv.l start -- -%% -[ \n\t,\r] -\;.* -DB -[0-9A-Fa-f]+H { int n; sscanf(yytext, "%xH", &n); printf("%c", n); } --- conv.l end -- - -Then, compile the conv program with GNU make with the following -command: - - make LEX=flex LOADLIBES=-lfl conv - -This should give you an executable named conv. Now, we create the -binary firmware files by doing the following conversion (assuming the -archive unpacked into a directory named PINNDDK): - - ./conv < PINNDDK/dspcode/pndspini.asm > /etc/sound/pndspini.bin - ./conv < PINNDDK/dspcode/pndsperm.asm > /etc/sound/pndsperm.bin - -The conv (and conv.l) program is not needed after conversion and can -be safely deleted. Then, when configuring the Linux kernel, specify -/etc/sound/pndspini.bin and /etc/sound/pndsperm.bin for the two -firmware files (Linux kernel versions older than 2.2 do not ask for -firmware paths, and are hardcoded to /etc/sound). - - -Recording from the S/PDIF Input -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you have a Pinnacle or Fiji with S/PDIF input and want to set it as -the input source, you can use this program if you have trouble trying -to do it with a mixer program (be sure to insert the module with the -digital=1 option). - -Compile with: -cc -O setdigital.c -o setdigital - --- start setdigital.c -- +#! /bin/sh +# +# Turtle Beach MultiSound Driver Notes +# -- Andrew Veliath +# +# Last update: September 10, 1998 +# Corresponding msnd driver: 0.8.2 +# +# ** This file is a README (top part) and shell archive (bottom part). +# The corresponding archived utility sources can be unpacked by +# running `sh MultiSound' (the utilities are only needed for the +# Pinnacle and Fiji cards). ** +# +# +# -=-=- Getting Firmware -=-=- +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# See the section `Obtaining and Creating Firmware Files' in this +# document for instructions on obtaining the necessary firmware +# files. +# +# +# Supported Features +# ~~~~~~~~~~~~~~~~~~ +# +# Currently, full-duplex digital audio (/dev/dsp only, /dev/audio is +# not currently available) and mixer functionality (/dev/mixer) are +# supported (memory mapped digital audio is not yet supported). +# Digital transfers and monitoring can be done as well if you have +# the digital daughterboard (see the section on using the S/PDIF port +# for more information). +# +# Support for the Turtle Beach MultiSound Hurricane architecture is +# composed of the following modules (these can also operate compiled +# into the kernel): +# +# msnd - MultiSound base (requires soundcore) +# +# msnd_classic - Base audio/mixer support for Classic, Monetery and +# Tahiti cards +# +# msnd_pinnacle - Base audio/mixer support for Pinnacle and Fiji cards +# +# +# Important Notes - Read Before Using +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# The firmware files are not included (may change in future). You +# must obtain these images from Turtle Beach (they are included in +# the MultiSound Development Kits), and place them in /etc/sound for +# example, and give the full paths in the Linux configuration. If +# you are compiling in support for the MultiSound driver rather than +# using it as a module, these firmware files must be accessible +# during kernel compilation. +# +# Please note these files must be binary files, not assembler. See +# the section later in this document for instructions to obtain these +# files. +# +# +# Configuring Card Resources +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# ** This section is very important, as your card may not work at all +# or your machine may crash if you do not do this correctly. ** +# +# * Classic/Monterey/Tahiti +# +# These cards are configured through the driver msnd_classic. You must +# know the io port, then the driver will select the irq and memory resources +# on the card. It is up to you to know if these are free locations or now, +# a conflict can lock the machine up. +# +# * Pinnacle/Fiji +# +# The Pinnacle and Fiji cards have an extra config port, either +# 0x250, 0x260 or 0x270. This port can be disabled to have the card +# configured strictly through PnP, however you lose the ability to +# access the IDE controller and joystick devices on this card when +# using PnP. The included pinnaclecfg program in this shell archive +# can be used to configure the card in non-PnP mode, and in PnP mode +# you can use isapnptools. These are described briefly here. +# +# pinnaclecfg is not required; you can use the msnd_pinnacle module +# to fully configure the card as well. However, pinnaclecfg can be +# used to change the resource values of a particular device after the +# msnd_pinnacle module has been loaded. If you are compiling the +# driver into the kernel, you must set these values during compile +# time, however other peripheral resource values can be changed with +# the pinnaclecfg program after the kernel is loaded. +# +# +# *** PnP mode +# +# Use pnpdump to obtain a sample configuration if you can; I was able +# to obtain one with the command `pnpdump 1 0x203' -- this may vary +# for you (running pnpdump by itself did not work for me). Then, +# edit this file and use isapnp to uncomment and set the card values. +# Use these values when inserting the msnd_pinnacle module. Using +# this method, you can set the resources for the DSP and the Kurzweil +# synth (Pinnacle). Since Linux does not directly support PnP +# devices, you may have difficulty when using the card in PnP mode +# when it the driver is compiled into the kernel. Using non-PnP mode +# is preferable in this case. +# +# Here is an example mypinnacle.conf for isapnp that sets the card to +# io base 0x210, irq 5 and mem 0xd8000, and also sets the Kurzweil +# synth to 0x330 and irq 9 (may need editing for your system): +# +# (READPORT 0x0203) +# (CSN 2) +# (IDENTIFY *) +# +# # DSP +# (CONFIGURE BVJ0440/-1 (LD 0 +# (INT 0 (IRQ 5 (MODE +E))) (IO 0 (BASE 0x0210)) (MEM 0 (BASE 0x0d8000)) +# (ACT Y))) +# +# # Kurzweil Synth (Pinnacle Only) +# (CONFIGURE BVJ0440/-1 (LD 1 +# (IO 0 (BASE 0x0330)) (INT 0 (IRQ 9 (MODE +E))) +# (ACT Y))) +# +# (WAITFORKEY) +# +# +# *** Non-PnP mode +# +# The second way is by running the card in non-PnP mode. This +# actually has some advantages in that you can access some other +# devices on the card, such as the joystick and IDE controller. To +# configure the card, unpack this shell archive and build the +# pinnaclecfg program. Using this program, you can assign the +# resource values to the card's devices, or disable the devices. As +# an alternative to using pinnaclecfg, you can specify many of the +# configuration values when loading the msnd_pinnacle module (or +# during kernel configuration when compiling the driver into the +# kernel). +# +# If you specify cfg=0x250 for the msnd_pinnacle module, it +# automatically configure the card to the given io, irq and memory +# values using that config port (the config port is jumper selectable +# on the card to 0x250, 0x260 or 0x270). +# +# See the `msnd_pinnacle Additional Options' section below for more +# information on these parameters (also, if you compile the driver +# directly into the kernel, these extra parameters can be useful +# here). +# +# +# ** It is very easy to cause problems in your machine if you choose a +# resource value which is incorrect. ** +# +# +# Examples +# ~~~~~~~~ +# +# * MultiSound Classic/Monterey/Tahiti: +# +# insmod soundcore +# insmod msnd +# insmod msnd_classic io=0x290 irq=7 mem=0xd0000 +# +# * MultiSound Pinnacle in PnP mode: +# +# insmod soundcore +# insmod msnd +# isapnp mypinnacle.conf +# insmod msnd_pinnacle io=0x210 irq=5 mem=0xd8000 <-- match mypinnacle.conf values +# +# * MultiSound Pinnacle in non-PnP mode (replace 0x250 with your configuration port, +# one of 0x250, 0x260 or 0x270): +# +# insmod soundcore +# insmod msnd +# insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 +# +# * To use the MPU-compatible Kurzweil synth on the Pinnacle in PnP +# mode, add the following (assumes you did `isapnp mypinnacle.conf'): +# +# insmod sound +# insmod mpu401 io=0x330 irq=9 <-- match mypinnacle.conf values +# +# * To use the MPU-compatible Kurzweil synth on the Pinnacle in non-PnP +# mode, add the following. Note how we first configure the peripheral's +# resources, _then_ install a Linux driver for it: +# +# insmod sound +# pinnaclecfg 0x250 mpu 0x330 9 +# insmod mpu401 io=0x330 irq=9 +# +# -- OR you can use the following sequence without pinnaclecfg in non-PnP mode: +# +# insmod soundcore +# insmod msnd +# insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 mpu_io=0x330 mpu_irq=9 +# insmod sound +# insmod mpu401 io=0x330 irq=9 +# +# * To setup the joystick port on the Pinnacle in non-PnP mode (though +# you have to find the actual Linux joystick driver elsewhere), you +# can use pinnaclecfg: +# +# pinnaclecfg 0x250 joystick 0x200 +# +# -- OR you can configure this using msnd_pinnacle with the following: +# +# insmod soundcore +# insmod msnd +# insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 joystick_io=0x200 +# +# +# msnd_classic, msnd_pinnacle Required Options +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# If the following options are not given, the module will not load. +# Examine the kernel message log for informative error messages. +# WARNING--probing isn't supported so try to make sure you have the +# correct shared memory area, otherwise you may experience problems. +# +# io I/O base of DSP, e.g. io=0x210 +# irq IRQ number, e.g. irq=5 +# mem Shared memory area, e.g. mem=0xd8000 +# +# +# msnd_classic, msnd_pinnacle Additional Options +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# fifosize The digital audio FIFOs, in kilobytes. If not +# specified, the default will be used. Increasing +# this value will reduce the chance of a FIFO +# underflow at the expense of increasing overall +# latency. For example, fifosize=512 will +# allocate 512kB read and write FIFOs (1MB total). +# While this may reduce dropouts, a heavy machine +# load will undoubtedly starve the FIFO of data +# and you will eventually get dropouts. One +# option is to alter the scheduling priority of +# the playback process, using `nice' or some form +# of POSIX soft real-time scheduling. +# +# calibrate_signal Setting this to one calibrates the ADCs to the +# signal, zero calibrates to the card (defaults +# to zero). +# +# +# msnd_pinnacle Additional Options +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# digital Specify digital=1 to enable the S/PDIF input +# if you have the digital daughterboard +# adapter. This will enable access to the +# DIGITAL1 input for the soundcard in the mixer. +# Some mixer programs might have trouble setting +# the DIGITAL1 source as an input. If you have +# trouble, you can try the setdigital.c program +# at the bottom of this document. +# +# cfg Non-PnP configuration port for the Pinnacle +# and Fiji (typically 0x250, 0x260 or 0x270, +# depending on the jumper configuration). If +# this option is omitted, then it is assumed +# that the card is in PnP mode, and that the +# specified DSP resource values are already +# configured with PnP (i.e. it won't attempt to +# do any sort of configuration). +# +# When the Pinnacle is in non-PnP mode, you can use the following +# options to configure particular devices. If a full specification +# for a device is not given, then the device is not configured. Note +# that you still must use a Linux driver for any of these devices +# once their resources are setup (such as the Linux joystick driver, +# or the MPU401 driver from OSS for the Kurzweil synth). +# +# mpu_io I/O port of MPU (on-board Kurzweil synth) +# mpu_irq IRQ of MPU (on-board Kurzweil synth) +# ide_io0 First I/O port of IDE controller +# ide_io1 Second I/O port of IDE controller +# ide_irq IRQ IDE controller +# joystick_io I/O port of joystick +# +# +# Obtaining and Creating Firmware Files +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# For the Classic/Tahiti/Monterey +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Download to /tmp and unzip the following file from Turtle Beach: +# +# ftp://ftp.voyetra.com/pub/tbs/msndcl/msndvkit.zip +# +# When unzipped, unzip the file named MsndFiles.zip. Then copy the +# following firmware files to /etc/sound (note the file renaming): +# +# cp DSPCODE/MSNDINIT.BIN /etc/sound/msndinit.bin +# cp DSPCODE/MSNDPERM.REB /etc/sound/msndperm.bin +# +# When configuring the Linux kernel, specify /etc/sound/msndinit.bin and +# /etc/sound/msndperm.bin for the two firmware files (Linux kernel +# versions older than 2.2 do not ask for firmware paths, and are +# hardcoded to /etc/sound). +# +# If you are compiling the driver into the kernel, these files must +# be accessible during compilation, but will not be needed later. +# The files must remain, however, if the driver is used as a module. +# +# +# For the Pinnacle/Fiji +# ~~~~~~~~~~~~~~~~~~~~~ +# +# Download to /tmp and unzip the following file from Turtle Beach (be +# sure to use the entire URL; some have had trouble navigating to the +# URL): +# +# ftp://ftp.voyetra.com/pub/tbs/pinn/pnddk100.zip +# +# Unpack this shell archive, and run make in the created directory +# (you need a C compiler and flex to build the utilities). This +# should give you the executables conv, pinnaclecfg and setdigital. +# conv is only used temporarily here to create the firmware files, +# while pinnaclecfg is used to configure the Pinnacle or Fiji card in +# non-PnP mode, and setdigital can be used to set the S/PDIF input on +# the mixer (pinnaclecfg and setdigital should be copied to a +# convenient place, possibly run during system initialization). +# +# To generating the firmware files with the `conv' program, we create +# the binary firmware files by doing the following conversion +# (assuming the archive unpacked into a directory named PINNDDK): +# +# ./conv < PINNDDK/dspcode/pndspini.asm > /etc/sound/pndspini.bin +# ./conv < PINNDDK/dspcode/pndsperm.asm > /etc/sound/pndsperm.bin +# +# The conv (and conv.l) program is not needed after conversion and can +# be safely deleted. Then, when configuring the Linux kernel, specify +# /etc/sound/pndspini.bin and /etc/sound/pndsperm.bin for the two +# firmware files (Linux kernel versions older than 2.2 do not ask for +# firmware paths, and are hardcoded to /etc/sound). +# +# If you are compiling the driver into the kernel, these files must +# be accessible during compilation, but will not be needed later. +# The files must remain, however, if the driver is used as a module. +# +# +# Using Digital I/O with the S/PDIF Port +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# If you have a Pinnacle or Fiji with the digital daughterboard and +# want to set it as the input source, you can use this program if you +# have trouble trying to do it with a mixer program (be sure to +# insert the module with the digital=1 option, or say Y to the option +# during compiled-in kernel operation). Upon selection of the S/PDIF +# port, you should be able monitor and record from it. +# +# There is something to note about using the S/PDIF port. Digital +# timing is taken from the digital signal, so if a signal is not +# connected to the port and it is selected as recording input, you +# will find PCM playback to be distorted in playback rate. Also, +# attempting to record at a sampling rate other than the DAT rate may +# be problematic (i.e. trying to record at 8000Hz when the DAT signal +# is 44100Hz). If you have a problem with this, set the recording +# input to the line in if you need to record at a rate other than +# that of the DAT rate. +# +# +# -- Shell archive attached below, just run `sh MultiSound' to extract. +# Contains Pinnacle/Fiji utilities to convert firmware, configure +# in non-PnP mode, and select the DIGITAL1 input for the mixer. +# +# +#!/bin/sh +# This is a shell archive (produced by GNU sharutils 4.2). +# To extract the files from this archive, save it to some FILE, remove +# everything before the `!/bin/sh' line above, then type `sh FILE'. +# +# Made on 1998-09-05 08:26 EDT by . +# Source directory was `/home/andrewtv/programming/pinnacle/pinnacle'. +# +# Existing files will *not* be overwritten unless `-c' is specified. +# +# This shar contains: +# length mode name +# ------ ---------- ------------------------------------------ +# 2111 -rw-rw-r-- MultiSound.d/setdigital.c +# 10301 -rw-rw-r-- MultiSound.d/pinnaclecfg.c +# 96 -rw-rw-r-- MultiSound.d/Makefile +# 141 -rw-rw-r-- MultiSound.d/conv.l +# +save_IFS="${IFS}" +IFS="${IFS}:" +gettext_dir=FAILED +locale_dir=FAILED +first_param="$1" +for dir in $PATH +do + if test "$gettext_dir" = FAILED && test -f $dir/gettext \ + && ($dir/gettext --version >/dev/null 2>&1) + then + set `$dir/gettext --version 2>&1` + if test "$3" = GNU + then + gettext_dir=$dir + fi + fi + if test "$locale_dir" = FAILED && test -f $dir/shar \ + && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) + then + locale_dir=`$dir/shar --print-text-domain-dir` + fi +done +IFS="$save_IFS" +if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED +then + echo=echo +else + TEXTDOMAINDIR=$locale_dir + export TEXTDOMAINDIR + TEXTDOMAIN=sharutils + export TEXTDOMAIN + echo="$gettext_dir/gettext -s" +fi +touch -am 1231235999 $$.touch >/dev/null 2>&1 +if test ! -f 1231235999 && test -f $$.touch; then + shar_touch=touch +else + shar_touch=: + echo + $echo 'WARNING: not restoring timestamps. Consider getting and' + $echo "installing GNU \`touch', distributed in GNU File Utilities..." + echo +fi +rm -f 1231235999 $$.touch +# +if mkdir _sh21233; then + $echo 'x -' 'creating lock directory' +else + $echo 'failed to create lock directory' + exit 1 +fi +# ============= MultiSound.d/setdigital.c ============== +if test ! -d 'MultiSound.d'; then + $echo 'x -' 'creating directory' 'MultiSound.d' + mkdir 'MultiSound.d' +fi +if test -f 'MultiSound.d/setdigital.c' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'MultiSound.d/setdigital.c' '(file already exists)' +else + $echo 'x -' extracting 'MultiSound.d/setdigital.c' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/setdigital.c' && +/********************************************************************* +X * +X * setdigital.c - sets the DIGITAL1 input for a mixer +X * +X * Copyright (C) 1998 Andrew Veliath +X * +X * This program is free software; you can redistribute it and/or modify +X * it under the terms of the GNU General Public License as published by +X * the Free Software Foundation; either version 2 of the License, or +X * (at your option) any later version. +X * +X * This program is distributed in the hope that it will be useful, +X * but WITHOUT ANY WARRANTY; without even the implied warranty of +X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +X * GNU General Public License for more details. +X * +X * You should have received a copy of the GNU General Public License +X * along with this program; if not, write to the Free Software +X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +X * +X * $Id: setdigital.c,v 1.1 1998/08/29 03:32:33 andrewtv Exp $ +X * +X ********************************************************************/ +X #include #include #include @@ -182,53 +478,586 @@ #include #include #include - +X +int main(int argc, char *argv[]) +{ +X int fd; +X unsigned long recmask, recsrc; +X +X if (argc != 2) { +X fprintf(stderr, "usage: setdigital \n"); +X exit(1); +X } +X +X if ((fd = open(argv[1], O_RDWR)) < 0) { +X perror(argv[1]); +X exit(1); +X } +X +X if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) { +X fprintf(stderr, "error: ioctl read recording mask failed\n"); +X perror("ioctl"); +X close(fd); +X exit(1); +X } +X +X if (!(recmask & SOUND_MASK_DIGITAL1)) { +X fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n"); +X close(fd); +X exit(1); +X } +X +X if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) { +X fprintf(stderr, "error: ioctl read recording source failed\n"); +X perror("ioctl"); +X close(fd); +X exit(1); +X } +X +X recsrc |= SOUND_MASK_DIGITAL1; +X +X if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) { +X fprintf(stderr, "error: ioctl write recording source failed\n"); +X perror("ioctl"); +X close(fd); +X exit(1); +X } +X +X close(fd); +X +X return 0; +} +SHAR_EOF + $shar_touch -am 0828233298 'MultiSound.d/setdigital.c' && + chmod 0664 'MultiSound.d/setdigital.c' || + $echo 'restore of' 'MultiSound.d/setdigital.c' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'MultiSound.d/setdigital.c:' 'MD5 check failed' +47720746d4367bae9954787c311c56fd MultiSound.d/setdigital.c +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/setdigital.c'`" + test 2111 -eq "$shar_count" || + $echo 'MultiSound.d/setdigital.c:' 'original size' '2111,' 'current size' "$shar_count!" + fi +fi +# ============= MultiSound.d/pinnaclecfg.c ============== +if test -f 'MultiSound.d/pinnaclecfg.c' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'MultiSound.d/pinnaclecfg.c' '(file already exists)' +else + $echo 'x -' extracting 'MultiSound.d/pinnaclecfg.c' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/pinnaclecfg.c' && +/********************************************************************* +X * +X * pinnaclecfg.c - Pinnacle/Fiji Device Configuration Program +X * +X * This is for NON-PnP mode only. For PnP mode, use isapnptools. +X * +X * This is Linux-specific, and must be run with root permissions. +X * +X * Part of the Turtle Beach MultiSound Sound Card Driver for Linux +X * +X * Copyright (C) 1998 Andrew Veliath +X * +X * This program is free software; you can redistribute it and/or modify +X * it under the terms of the GNU General Public License as published by +X * the Free Software Foundation; either version 2 of the License, or +X * (at your option) any later version. +X * +X * This program is distributed in the hope that it will be useful, +X * but WITHOUT ANY WARRANTY; without even the implied warranty of +X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +X * GNU General Public License for more details. +X * +X * You should have received a copy of the GNU General Public License +X * along with this program; if not, write to the Free Software +X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +X * +X * $Id: pinnaclecfg.c,v 1.3 1998/08/29 03:32:32 andrewtv Exp $ +X * +X ********************************************************************/ +X +#include +#include +#include +#include +#include +#include +#include +X +#define IREG_LOGDEVICE 0x07 +#define IREG_ACTIVATE 0x30 +#define LD_ACTIVATE 0x01 +#define LD_DISACTIVATE 0x00 +#define IREG_EECONTROL 0x3F +#define IREG_MEMBASEHI 0x40 +#define IREG_MEMBASELO 0x41 +#define IREG_MEMCONTROL 0x42 +#define IREG_MEMRANGEHI 0x43 +#define IREG_MEMRANGELO 0x44 +#define MEMTYPE_8BIT 0x00 +#define MEMTYPE_16BIT 0x02 +#define MEMTYPE_RANGE 0x00 +#define MEMTYPE_HIADDR 0x01 +#define IREG_IO0_BASEHI 0x60 +#define IREG_IO0_BASELO 0x61 +#define IREG_IO1_BASEHI 0x62 +#define IREG_IO1_BASELO 0x63 +#define IREG_IRQ_NUMBER 0x70 +#define IREG_IRQ_TYPE 0x71 +#define IRQTYPE_HIGH 0x02 +#define IRQTYPE_LOW 0x00 +#define IRQTYPE_LEVEL 0x01 +#define IRQTYPE_EDGE 0x00 +X +#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF)) +#define LOBYTE(w) ((BYTE)(w)) +#define MAKEWORD(low,hi) ((WORD)(((BYTE)(low))|(((WORD)((BYTE)(hi)))<<8))) +X +typedef __u8 BYTE; +typedef __u16 USHORT; +typedef __u16 WORD; +X +static int config_port = -1; +X +static int msnd_write_cfg(int cfg, int reg, int value) +{ +X outb(reg, cfg); +X outb(value, cfg + 1); +X if (value != inb(cfg + 1)) { +X fprintf(stderr, "error: msnd_write_cfg: I/O error\n"); +X return -EIO; +X } +X return 0; +} +X +static int msnd_read_cfg(int cfg, int reg) +{ +X outb(reg, cfg); +X return inb(cfg + 1); +} +X +static int msnd_write_cfg_io0(int cfg, int num, WORD io) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io))) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io))) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_io0(int cfg, int num, WORD *io) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X +X *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO0_BASELO), +X msnd_read_cfg(cfg, IREG_IO0_BASEHI)); +X +X return 0; +} +X +static int msnd_write_cfg_io1(int cfg, int num, WORD io) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io))) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io))) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_io1(int cfg, int num, WORD *io) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X +X *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO1_BASELO), +X msnd_read_cfg(cfg, IREG_IO1_BASEHI)); +X +X return 0; +} +X +static int msnd_write_cfg_irq(int cfg, int num, WORD irq) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq))) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE)) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_irq(int cfg, int num, WORD *irq) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X +X *irq = msnd_read_cfg(cfg, IREG_IRQ_NUMBER); +X +X return 0; +} +X +static int msnd_write_cfg_mem(int cfg, int num, int mem) +{ +X WORD wmem; +X +X mem >>= 8; +X mem &= 0xfff; +X wmem = (WORD)mem; +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem))) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem))) +X return -EIO; +X if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT))) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_mem(int cfg, int num, int *mem) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X +X *mem = MAKEWORD(msnd_read_cfg(cfg, IREG_MEMBASELO), +X msnd_read_cfg(cfg, IREG_MEMBASEHI)); +X *mem <<= 8; +X +X return 0; +} +X +static int msnd_activate_logical(int cfg, int num) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE)) +X return -EIO; +X return 0; +} +X +static int msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg_io0(cfg, num, io0)) +X return -EIO; +X if (msnd_write_cfg_io1(cfg, num, io1)) +X return -EIO; +X if (msnd_write_cfg_irq(cfg, num, irq)) +X return -EIO; +X if (msnd_write_cfg_mem(cfg, num, mem)) +X return -EIO; +X if (msnd_activate_logical(cfg, num)) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_logical(int cfg, int num, WORD *io0, WORD *io1, WORD *irq, int *mem) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_read_cfg_io0(cfg, num, io0)) +X return -EIO; +X if (msnd_read_cfg_io1(cfg, num, io1)) +X return -EIO; +X if (msnd_read_cfg_irq(cfg, num, irq)) +X return -EIO; +X if (msnd_read_cfg_mem(cfg, num, mem)) +X return -EIO; +X return 0; +} +X +static void usage(void) +{ +X fprintf(stderr, +X "\n" +X "pinnaclecfg 1.0\n" +X "\n" +X "usage: pinnaclecfg [device config]\n" +X "\n" +X "This is for use with the card in NON-PnP mode only.\n" +X "\n" +X "Available devices (not all available for Fiji):\n" +X "\n" +X " Device Description\n" +X " -------------------------------------------------------------------\n" +X " reset Reset all devices (i.e. disable)\n" +X " show Display current device configurations\n" +X "\n" +X " dsp Audio device\n" +X " mpu Internal Kurzweil synth\n" +X " ide On-board IDE controller\n" +X " joystick Joystick port\n" +X "\n"); +X exit(1); +} +X +static int cfg_reset(void) +{ +X int i; +X +X for (i = 0; i < 4; ++i) +X msnd_write_cfg_logical(config_port, i, 0, 0, 0, 0); +X +X return 0; +} +X +static int cfg_show(void) +{ +X int i; +X int count = 0; +X +X for (i = 0; i < 4; ++i) { +X WORD io0, io1, irq; +X int mem; +X msnd_read_cfg_logical(config_port, i, &io0, &io1, &irq, &mem); +X switch (i) { +X case 0: +X if (io0 || irq || mem) { +X printf("dsp 0x%x %d 0x%x\n", io0, irq, mem); +X ++count; +X } +X break; +X case 1: +X if (io0 || irq) { +X printf("mpu 0x%x %d\n", io0, irq); +X ++count; +X } +X break; +X case 2: +X if (io0 || io1 || irq) { +X printf("ide 0x%x 0x%x %d\n", io0, io1, irq); +X ++count; +X } +X break; +X case 3: +X if (io0) { +X printf("joystick 0x%x\n", io0); +X ++count; +X } +X break; +X } +X } +X +X if (count == 0) +X fprintf(stderr, "no devices configured\n"); +X +X return 0; +} +X +static int cfg_dsp(int argc, char *argv[]) +{ +X int io, irq, mem; +X +X if (argc < 3 || +X sscanf(argv[0], "0x%x", &io) != 1 || +X sscanf(argv[1], "%d", &irq) != 1 || +X sscanf(argv[2], "0x%x", &mem) != 1) +X usage(); +X +X if (!(io == 0x290 || +X io == 0x260 || +X io == 0x250 || +X io == 0x240 || +X io == 0x230 || +X io == 0x220 || +X io == 0x210 || +X io == 0x3e0)) { +X fprintf(stderr, "error: io must be one of " +X "210, 220, 230, 240, 250, 260, 290, or 3E0\n"); +X usage(); +X } +X +X if (!(irq == 5 || +X irq == 7 || +X irq == 9 || +X irq == 10 || +X irq == 11 || +X irq == 12)) { +X fprintf(stderr, "error: irq must be one of " +X "5, 7, 9, 10, 11 or 12\n"); +X usage(); +X } +X +X if (!(mem == 0xb0000 || +X mem == 0xc8000 || +X mem == 0xd0000 || +X mem == 0xd8000 || +X mem == 0xe0000 || +X mem == 0xe8000)) { +X fprintf(stderr, "error: mem must be one of " +X "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n"); +X usage(); +X } +X +X return msnd_write_cfg_logical(config_port, 0, io, 0, irq, mem); +} +X +static int cfg_mpu(int argc, char *argv[]) +{ +X int io, irq; +X +X if (argc < 2 || +X sscanf(argv[0], "0x%x", &io) != 1 || +X sscanf(argv[1], "%d", &irq) != 1) +X usage(); +X +X return msnd_write_cfg_logical(config_port, 1, io, 0, irq, 0); +} +X +static int cfg_ide(int argc, char *argv[]) +{ +X int io0, io1, irq; +X +X if (argc < 3 || +X sscanf(argv[0], "0x%x", &io0) != 1 || +X sscanf(argv[0], "0x%x", &io1) != 1 || +X sscanf(argv[1], "%d", &irq) != 1) +X usage(); +X +X return msnd_write_cfg_logical(config_port, 2, io0, io1, irq, 0); +} +X +static int cfg_joystick(int argc, char *argv[]) +{ +X int io; +X +X if (argc < 1 || +X sscanf(argv[0], "0x%x", &io) != 1) +X usage(); +X +X return msnd_write_cfg_logical(config_port, 3, io, 0, 0, 0); +} +X int main(int argc, char *argv[]) { - int fd; - unsigned long recmask, recsrc; - - if (argc != 2) { - fprintf(stderr, "usage: setdigital \n"); - exit(1); - } else - - if ((fd = open(argv[1], O_RDWR)) < 0) { - perror(argv[1]); - exit(1); - } - - if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) { - fprintf(stderr, "error: ioctl read recmask failed\n"); - perror("ioctl"); - close(fd); - exit(1); - } - - if (!(recmask & SOUND_MASK_DIGITAL1)) { - fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n"); - close(fd); - exit(1); - } - - if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) { - fprintf(stderr, "error: ioctl read recsrc failed\n"); - perror("ioctl"); - close(fd); - exit(1); - } - - recsrc |= SOUND_MASK_DIGITAL1; - - if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) { - fprintf(stderr, "error: ioctl write recsrc failed\n"); - perror("ioctl"); - close(fd); - exit(1); - } - - close(fd); - - return 0; +X char *device; +X int rv = 0; +X +X --argc; ++argv; +X +X if (argc < 2) +X usage(); +X +X sscanf(argv[0], "0x%x", &config_port); +X if (config_port != 0x250 && config_port != 0x260 && config_port != 0x270) { +X fprintf(stderr, "error: must be 0x250, 0x260 or 0x270\n"); +X exit(1); +X } +X if (ioperm(config_port, 2, 1)) { +X perror("ioperm"); +X fprintf(stderr, "note: pinnaclecfg must be run as root\n"); +X exit(1); +X } +X device = argv[1]; +X +X argc -= 2; argv += 2; +X +X if (strcmp(device, "reset") == 0) +X rv = cfg_reset(); +X else if (strcmp(device, "show") == 0) +X rv = cfg_show(); +X else if (strcmp(device, "dsp") == 0) +X rv = cfg_dsp(argc, argv); +X else if (strcmp(device, "mpu") == 0) +X rv = cfg_mpu(argc, argv); +X else if (strcmp(device, "ide") == 0) +X rv = cfg_ide(argc, argv); +X else if (strcmp(device, "joystick") == 0) +X rv = cfg_joystick(argc, argv); +X else { +X fprintf(stderr, "error: unknown device %s\n", device); +X usage(); +X } +X +X if (rv) +X fprintf(stderr, "error: device configuration failed\n"); +X +X return 0; } --- end setdigital.c -- +SHAR_EOF + $shar_touch -am 0905082598 'MultiSound.d/pinnaclecfg.c' && + chmod 0664 'MultiSound.d/pinnaclecfg.c' || + $echo 'restore of' 'MultiSound.d/pinnaclecfg.c' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'MultiSound.d/pinnaclecfg.c:' 'MD5 check failed' +71f99b834a2845daae8ae034623e313e MultiSound.d/pinnaclecfg.c +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/pinnaclecfg.c'`" + test 10301 -eq "$shar_count" || + $echo 'MultiSound.d/pinnaclecfg.c:' 'original size' '10301,' 'current size' "$shar_count!" + fi +fi +# ============= MultiSound.d/Makefile ============== +if test -f 'MultiSound.d/Makefile' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'MultiSound.d/Makefile' '(file already exists)' +else + $echo 'x -' extracting 'MultiSound.d/Makefile' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/Makefile' && +CC = gcc +CFLAGS = -O +PROGS = setdigital pinnaclecfg conv +X +all: $(PROGS) +X +clean: +X rm -f $(PROGS) +SHAR_EOF + $shar_touch -am 0828231798 'MultiSound.d/Makefile' && + chmod 0664 'MultiSound.d/Makefile' || + $echo 'restore of' 'MultiSound.d/Makefile' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'MultiSound.d/Makefile:' 'MD5 check failed' +ab95a049d10611a5e5d559a56965b33f MultiSound.d/Makefile +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/Makefile'`" + test 96 -eq "$shar_count" || + $echo 'MultiSound.d/Makefile:' 'original size' '96,' 'current size' "$shar_count!" + fi +fi +# ============= MultiSound.d/conv.l ============== +if test -f 'MultiSound.d/conv.l' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'MultiSound.d/conv.l' '(file already exists)' +else + $echo 'x -' extracting 'MultiSound.d/conv.l' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/conv.l' && +%% +[ \n\t,\r] +\;.* +DB +[0-9A-Fa-f]+H { int n; sscanf(yytext, "%xH", &n); printf("%c", n); } +%% +int yywrap() { return 1; } +main() { yylex(); } +SHAR_EOF + $shar_touch -am 0828231798 'MultiSound.d/conv.l' && + chmod 0664 'MultiSound.d/conv.l' || + $echo 'restore of' 'MultiSound.d/conv.l' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'MultiSound.d/conv.l:' 'MD5 check failed' +d2411fc32cd71a00dcdc1f009e858dd2 MultiSound.d/conv.l +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/conv.l'`" + test 141 -eq "$shar_count" || + $echo 'MultiSound.d/conv.l:' 'original size' '141,' 'current size' "$shar_count!" + fi +fi +rm -fr _sh21233 +exit 0 diff -u --recursive --new-file v2.1.125/linux/Documentation/stallion.txt linux/Documentation/stallion.txt --- v2.1.125/linux/Documentation/stallion.txt Wed Jun 24 22:54:02 1998 +++ linux/Documentation/stallion.txt Fri Oct 23 08:26:03 1998 @@ -4,8 +4,8 @@ Copyright (C) 1994-1998, Stallion Technologies (support@stallion.com). -Version: 5.4.6 -Date: 23JUN98 +Version: 5.4.7 +Date: 23OCT98 diff -u --recursive --new-file v2.1.125/linux/MAINTAINERS linux/MAINTAINERS --- v2.1.125/linux/MAINTAINERS Fri Oct 9 13:27:04 1998 +++ linux/MAINTAINERS Tue Oct 20 14:17:45 1998 @@ -16,7 +16,8 @@ SMC etherpower for that.) 3. Make sure your changes compile correctly in multiple - configurations. + configurations. In paticular check changes work both as a module + and built into the kernel. 4. When you are happy with a change make it generally available for testing and await feedback. @@ -28,7 +29,8 @@ job the maintainers (and especially Linus) do is to keep things looking the same. Sometimes this means that the clever hack in your driver to get around a problem actual needs to become a - generalized kernel feature ready for next time. + generalized kernel feature ready for next time. See + Documentation/CodingStyle for guidance here. PLEASE try to include any credit lines you want added with the patch. It avoids people being missed off by mistake and makes @@ -240,6 +242,11 @@ L: linux-net@vger.rutgers.edu S: Maintained +ETHERTEAM 16I DRIVER +P: Mika Kuoppala +M: miku@iki.fi +S: Maintained + EXT2 FILE SYSTEM P: Remy Card M: Remy.Card@linux.org @@ -303,6 +310,12 @@ L: linux-hams@vger.rutgers.edu S: Maintained +HIPPI +P: Jes Sorensen +M: Jes.Sorensen@cern.ch +L: linux-hippi@sunsite.auc.dk +S: Maintained + HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series P: Jaroslav Kysela M: perex@jcu.cz @@ -484,9 +497,7 @@ P: Andrea Arcangeli M: andrea@e-mind.com L: linux-parport@torque.net -L: pnp-list@redhat.com W: http://www.cyberelk.demon.co.uk/parport.html -W: http://www.cage.curtin.edu.au/~campbell/parbus/ S: Maintained PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES @@ -702,6 +713,12 @@ L: linux-x25@vger.rutgers.edu S: Maintained +Z85230 SYNCHRONOUS DRIVER +P: Alan Cox +M: alan@redhat.com +W: http://roadrunner.swansea.linux.org.uk/synchronous.shtml +S: Maintained + Z8530 DRIVER FOR AX.25 P: Joerg Reuter M: jreuter@poboxes.com @@ -709,7 +726,6 @@ W: http://qsl.net/dl1bke/ L: linux-hams@vger.rutgers.edu S: Maintained - REST: P: Linus Torvalds diff -u --recursive --new-file v2.1.125/linux/Makefile linux/Makefile --- v2.1.125/linux/Makefile Fri Oct 9 13:27:04 1998 +++ linux/Makefile Fri Oct 16 20:33:22 1998 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 125 +SUBLEVEL = 126 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff -u --recursive --new-file v2.1.125/linux/README linux/README --- v2.1.125/linux/README Tue Aug 18 22:02:01 1998 +++ linux/README Sat Oct 10 10:30:35 1998 @@ -96,15 +96,6 @@ the current directory, but an alternative directory can be specified as the second argument. - - Make sure your /usr/include/asm, /usr/include/linux, and /usr/include/scsi - directories are just symlinks to the kernel sources: - - cd /usr/include - rm -rf asm linux scsi - ln -s /usr/src/linux/include/asm-i386 asm - ln -s /usr/src/linux/include/linux linux - ln -s /usr/src/linux/include/scsi scsi - - Make sure you have no stale .o files and dependencies lying around: cd /usr/src/linux diff -u --recursive --new-file v2.1.125/linux/arch/alpha/Makefile linux/arch/alpha/Makefile --- v2.1.125/linux/arch/alpha/Makefile Wed Sep 9 14:51:03 1998 +++ linux/arch/alpha/Makefile Mon Oct 12 11:40:12 1998 @@ -19,17 +19,23 @@ # Determine if GCC understands the -mcpu= option. have_mcpu := $(shell if $(CC) -mcpu=ev5 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi) -# If GENERIC, make sure to turn off any instruction set extensions that -# the host compiler might have on by default. Given that EV4 and EV5 -# have the same instruction set, prefer EV5 because an EV5 schedule is -# more likely to keep an EV4 processor busy than vice-versa. -ifeq ($(CONFIG_ALPHA_GENERIC)$(have_mcpu),yy) - CFLAGS := $(CFLAGS) -mcpu=ev5 -endif - -# If EV6, turn on the proper optimizations. -ifeq ($(CONFIG_ALPHA_EV6)$(have_mcpu),yy) - CFLAGS := $(CFLAGS) -mcpu=ev6 +# Turn on the proper cpu optimizations. +ifeq ($(have_mcpu),y) + # If GENERIC, make sure to turn off any instruction set extensions that + # the host compiler might have on by default. Given that EV4 and EV5 + # have the same instruction set, prefer EV5 because an EV5 schedule is + # more likely to keep an EV4 processor busy than vice-versa. + ifeq ($(CONFIG_ALPHA_GENERIC),y) + CFLAGS := $(CFLAGS) -mcpu=ev5 + endif + ifeq ($(CONFIG_ALPHA_EV4),y) + CFLAGS := $(CFLAGS) -mcpu=ev4 + endif + # Leave out EV5, since it is too hard to figure out whether we + # should use EV56 insns or not. + ifeq ($(CONFIG_ALPHA_EV6),y) + CFLAGS := $(CFLAGS) -mcpu=ev6 + endif endif # For TSUNAMI, we must have the assembler not emulate our instructions. diff -u --recursive --new-file v2.1.125/linux/arch/alpha/boot/Makefile linux/arch/alpha/boot/Makefile --- v2.1.125/linux/arch/alpha/boot/Makefile Wed Sep 9 14:51:03 1998 +++ linux/arch/alpha/boot/Makefile Mon Oct 12 11:40:12 1998 @@ -36,7 +36,10 @@ tools/mkbb bootimage tools/lxboot bootpfile: tools/bootph vmlinux.nh - ( cat tools/bootph vmlinux.nh ) > bootpfile + cat tools/bootph vmlinux.nh > bootpfile +ifdef INITRD + cat $(INITRD) >> bootpfile +endif srmboot: bootdevice bootimage dd if=bootimage of=$(BOOTDEV) bs=512 seek=1 skip=1 @@ -48,15 +51,18 @@ vmlinux.gz: vmlinux gzip -fv9 vmlinux -# -# A raw binary without header. Used by raw boot. -# main.o: ksize.h bootp.o: ksize.h -ksize.h: $(OBJSTRIP) vmlinux.nh - echo "#define KERNEL_SIZE `$(OBJSTRIP) -p vmlinux.nh /dev/null`" > $@ +ksize.h: vmlinux.nh dummy + echo "#define KERNEL_SIZE `ls -l vmlinux.nh | awk '{print $$5}'`" > $@T +ifdef INITRD + [ -f $(INITRD) ] || exit 1 + echo "#define INITRD_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T +endif + cmp -s $@T $@ || mv -f $@T $@ + rm -f $@T vmlinux.nh: $(VMLINUX) $(OBJSTRIP) $(OBJSTRIP) -v $(VMLINUX) vmlinux.nh @@ -91,3 +97,5 @@ rm -f vmlinux.nh ksize.h dep: + +dummy: diff -u --recursive --new-file v2.1.125/linux/arch/alpha/boot/bootp.c linux/arch/alpha/boot/bootp.c --- v2.1.125/linux/arch/alpha/boot/bootp.c Wed Sep 9 14:51:03 1998 +++ linux/arch/alpha/boot/bootp.c Mon Oct 12 11:40:12 1998 @@ -22,74 +22,30 @@ #include "ksize.h" -extern int vsprintf(char *, const char *, va_list); extern unsigned long switch_to_osf_pal(unsigned long nr, struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa, - unsigned long vptb, unsigned long *kstk); + unsigned long *vptb); -extern long dispatch(long code, ...); - -static void -puts(const char *str, int len) -{ - long written; - - while (len > 0) { - written = dispatch(CCB_PUTS, 0, str, len); - if (written < 0) - break; - len -= (unsigned int) written; - str += (unsigned int) written; - } -} - -int printk(const char * fmt, ...) -{ - va_list args; - int i, j, remaining, num_nl; - static char buf[1024]; - - va_start(args, fmt); - i = vsprintf(buf, fmt, args); - va_end(args); - - /* expand \n into \r\n: */ - - num_nl = 0; - for (j = 0; j < i; ++j) { - if (buf[j] == '\n') - ++num_nl; - } - remaining = i + num_nl; - for (j = i - 1; j >= 0; --j) { - buf[j + num_nl] = buf[j]; - if (buf[j] == '\n') { - --num_nl; - buf[j + num_nl] = '\r'; - } - } - - puts(buf, remaining); - return i; -} - -#define hwrpb (*INIT_HWRPB) +struct hwrpb_struct *hwrpb = INIT_HWRPB; +static struct pcb_struct pcb_va[1]; /* * Find a physical address of a virtual object.. * * This is easy using the virtual page table address. */ -struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb) + +static inline void * +find_pa(unsigned long *vptb, void *ptr) { - unsigned long address = (unsigned long) pcb; + unsigned long address = (unsigned long) ptr; unsigned long result; result = vptb[address >> 13]; result >>= 32; result <<= 13; result |= address & 0x1fff; - return (struct pcb_struct *) result; + return (void *) result; } /* @@ -101,31 +57,19 @@ * code has the L1 page table identity-map itself in the second PTE * in the L1 page table. Thus the L1-page is virtually addressable * itself (through three levels) at virtual address 0x200802000. - * - * As we don't want it there anyway, we also move the L1 self-map - * up as high as we can, so that the last entry in the L1 page table - * maps the page tables. - * - * As a result, the OSF/1 pal-code will instead use a virtual page table - * map located at 0xffffffe00000000. */ -#define pcb_va ((struct pcb_struct *) 0x20000000) -#define old_vptb (0x0000000200000000UL) -#define new_vptb (0xfffffffe00000000UL) -void pal_init(void) + +#define VPTB ((unsigned long *) 0x200000000) +#define L1 ((unsigned long *) 0x200802000) + +void +pal_init(void) { - unsigned long i, rev, sum; - unsigned long *L1, *l; + unsigned long i, rev; struct percpu_struct * percpu; struct pcb_struct * pcb_pa; - /* Find the level 1 page table and duplicate it in high memory */ - L1 = (unsigned long *) 0x200802000UL; /* (1<<33 | 1<<23 | 1<<13) */ - L1[1023] = L1[1]; - - percpu = (struct percpu_struct *) - (hwrpb.processor_offset + (unsigned long) &hwrpb), - + /* Create the dummy PCB. */ pcb_va->ksp = 0; pcb_va->usp = 0; pcb_va->ptbr = L1[1] >> 32; @@ -133,58 +77,45 @@ pcb_va->pcc = 0; pcb_va->unique = 0; pcb_va->flags = 1; - pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va); - printk("Switching to OSF PAL-code .. "); + pcb_va->res1 = 0; + pcb_va->res2 = 0; + pcb_pa = find_pa(VPTB, pcb_va); + /* * a0 = 2 (OSF) * a1 = return address, but we give the asm the vaddr of the PCB * a2 = physical addr of PCB * a3 = new virtual page table pointer - * a4 = KSP (but we give it 0, asm sets it) + * a4 = KSP (but the asm sets it) */ - i = switch_to_osf_pal( - 2, - pcb_va, - pcb_pa, - new_vptb, - 0); + srm_printk("Switching to OSF PAL-code .. "); + + i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB); if (i) { - printk("failed, code %ld\n", i); + srm_printk("failed, code %ld\n", i); halt(); } - rev = percpu->pal_revision = percpu->palcode_avail[2]; - hwrpb.vptb = new_vptb; + percpu = (struct percpu_struct *) + (INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB); + rev = percpu->pal_revision = percpu->palcode_avail[2]; - /* update checksum: */ - sum = 0; - for (l = (unsigned long *) &hwrpb; - l < (unsigned long *) &hwrpb.chksum; - ++l) - sum += *l; - hwrpb.chksum = sum; - - printk("Ok (rev %lx)\n", rev); - /* remove the old virtual page-table mapping */ - L1[1] = 0; + srm_printk("Ok (rev %lx)\n", rev); tbia(); /* do it directly in case we are SMP */ } -static inline long load(unsigned long dst, - unsigned long src, - unsigned long count) +static inline void +load(unsigned long dst, unsigned long src, unsigned long count) { - extern void * memcpy(void *, const void *, size_t); - memcpy((void *)dst, (void *)src, count); - return count; } /* * Start the kernel. */ -static void runkernel(void) +static inline void +runkernel(void) { __asm__ __volatile__( "bis %1,%1,$30\n\t" @@ -199,65 +130,82 @@ #define KERNEL_ORIGIN \ ((((unsigned long)&_end) + 511) & ~511) -void start_kernel(void) +void +start_kernel(void) { - static long i; - static int nbytes; /* - * note that this crufty stuff with static and envval and envbuf - * is because: + * Note that this crufty stuff with static and envval + * and envbuf is because: * - * 1. frequently, the stack is is short, and we don't want to overrun; - * 2. frequently the stack is where we are going to copy the kernel to; - * 3. a certain SRM console required the GET_ENV output to stack. + * 1. Frequently, the stack is short, and we don't want to overrun; + * 2. Frequently the stack is where we are going to copy the kernel to; + * 3. A certain SRM console required the GET_ENV output to stack. + * ??? A comment in the aboot sources indicates that the GET_ENV + * destination must be quadword aligned. Might this explain the + * behaviour, rather than requiring output to the stack, which + * seems rather far-fetched. */ - static char envval[256]; - char envbuf[256]; + static long nbytes; + static char envval[256] __attribute__((aligned(8))); +#ifdef INITRD_SIZE + static unsigned long initrd_start; +#endif - printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n"); - if (hwrpb.pagesize != 8192) { - printk("Expected 8kB pages, got %ldkB\n", - hwrpb.pagesize >> 10); + srm_printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n"); + if (INIT_HWRPB->pagesize != 8192) { + srm_printk("Expected 8kB pages, got %ldkB\n", + INIT_HWRPB->pagesize >> 10); + return; + } + if (INIT_HWRPB->vptb != (unsigned long) VPTB) { + srm_printk("Expected vptb at %p, got %p\n", + VPTB, (void *)INIT_HWRPB->vptb); return; } pal_init(); - nbytes = dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS, - envbuf, sizeof(envbuf)); - if (nbytes < 0 || nbytes >= sizeof(envbuf)) { +#ifdef INITRD_SIZE + /* The initrd must be page-aligned. See below for the + cause of the magic number 5. */ + initrd_start = ((START_ADDR + 5*KERNEL_SIZE) | (PAGE_SIZE-1)) + 1; + srm_printk("Initrd positioned at %#lx\n", initrd_start); +#endif + + nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS, + envval, sizeof(envval)); + if (nbytes < 0 || nbytes >= sizeof(envval)) { nbytes = 0; } - envbuf[nbytes] = '\0'; - memcpy(envval, envbuf, nbytes+1); - printk("Loading the kernel...'%s'\n", envval); + envval[nbytes] = '\0'; + srm_printk("Loading the kernel...'%s'\n", envval); /* NOTE: *no* callbacks or printouts from here on out!!! */ -#if 1 /* - * this is a hack, as some consoles seem to get virtual 20000000 + * This is a hack, as some consoles seem to get virtual 20000000 * (ie where the SRM console puts the kernel bootp image) memory * overlapping physical 310000 memory, which causes real problems * when attempting to copy the former to the latter... :-( * - * so, we first move the kernel virtual-to-physical way above where + * So, we first move the kernel virtual-to-physical way above where * we physically want the kernel to end up, then copy it from there * to its final resting place... ;-} * - * sigh... + * Sigh... */ - i = load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE); - i = load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE); -#else - i = load(START_ADDR, KERNEL_ORIGIN, KERNEL_SIZE); +#ifdef INITRD_SIZE + load(initrd_start, KERNEL_ORIGIN+KERNEL_SIZE, INITRD_SIZE); #endif + load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE); + load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE); + memset((char*)ZERO_PAGE, 0, PAGE_SIZE); strcpy((char*)ZERO_PAGE, envval); +#ifdef INITRD_SIZE + ((long *)(ZERO_PAGE+256))[0] = initrd_start; + ((long *)(ZERO_PAGE+256))[1] = INITRD_SIZE; +#endif runkernel(); - - for (i = 0 ; i < 0x100000000 ; i++) - /* nothing */; - halt(); } diff -u --recursive --new-file v2.1.125/linux/arch/alpha/boot/head.S linux/arch/alpha/boot/head.S --- v2.1.125/linux/arch/alpha/boot/head.S Sat Mar 16 03:52:12 1996 +++ linux/arch/alpha/boot/head.S Mon Oct 12 11:40:12 1998 @@ -6,28 +6,22 @@ #include -#define halt .long PAL_halt - .set noreorder .globl __start .ent __start __start: - bis $31,$31,$31 - br 1f - /* room for the initial PCB, which comes here */ - .quad 0,0,0,0,0,0,0,0 -1: br $27,2f -2: ldgp $29,0($27) - lda $27,start_kernel - jsr $26,($27),start_kernel - halt + br $29,2f +2: ldgp $29,0($29) + jsr $26,start_kernel + call_pal PAL_halt .end __start .align 5 .globl wrent .ent wrent wrent: - .long PAL_wrent + .prologue 0 + call_pal PAL_wrent ret ($26) .end wrent @@ -35,7 +29,8 @@ .globl wrkgp .ent wrkgp wrkgp: - .long PAL_wrkgp + .prologue 0 + call_pal PAL_wrkgp ret ($26) .end wrkgp @@ -44,6 +39,7 @@ .ent switch_to_osf_pal switch_to_osf_pal: subq $30,128,$30 + .frame $30,128,$26 stq $26,0($30) stq $1,8($30) stq $2,16($30) @@ -60,11 +56,12 @@ stq $13,104($30) stq $14,112($30) stq $15,120($30) + .prologue 0 stq $30,0($17) /* save KSP in PCB */ bis $30,$30,$20 /* a4 = KSP */ - br $17,__do_swppal + br $17,1f ldq $26,0($30) ldq $1,8($30) @@ -84,56 +81,22 @@ ldq $15,120($30) addq $30,128,$30 ret ($26) - -__do_swppal: - .long PAL_swppal +1: call_pal PAL_swppal .end switch_to_osf_pal -.globl dispatch -.ent dispatch -dispatch: - subq $30,80,$30 - stq $26,0($30) - stq $29,8($30) - - stq $8,16($30) - stq $9,24($30) - stq $10,32($30) - stq $11,40($30) - stq $12,48($30) - stq $13,56($30) - stq $14,64($30) - stq $15,72($30) - - lda $1,0x10000000 /* hwrpb */ - ldq $2,0xc0($1) /* crb offset */ - addq $2,$1,$2 /* crb */ - ldq $27,0($2) /* dispatch procedure value */ - - ldq $2,8($27) /* dispatch call address */ - jsr $26,($2) /* call it (weird VMS call seq) */ - - ldq $26,0($30) - ldq $29,8($30) - - ldq $8,16($30) - ldq $9,24($30) - ldq $10,32($30) - ldq $11,40($30) - ldq $12,48($30) - ldq $13,56($30) - ldq $14,64($30) - ldq $15,72($30) - - addq $30,80,$30 - ret $31,($26) -.end dispatch - .align 3 .globl tbi .ent tbi tbi: - .long PAL_tbi + .prologue 0 + call_pal PAL_tbi ret ($26) .end tbi + .align 3 + .globl halt + .ent halt +halt: + .prologue 0 + call_pal PAL_halt + .end halt diff -u --recursive --new-file v2.1.125/linux/arch/alpha/config.in linux/arch/alpha/config.in --- v2.1.125/linux/arch/alpha/config.in Tue Aug 18 22:02:01 1998 +++ linux/arch/alpha/config.in Mon Oct 12 11:40:12 1998 @@ -175,8 +175,6 @@ define_bool CONFIG_ALPHA_AVANTI y fi -#bool 'Echo console messages on /dev/ttyS0 (COM1)' CONFIG_SERIAL_ECHO - if [ "$CONFIG_PCI" = "y" ]; then bool 'PCI quirks' CONFIG_PCI_QUIRKS if [ "$CONFIG_PCI_QUIRKS" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c --- v2.1.125/linux/arch/alpha/kernel/alpha_ksyms.c Tue Aug 18 22:02:01 1998 +++ linux/arch/alpha/kernel/alpha_ksyms.c Mon Oct 12 11:40:12 1998 @@ -136,6 +136,37 @@ EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(__strlen_user); +/* + * SMP-specific symbols. + */ + +#ifdef __SMP__ +EXPORT_SYMBOL(synchronize_irq); +EXPORT_SYMBOL(flush_tlb_all); +EXPORT_SYMBOL(flush_tlb_mm); +EXPORT_SYMBOL(flush_tlb_page); +EXPORT_SYMBOL(flush_tlb_range); +EXPORT_SYMBOL(cpu_data); +EXPORT_SYMBOL(cpu_number_map); +EXPORT_SYMBOL(global_bh_lock); +EXPORT_SYMBOL(global_bh_count); +EXPORT_SYMBOL(synchronize_bh); +EXPORT_SYMBOL(global_irq_holder); +EXPORT_SYMBOL(__global_cli); +EXPORT_SYMBOL(__global_sti); +EXPORT_SYMBOL(__global_save_flags); +EXPORT_SYMBOL(__global_restore_flags); +#if DEBUG_SPINLOCK +EXPORT_SYMBOL(spin_unlock); +EXPORT_SYMBOL(spin_lock); +EXPORT_SYMBOL(spin_trylock); +#endif +#if DEBUG_RWLOCK +EXPORT_SYMBOL(write_lock); +EXPORT_SYMBOL(read_lock); +#endif +#endif /* __SMP__ */ + /* * The following are special because they're not called * explicitly (the C compiler or assembler generates them in diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c --- v2.1.125/linux/arch/alpha/kernel/bios32.c Wed Sep 9 14:51:03 1998 +++ linux/arch/alpha/kernel/bios32.c Mon Oct 12 11:40:12 1998 @@ -524,16 +524,8 @@ size = (mask & base) & 0xffffffff; switch (type) { case PCI_BASE_ADDRESS_MEM_TYPE_32: - break; - case PCI_BASE_ADDRESS_MEM_TYPE_64: - printk("bios32 WARNING: " - "ignoring 64-bit device in " - "slot %d, function %d: \n", - PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn)); - idx++; /* skip extra 4 bytes */ - continue; + break; case PCI_BASE_ADDRESS_MEM_TYPE_1M: /* @@ -594,6 +586,29 @@ off, base); handle = PCI_HANDLE(bus->number) | base; dev->base_address[idx] = handle; + + /* + * Currently for 64-bit cards, we simply do the usual + * for setup of the first register (low) of the pair, + * and then clear out the second (high) register, as + * we are not yet able to do 64-bit addresses, and + * setting the high register to 0 allows 32-bit SAC + * addresses to be used. + */ + if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) { + pcibios_write_config_dword(bus->number, + dev->devfn, + off+4, 0); + /* Bypass hi reg in the loop. */ + dev->base_address[++idx] = 0; + + printk("bios32 WARNING: " + "handling 64-bit device in " + "slot %d, function %d: \n", + PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + } + DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%lx (0x%x)\n", dev->device, handle, size)); } @@ -692,36 +707,46 @@ struct pci_dev *bridge = bus->self; DBG_DEVS(("layout_bus: config bus %d bridge\n", bus->number)); + /* * Set up the top and bottom of the PCI I/O segment * for this bus. */ pcibios_read_config_dword(bridge->bus->number, bridge->devfn, - 0x1c, &l); + PCI_IO_BASE, &l); l &= 0xffff0000; l |= ((bio >> 8) & 0x00f0) | ((tio - 1) & 0xf000); pcibios_write_config_dword(bridge->bus->number, bridge->devfn, - 0x1c, l); + PCI_IO_BASE, l); + + /* Also clear out the upper 16 bits. */ + pcibios_write_config_dword(bridge->bus->number, bridge->devfn, + PCI_IO_BASE_UPPER16, 0); + /* * Set up the top and bottom of the PCI Memory segment * for this bus. */ l = ((bmem & 0xfff00000) >> 16) | ((tmem - 1) & 0xfff00000); pcibios_write_config_dword(bridge->bus->number, bridge->devfn, - 0x20, l); + PCI_MEMORY_BASE, l); /* * Turn off downstream PF memory address range: */ pcibios_write_config_dword(bridge->bus->number, bridge->devfn, - 0x24, 0x0000ffff); + PCI_PREF_MEMORY_BASE, 0x0000ffff); + /* * Tell bridge that there is an ISA bus in the system, * and (possibly) a VGA as well. */ + /* ??? This appears to be a single-byte write into MIN_GNT. + What is up with this? */ l = 0x00040000; /* ISA present */ if (found_vga) l |= 0x00080000; /* VGA present */ pcibios_write_config_dword(bridge->bus->number, bridge->devfn, 0x3c, l); + /* * Clear status bits, enable I/O (for downstream I/O), * turn on master enable (for upstream I/O), turn on @@ -729,7 +754,7 @@ * master enable (for upstream memory and I/O). */ pcibios_write_config_dword(bridge->bus->number, bridge->devfn, - 0x4, 0xffff0007); + PCI_COMMAND, 0xffff0007); } DBG_DEVS(("layout_bus: bus %d finished\n", bus->number)); return found_vga; diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/core_pyxis.c linux/arch/alpha/kernel/core_pyxis.c --- v2.1.125/linux/arch/alpha/kernel/core_pyxis.c Wed Sep 9 14:51:03 1998 +++ linux/arch/alpha/kernel/core_pyxis.c Mon Oct 12 11:40:12 1998 @@ -99,33 +99,13 @@ mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr, unsigned char *type1) { - unsigned long addr; + *type1 = (bus == 0) ? 0 : 1; + *pci_addr = (bus << 16) | (device_fn << 8) | (where); DBG_CNF(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," - " pci_addr=0x%p, type1=0x%p)\n", - bus, device_fn, where, pci_addr, type1)); + " returning address 0x%p\n" + bus, device_fn, where, *pci_addr)); - if (bus == 0) { - int device; - - device = device_fn >> 3; - /* Type 0 configuration cycle. */ -#if NOT_NOW - if (device > 20) { - DBG_CNF(("mk_conf_addr: device (%d) > 20, return -1\n", - device)); - return -1; - } -#endif - *type1 = 0; - addr = (device_fn << 8) | (where); - } else { - /* Type 1 configuration cycle. */ - *type1 = 1; - addr = (bus << 16) | (device_fn << 8) | (where); - } - *pci_addr = addr; - DBG_CNF(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); return 0; } @@ -142,12 +122,11 @@ stat0 = *(vuip)PYXIS_ERR; *(vuip)PYXIS_ERR = stat0; mb(); temp = *(vuip)PYXIS_ERR; /* re-read to force write */ - DBG_CNF(("conf_read: PYXIS ERR was 0x%x\n", stat0)); /* If Type1 access, must set PYXIS CFG. */ if (type1) { pyxis_cfg = *(vuip)PYXIS_CFG; - *(vuip)PYXIS_CFG = pyxis_cfg | 1; mb(); + *(vuip)PYXIS_CFG = (pyxis_cfg & ~3L) | 1; mb(); temp = *(vuip)PYXIS_CFG; /* re-read to force write */ } @@ -172,14 +151,15 @@ /* If Type1 access, must reset IOC CFG so normal IO space ops work. */ if (type1) { - *(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb(); + *(vuip)PYXIS_CFG = pyxis_cfg & ~3L; mb(); temp = *(vuip)PYXIS_CFG; /* re-read to force write */ } + __restore_flags(flags); + DBG_CNF(("conf_read(addr=0x%lx, type1=%d) = %#x\n", addr, type1, value)); - __restore_flags(flags); return value; } @@ -190,9 +170,6 @@ unsigned int stat0, temp; unsigned int pyxis_cfg = 0; - DBG_CNF(("conf_write(addr=%#lx, value=%#x, type1=%d)\n", - addr, value, type1)); - __save_and_cli(flags); /* avoid getting hit by machine check */ /* Reset status register to avoid losing errors. */ @@ -203,7 +180,7 @@ /* If Type1 access, must set PYXIS CFG. */ if (type1) { pyxis_cfg = *(vuip)PYXIS_CFG; - *(vuip)PYXIS_CFG = pyxis_cfg | 1; mb(); + *(vuip)PYXIS_CFG = (pyxis_cfg & ~3L) | 1; mb(); temp = *(vuip)PYXIS_CFG; /* re-read to force write */ } @@ -216,18 +193,20 @@ /* Access configuration space. */ *(vuip)addr = value; mb(); - mb(); /* magic */ - temp = *(vuip)PYXIS_ERR; /* do a PYXIS read to force the write */ + temp = *(vuip)addr; /* read back to force the write */ PYXIS_mcheck_expected = 0; mb(); /* If Type1 access, must reset IOC CFG so normal IO space ops work. */ if (type1) { - *(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb(); + *(vuip)PYXIS_CFG = pyxis_cfg & ~3L; mb(); temp = *(vuip)PYXIS_CFG; /* re-read to force write */ } __restore_flags(flags); + + DBG_CNF(("conf_write(addr=%#lx, value=%#x, type1=%d)\n", + addr, value, type1)); } int diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v2.1.125/linux/arch/alpha/kernel/entry.S Wed Sep 9 14:51:03 1998 +++ linux/arch/alpha/kernel/entry.S Mon Oct 12 11:40:12 1998 @@ -552,7 +552,6 @@ ret_from_sys_call: cmovne $26,0,$19 /* $19 = 0 => non-restartable */ /* check bottom half interrupts */ - bne $1,ret_from_handle_bh ldq $3,bh_active ldq $4,bh_mask and $3,$4,$2 @@ -678,7 +677,7 @@ bis $30,$30,$18 bis $31,$31,$16 jsr $26,do_signal - lda $30,SWITCH_STACK_SIZE($30) + bsr $1,undo_switch_stack br $31,restore_all .end entSys diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/head.S linux/arch/alpha/kernel/head.S --- v2.1.125/linux/arch/alpha/kernel/head.S Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/head.S Mon Oct 12 11:40:12 1998 @@ -9,8 +9,6 @@ #include -#define halt call_pal PAL_halt - .globl swapper_pg_dir .globl _stext swapper_pg_dir=SWAPPER_PGD @@ -29,28 +27,28 @@ lda $30,0x4000($8) /* ... and then we can start the kernel. */ jsr $26,start_kernel - halt + call_pal PAL_halt .end __start #ifdef __SMP__ .align 3 .globl __start_cpu .ent __start_cpu - /* on entry here from SRM console, the HWPCB of this processor */ - /* has been loaded, and $27 contains the task pointer */ + /* On entry here from SRM console, the HWPCB of this processor + has been loaded, and $27 contains the task pointer */ __start_cpu: .prologue 0 - /* first order of business, load the GP */ + /* First order of business, load the GP */ br $26,1f 1: ldgp $29,0($26) /* We need to get current loaded up with our first task... */ - lda $8,0($27) - /* set FEN */ + mov $27,$8 + /* Set FEN */ lda $16,1($31) call_pal PAL_wrfen /* ... and then we can start the processor. */ jsr $26,start_secondary - halt + call_pal PAL_halt .end __start_cpu #endif /* __SMP__ */ @@ -121,10 +119,20 @@ .globl wripir .ent wripir wripir: + .prologue 0 call_pal PAL_wripir ret ($26) .end wripir + .align 3 + .globl wrvptptr + .ent wrvptptr +wrvptptr: + .prologue 0 + call_pal PAL_wrvptptr + ret ($26) + .end wrvptptr + # # The following two functions are needed for supporting SRM PALcode # on the PC164 (at least), since that PALcode manages the interrupt @@ -152,3 +160,17 @@ call_pal PAL_cserve ret ($26) .end cserve_dis + + # + # It is handy, on occasion, to make halt actually just loop. + # Putting it here means we dont have to recompile the whole + # kernel. + # + + .align 3 + .globl halt + .ent halt +halt: + .prologue 0 + call_pal PAL_halt + .end halt diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c --- v2.1.125/linux/arch/alpha/kernel/irq.c Wed Sep 9 14:51:03 1998 +++ linux/arch/alpha/kernel/irq.c Mon Oct 12 11:40:12 1998 @@ -311,26 +311,41 @@ int get_irq_list(char *buf) { - int i, len = 0; + int i, j; struct irqaction * action; - int cpu = smp_processor_id(); + char *p = buf; + +#ifdef __SMP__ + p += sprintf(p, " "); + for (j = 0; j < smp_num_cpus; j++) + p += sprintf(p, "CPU%d ", j); + *p++ = '\n'; +#endif for (i = 0; i < NR_IRQS; i++) { action = irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %10u %c %s", - i, kstat.irqs[cpu][i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); + p += sprintf(p, "%3d: ",i); +#ifndef __SMP__ + p += sprintf(p, "%10u ", kstat_irqs(i)); +#else + for (j = 0; j < smp_num_cpus; j++) + p += sprintf(p, "%10u ", + kstat.irqs[cpu_logical_map(j)][i]); +#endif + p += sprintf(p, " %c%s", + (action->flags & SA_INTERRUPT)?'+':' ', + action->name); + for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ", %s%s", - (action->flags & SA_INTERRUPT) ? "+":"", - action->name); + p += sprintf(p, ", %c%s", + (action->flags & SA_INTERRUPT)?'+':' ', + action->name); } - len += sprintf(buf+len, "\n"); + *p++ = '\n'; } - return len; + return p - buf; } #ifdef __SMP__ @@ -427,8 +442,10 @@ /* * Finally. */ +#if DEBUG_SPINLOCK global_irq_lock.task = current; global_irq_lock.previous = where; +#endif global_irq_holder = cpu; previous_irqholder = where; } diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/irq.h linux/arch/alpha/kernel/irq.h --- v2.1.125/linux/arch/alpha/kernel/irq.h Wed Sep 9 14:51:03 1998 +++ linux/arch/alpha/kernel/irq.h Mon Oct 12 11:40:12 1998 @@ -11,12 +11,8 @@ #define STANDARD_INIT_IRQ_PROLOG \ outb(0, DMA1_RESET_REG); \ outb(0, DMA2_RESET_REG); \ - outb(0, DMA1_MASK_REG); \ - outb(0, DMA2_MASK_REG); \ outb(0, DMA1_CLR_MASK_REG); \ - outb(0, DMA2_CLR_MASK_REG); \ - outb(DMA_MODE_CASCADE, DMA2_MODE_REG) - + outb(0, DMA2_CLR_MASK_REG) extern unsigned long alpha_irq_mask; diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/machvec.h linux/arch/alpha/kernel/machvec.h --- v2.1.125/linux/arch/alpha/kernel/machvec.h Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/machvec.h Mon Oct 12 11:40:12 1998 @@ -27,8 +27,7 @@ #define CAT1(x,y) x##y #define CAT(x,y) CAT1(x,y) -#define DO_DEFAULT_RTC \ - rtc_port: 0x70, rtc_addr: 0x80, rtc_bcd: 0 +#define DO_DEFAULT_RTC rtc_port: 0x70 #define DO_EV4_MMU \ max_asn: EV4_MAX_ASN, \ diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v2.1.125/linux/arch/alpha/kernel/process.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/process.c Mon Oct 12 11:40:12 1998 @@ -181,6 +181,9 @@ return; } + if (alpha_using_srm) + srm_paging_stop(); + halt(); } diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h --- v2.1.125/linux/arch/alpha/kernel/proto.h Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/proto.h Mon Oct 12 11:40:12 1998 @@ -143,6 +143,7 @@ /* time.c */ extern void timer_interrupt(int irq, void *dev, struct pt_regs * regs); +extern unsigned long est_cycle_freq; /* smc37c93x.c */ extern void SMC93x_Init(void); @@ -172,5 +173,12 @@ extern void entUna(void); /* process.c */ -void generic_kill_arch (int mode, char *reboot_cmd); -void cpu_idle(void *) __attribute__((noreturn)); +extern void generic_kill_arch (int mode, char *reboot_cmd); +extern void cpu_idle(void *) __attribute__((noreturn)); + +/* ptrace.c */ +extern int ptrace_set_bpt (struct task_struct *child); +extern int ptrace_cancel_bpt (struct task_struct *child); + +/* ../mm/init.c */ +void srm_paging_stop(void); diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c --- v2.1.125/linux/arch/alpha/kernel/ptrace.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/ptrace.c Mon Oct 12 11:40:12 1998 @@ -12,27 +12,26 @@ #include #include #include +#include #include #include #include +#include "proto.h" + +#define DEBUG DBG_MEM #undef DEBUG #ifdef DEBUG - enum { DBG_MEM = (1<<0), DBG_BPT = (1<<1), DBG_MEM_ALL = (1<<2) }; - -int debug_mask = DBG_BPT; - -# define DBG(fac,args) {if ((fac) & debug_mask) printk args;} - +#define DBG(fac,args) {if ((fac) & DEBUG) printk args;} #else -# define DBG(fac,args) +#define DBG(fac,args) #endif #define BREAKINST 0x00000080 /* call_pal bpt */ @@ -45,33 +44,26 @@ /* * Processes always block with the following stack-layout: * - * +================================+ -------------------------- - * | PALcode saved frame (ps, pc, | ^ ^ - * | gp, a0, a1, a2) | | | - * +================================+ | struct pt_regs | - * | | | | - * | frame generated by SAVE_ALL | | | - * | | v | P - * +================================+ | A - * | | ^ | G - * | frame saved by do_switch_stack | | struct switch_stack | E - * | | v | _ - * +================================+ | S - * | | | I - * | | | Z - * / / | E - * / / | - * | | | - * | | | - * | | v - * +================================+ <------------------------- - * task + PAGE_SIZE + * +================================+ <---- task + 2*PAGE_SIZE + * | PALcode saved frame (ps, pc, | ^ + * | gp, a0, a1, a2) | | + * +================================+ | struct pt_regs + * | | | + * | frame generated by SAVE_ALL | | + * | | v + * +================================+ + * | | ^ + * | frame saved by do_switch_stack | | struct switch_stack + * | | v + * +================================+ */ -#define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \ +#define PT_REG(reg) (PAGE_SIZE*2 - sizeof(struct pt_regs) \ + (long)&((struct pt_regs *)0)->reg) -#define SW_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \ - - sizeof(struct switch_stack) \ + +#define SW_REG(reg) (PAGE_SIZE*2 - sizeof(struct pt_regs) \ + - sizeof(struct switch_stack) \ + (long)&((struct switch_stack *)0)->reg) + /* * The following table maps a register index into the stack offset at * which the register is saved. Register indices are 0-31 for integer @@ -80,10 +72,10 @@ * get_reg/put_reg below). */ enum { - REG_R0 = 0, REG_F0 = 32, REG_PC = 64 + REG_R0 = 0, REG_F0 = 32, REG_FPCR = 63, REG_PC = 64 }; -static unsigned short regoff[] = { +static int regoff[] = { PT_REG( r0), PT_REG( r1), PT_REG( r2), PT_REG( r3), PT_REG( r4), PT_REG( r5), PT_REG( r6), PT_REG( r7), PT_REG( r8), SW_REG( r9), SW_REG( r10), SW_REG( r11), @@ -106,38 +98,40 @@ static long zero; /* - * Get contents of register REGNO in task TASK. + * Get address of register REGNO in task TASK. */ -static inline long get_reg(struct task_struct * task, long regno) +static long * +get_reg_addr(struct task_struct * task, unsigned long regno) { long *addr; if (regno == 30) { addr = &task->tss.usp; - } else if (regno == 31) { + } else if (regno == 31 || regno > 64) { zero = 0; addr = &zero; } else { - addr = (long *) (regoff[regno] + PAGE_SIZE + (long)task); + addr = (long *)((long)task + regoff[regno]); } - return *addr; + return addr; } /* - * Write contents of register REGNO in task TASK. + * Get contents of register REGNO in task TASK. */ -static inline int put_reg(struct task_struct *task, long regno, long data) +static inline long +get_reg(struct task_struct * task, unsigned long regno) { - long *addr, zero; + return *get_reg_addr(task, regno); +} - if (regno == 30) { - addr = &task->tss.usp; - } else if (regno == 31) { - addr = &zero; - } else { - addr = (long *) (regoff[regno] + PAGE_SIZE + (long)task); - } - *addr = data; +/* + * Write contents of register REGNO in task TASK. + */ +static inline int +put_reg(struct task_struct *task, unsigned long regno, long data) +{ + *get_reg_addr(task, regno) = data; return 0; } @@ -147,8 +141,9 @@ * and that it is in the task area before calling this: this routine does * no checking. */ -static unsigned long get_long(struct task_struct * tsk, - struct vm_area_struct * vma, unsigned long addr) +static unsigned long +get_long(struct task_struct * tsk, struct vm_area_struct * vma, + unsigned long addr) { pgd_t * pgdir; pmd_t * pgmiddle; @@ -199,8 +194,9 @@ * Now keeps R/W state of page so that a text page stays readonly * even if a debugger scribbles breakpoints into it. -M.U- */ -static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, - unsigned long addr, unsigned long data) +static void +put_long(struct task_struct * tsk, struct vm_area_struct * vma, + unsigned long addr, unsigned long data) { pgd_t *pgdir; pmd_t *pgmiddle; @@ -250,8 +246,8 @@ flush_tlb(); } -static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, - unsigned long addr) +static struct vm_area_struct * +find_extend_vma(struct task_struct * tsk, unsigned long addr) { struct vm_area_struct * vma; @@ -274,8 +270,8 @@ * This routine checks the page boundaries, and that the offset is * within the task area. It then calls get_long() to read a long. */ -static int read_long(struct task_struct * tsk, unsigned long addr, - unsigned long * result) +static int +read_long(struct task_struct * tsk, unsigned long addr, unsigned long * result) { struct vm_area_struct * vma = find_extend_vma(tsk, addr); @@ -315,8 +311,8 @@ * This routine checks the page boundaries, and that the offset is * within the task area. It then calls put_long() to write a long. */ -static int write_long(struct task_struct * tsk, unsigned long addr, - unsigned long data) +static int +write_long(struct task_struct * tsk, unsigned long addr, unsigned long data) { struct vm_area_struct * vma = find_extend_vma(tsk, addr); @@ -349,8 +345,8 @@ /* * Read a 32bit int from address space TSK. */ -static int read_int(struct task_struct * tsk, unsigned long addr, - unsigned int *data) +static int +read_int(struct task_struct * tsk, unsigned long addr, unsigned int *data) { unsigned long l, align; int res; @@ -376,8 +372,8 @@ * For simplicity, do a read-modify-write of the 64bit word that * contains the 32bit word that we are about to write. */ -static int write_int(struct task_struct * tsk, unsigned long addr, - unsigned int data) +static int +write_int(struct task_struct * tsk, unsigned long addr, unsigned int data) { unsigned long l, align; int res; @@ -400,7 +396,8 @@ /* * Set breakpoint. */ -int ptrace_set_bpt(struct task_struct * child) +int +ptrace_set_bpt(struct task_struct * child) { int displ, i, res, reg_b, nsaved = 0; u32 insn, op_code; @@ -422,31 +419,31 @@ * branch (emulation can be tricky for fp branches). */ displ = ((s32)(insn << 11)) >> 9; - child->tss.debugreg[nsaved++] = pc + 4; + child->tss.bpt_addr[nsaved++] = pc + 4; if (displ) /* guard against unoptimized code */ - child->tss.debugreg[nsaved++] = pc + 4 + displ; + child->tss.bpt_addr[nsaved++] = pc + 4 + displ; DBG(DBG_BPT, ("execing branch\n")); } else if (op_code == 0x1a) { reg_b = (insn >> 16) & 0x1f; - child->tss.debugreg[nsaved++] = get_reg(child, reg_b); + child->tss.bpt_addr[nsaved++] = get_reg(child, reg_b); DBG(DBG_BPT, ("execing jump\n")); } else { - child->tss.debugreg[nsaved++] = pc + 4; + child->tss.bpt_addr[nsaved++] = pc + 4; DBG(DBG_BPT, ("execing normal insn\n")); } /* install breakpoints: */ for (i = 0; i < nsaved; ++i) { - res = read_int(child, child->tss.debugreg[i], &insn); + res = read_int(child, child->tss.bpt_addr[i], &insn); if (res < 0) return res; - child->tss.debugreg[i + 2] = insn; - DBG(DBG_BPT, (" -> next_pc=%lx\n", child->tss.debugreg[i])); - res = write_int(child, child->tss.debugreg[i], BREAKINST); + child->tss.bpt_insn[i] = insn; + DBG(DBG_BPT, (" -> next_pc=%lx\n", child->tss.bpt_addr[i])); + res = write_int(child, child->tss.bpt_addr[i], BREAKINST); if (res < 0) return res; } - child->tss.debugreg[4] = nsaved; + child->tss.bpt_nsaved = nsaved; return 0; } @@ -454,11 +451,12 @@ * Ensure no single-step breakpoint is pending. Returns non-zero * value if child was being single-stepped. */ -int ptrace_cancel_bpt(struct task_struct * child) +int +ptrace_cancel_bpt(struct task_struct * child) { - int i, nsaved = child->tss.debugreg[4]; + int i, nsaved = child->tss.bpt_nsaved; - child->tss.debugreg[4] = 0; + child->tss.bpt_nsaved = 0; if (nsaved > 2) { printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved); @@ -466,16 +464,18 @@ } for (i = 0; i < nsaved; ++i) { - write_int(child, child->tss.debugreg[i], - child->tss.debugreg[i + 2]); + write_int(child, child->tss.bpt_addr[i], + child->tss.bpt_insn[i]); } return (nsaved != 0); } -asmlinkage long sys_ptrace(long request, long pid, long addr, long data, - int a4, int a5, struct pt_regs regs) +asmlinkage long +sys_ptrace(long request, long pid, long addr, long data, + int a4, int a5, struct pt_regs regs) { struct task_struct *child; + unsigned long tmp; long ret; lock_kernel(); @@ -540,9 +540,7 @@ switch (request) { /* When I and D space are separate, these will need to be fixed. */ case PTRACE_PEEKTEXT: /* read word at location addr. */ - case PTRACE_PEEKDATA: { - unsigned long tmp; - + case PTRACE_PEEKDATA: ret = read_long(child, addr, &tmp); DBG(DBG_MEM, ("peek %#lx->%#lx\n", addr, tmp)); if (ret < 0) @@ -550,13 +548,12 @@ regs.r0 = 0; /* special return: no errors */ ret = tmp; goto out; - } - /* read register number ADDR. */ + /* Read register number ADDR. */ case PTRACE_PEEKUSR: regs.r0 = 0; /* special return: no errors */ - DBG(DBG_MEM, ("peek $%ld=%#lx\n", addr, regs.r0)); ret = get_reg(child, addr); + DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret)); goto out; /* When I and D space are separate, this will have to be fixed. */ @@ -573,7 +570,7 @@ case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: { /* restart after signal. */ + case PTRACE_CONT: /* restart after signal. */ ret = -EIO; if ((unsigned long) data > _NSIG) goto out; @@ -587,14 +584,13 @@ ptrace_cancel_bpt(child); ret = data; goto out; - } /* * Make the child exit. Best I can do is send it a sigkill. * perhaps it should be put in the status that it wants to * exit. */ - case PTRACE_KILL: { + case PTRACE_KILL: if (child->state != TASK_ZOMBIE) { wake_up_process(child); child->exit_code = SIGKILL; @@ -603,22 +599,20 @@ ptrace_cancel_bpt(child); ret = 0; goto out; - } - case PTRACE_SINGLESTEP: { /* execute single instruction. */ + case PTRACE_SINGLESTEP: /* execute single instruction. */ ret = -EIO; if ((unsigned long) data > _NSIG) goto out; - child->tss.debugreg[4] = -1; /* mark single-stepping */ + child->tss.bpt_nsaved = -1; /* mark single-stepping */ child->flags &= ~PF_TRACESYS; wake_up_process(child); child->exit_code = data; /* give it a chance to run. */ ret = 0; goto out; - } - case PTRACE_DETACH: { /* detach a process that was attached. */ + case PTRACE_DETACH: /* detach a process that was attached. */ ret = -EIO; if ((unsigned long) data > _NSIG) goto out; @@ -632,7 +626,6 @@ ptrace_cancel_bpt(child); ret = 0; goto out; - } default: ret = -EIO; @@ -643,7 +636,8 @@ return ret; } -asmlinkage void syscall_trace(void) +asmlinkage void +syscall_trace(void) { if ((current->flags & (PF_PTRACED|PF_TRACESYS)) != (PF_PTRACED|PF_TRACESYS)) diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c --- v2.1.125/linux/arch/alpha/kernel/setup.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/setup.c Mon Oct 12 11:40:12 1998 @@ -467,19 +467,22 @@ vec = eb66_vecs[eb66_indices[member]]; break; case ST_DEC_1000: - if (cpu == EV5_CPU) + cpu &= 0xffffffff; + if (cpu == EV5_CPU || cpu == EV56_CPU) vec = &mikasa_primo_mv; else vec = &mikasa_mv; break; case ST_DEC_NORITAKE: - if (cpu == EV5_CPU) + cpu &= 0xffffffff; + if (cpu == EV5_CPU || cpu == EV56_CPU) vec = &noritake_primo_mv; else vec = &noritake_mv; break; case ST_DEC_2100_A500: - if (cpu == EV5_CPU) + cpu &= 0xffffffff; + if (cpu == EV5_CPU || cpu == EV56_CPU) vec = &sable_gamma_mv; else vec = &sable_mv; @@ -678,7 +681,7 @@ "system variation\t: %s\n" "system revision\t\t: %ld\n" "system serial number\t: %s\n" - "cycle frequency [Hz]\t: %lu\n" + "cycle frequency [Hz]\t: %lu %s\n" "timer frequency [Hz]\t: %lu.%02lu\n" "page size [bytes]\t: %ld\n" "phys. address bits\t: %ld\n" @@ -691,7 +694,8 @@ (char*)cpu->serial_no, systype_name, sysvariation_name, hwrpb->sys_revision, (char*)hwrpb->ssn, - hwrpb->cycle_freq, + hwrpb->cycle_freq ? : est_cycle_freq, + hwrpb->cycle_freq ? "" : "est.", hwrpb->intr_freq / 4096, (100 * hwrpb->intr_freq / 4096) % 100, hwrpb->pagesize, @@ -703,8 +707,8 @@ platform_string()); #ifdef __SMP__ - return len + smp_info(buffer+len); -#else - return len; + len += smp_info(buffer+len); #endif + + return len; } diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c --- v2.1.125/linux/arch/alpha/kernel/signal.c Tue Jun 23 10:01:19 1998 +++ linux/arch/alpha/kernel/signal.c Mon Oct 12 11:40:12 1998 @@ -33,9 +33,6 @@ asmlinkage int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *, unsigned long, unsigned long); -extern int ptrace_set_bpt (struct task_struct *child); -extern int ptrace_cancel_bpt (struct task_struct *child); - /* * The OSF/1 sigprocmask calling sequence is different from the diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/smc37c93x.c linux/arch/alpha/kernel/smc37c93x.c --- v2.1.125/linux/arch/alpha/kernel/smc37c93x.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/smc37c93x.c Mon Oct 12 11:40:12 1998 @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -86,21 +87,28 @@ unsigned long indexPort; unsigned long dataPort; + int i; + configPort = indexPort = baseAddr; dataPort = configPort + 1; - outb(CONFIG_ON_KEY, configPort); - outb(CONFIG_ON_KEY, configPort); - outb(DEVICE_ID, indexPort); - devId = inb(dataPort); - if ( devId == VALID_DEVICE_ID ) { - outb(DEVICE_REV, indexPort); - devRev = inb(dataPort); - } - else { - baseAddr = 0; +#define NUM_RETRIES 5 + + for (i = 0; i < NUM_RETRIES; i++) + { + outb(CONFIG_ON_KEY, configPort); + outb(CONFIG_ON_KEY, configPort); + outb(DEVICE_ID, indexPort); + devId = inb(dataPort); + if (devId == VALID_DEVICE_ID) { + outb(DEVICE_REV, indexPort); + devRev = inb(dataPort); + break; + } + else + udelay(100); } - return baseAddr; + return (i != NUM_RETRIES) ? baseAddr : 0L; } static void __init SMCRunState(unsigned long baseAddr) diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c --- v2.1.125/linux/arch/alpha/kernel/smp.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/smp.c Mon Oct 12 11:40:12 1998 @@ -39,6 +39,7 @@ unsigned int boot_cpu_id = 0; static int smp_activated = 0; +static unsigned long ipicnt[NR_CPUS] = {0,}; /* IPI counts */ int smp_found_config = 0; /* Have we found an SMP box */ static int max_cpus = -1; @@ -619,7 +620,6 @@ { tbia(); clear_bit(this_cpu, &ipi_msg_flush_tb.flush_tb_mask); - mb(); return 0; } @@ -627,12 +627,9 @@ local_flush_tlb_mm(unsigned int this_cpu) { struct mm_struct * mm = ipi_msg_flush_tb.p.flush_mm; - if (mm != current->mm) - flush_tlb_other(mm); - else + if (mm == current->mm) flush_tlb_current(mm); clear_bit(this_cpu, &ipi_msg_flush_tb.flush_tb_mask); - mb(); return 0; } @@ -642,12 +639,9 @@ struct vm_area_struct * vma = ipi_msg_flush_tb.p.flush_vma; struct mm_struct * mm = vma->vm_mm; - if (mm != current->mm) - flush_tlb_other(mm); - else + if (mm == current->mm) flush_tlb_current_page(mm, vma, ipi_msg_flush_tb.flush_addr); clear_bit(this_cpu, &ipi_msg_flush_tb.flush_tb_mask); - mb(); return 0; } @@ -701,7 +695,7 @@ volatile int * pending_ipis = &ipi_bits[this_cpu]; int ops; - mb(); + mb(); /* Order bit setting and interrupt. */ #if 0 printk("handle_ipi: on CPU %d ops 0x%x PC 0x%lx\n", this_cpu, *pending_ipis, regs->pc); @@ -711,10 +705,10 @@ for (first = 0; (ops & 1) == 0; ++first, ops >>= 1) ; /* look for the first thing to do */ clear_bit(first, pending_ipis); - mb(); + mb(); /* Order bit clearing and data access. */ if ((*ipi_func[first])(this_cpu)) - printk("%d\n", first); - mb(); + printk("%d\n", first); + mb(); /* Order data access and bit clearing. */ } if (hwrpb->txrdy) secondary_console_message(); @@ -726,19 +720,26 @@ int i; unsigned int j; + mb(); /* Order out-of-band data and bit setting. */ for (i = 0, j = 1; i < NR_CPUS; ++i, j += j) { if ((to_whom & j) == 0) continue; set_bit(operation, &ipi_bits[i]); - mb(); + mb(); /* Order bit setting and interrupt. */ wripir(i); } } -int smp_info(char *buffer) +int +smp_info(char *buffer) { - return sprintf(buffer, "CPUs probed %d active %d map 0x%x\n", - smp_num_probed, smp_num_cpus, cpu_present_map); + int i; + unsigned long sum = 0; + for (i = 0; i < NR_CPUS; i++) + sum += ipicnt[i]; + + return sprintf(buffer, "CPUs probed %d active %d map 0x%x IPIs %ld\n", + smp_num_probed, smp_num_cpus, cpu_present_map, sum); } /* wrapper for call from panic() */ @@ -763,19 +764,22 @@ unsigned int to_whom = cpu_present_map ^ (1 << smp_processor_id()); int timeout = 10000; + spin_lock_own(&kernel_flag, "flush_tlb_all"); + ipi_msg_flush_tb.flush_tb_mask = to_whom; send_ipi_message(to_whom, TLB_ALL); tbia(); while (ipi_msg_flush_tb.flush_tb_mask) { - if (--timeout < 0) { - printk("flush_tlb_all: STUCK on CPU %d mask 0x%x\n", - smp_processor_id(), ipi_msg_flush_tb.flush_tb_mask); - ipi_msg_flush_tb.flush_tb_mask = 0; - break; - } - udelay(100); - ; /* Wait for all clear from other CPUs. */ + if (--timeout < 0) { + printk("flush_tlb_all: STUCK on CPU %d mask 0x%x\n", + smp_processor_id(), + ipi_msg_flush_tb.flush_tb_mask); + ipi_msg_flush_tb.flush_tb_mask = 0; + break; + } + /* Wait for all clear from other CPUs. */ + udelay(100); } } @@ -785,6 +789,8 @@ unsigned int to_whom = cpu_present_map ^ (1 << smp_processor_id()); int timeout = 10000; + spin_lock_own(&kernel_flag, "flush_tlb_mm"); + ipi_msg_flush_tb.p.flush_mm = mm; ipi_msg_flush_tb.flush_tb_mask = to_whom; send_ipi_message(to_whom, TLB_MM); @@ -814,6 +820,8 @@ struct mm_struct * mm = vma->vm_mm; int timeout = 10000; + spin_lock_own(&kernel_flag, "flush_tlb_page"); + ipi_msg_flush_tb.p.flush_vma = vma; ipi_msg_flush_tb.flush_addr = addr; ipi_msg_flush_tb.flush_tb_mask = to_whom; @@ -849,6 +857,8 @@ timeout = 10000; to_whom = cpu_present_map ^ (1 << smp_processor_id()); + spin_lock_own(&kernel_flag, "flush_tlb_range"); + ipi_msg_flush_tb.p.flush_mm = mm; ipi_msg_flush_tb.flush_tb_mask = to_whom; send_ipi_message(to_whom, TLB_MM); @@ -871,11 +881,51 @@ } #if DEBUG_SPINLOCK -void spin_lock(spinlock_t * lock) + +#ifdef MANAGE_SPINLOCK_IPL + +static inline long +spinlock_raise_ipl(spinlock_t * lock) +{ + long min_ipl = lock->target_ipl; + long last_ipl = swpipl(7); + if (last_ipl < 7 && min_ipl < 7) + setipl(min_ipl < last_ipl ? last_ipl : min_ipl); + return last_ipl; +} + +static inline void +spinlock_restore_ipl(long prev) +{ + setipl(prev); +} + +#else + +#define spinlock_raise_ipl(LOCK) 0 +#define spinlock_restore_ipl(PREV) ((void)0) + +#endif /* MANAGE_SPINLOCK_IPL */ + +void +spin_unlock(spinlock_t * lock) +{ + long old_ipl = lock->saved_ipl; + mb(); + lock->lock = 0; + spinlock_restore_ipl(old_ipl); +} + +void +spin_lock(spinlock_t * lock) { long tmp; - long stuck; + long stuck = 1<<27; void *inline_pc = __builtin_return_address(0); + unsigned long started = jiffies; + int printed = 0; + int cpu = smp_processor_id(); + long old_ipl = spinlock_raise_ipl(lock); try_again: @@ -885,15 +935,15 @@ of this object file's text section so as to perfect branch prediction. */ __asm__ __volatile__( - "1: ldq_l %0,%1\n" + "1: ldl_l %0,%1\n" " subq %2,1,%2\n" " blbs %0,2f\n" " or %0,1,%0\n" - " stq_c %0,%1\n" + " stl_c %0,%1\n" " beq %0,3f\n" "4: mb\n" ".section .text2,\"ax\"\n" - "2: ldq %0,%1\n" + "2: ldl %0,%1\n" " subq %2,1,%2\n" "3: blt %2,4b\n" " blbs %0,2b\n" @@ -905,13 +955,43 @@ : "2" (stuck)); if (stuck < 0) { - printk("spinlock stuck at %p (cur=%p, own=%p, prev=%p)\n", - inline_pc, current, lock->task, lock->previous); + if (!printed) { + printk("spinlock stuck at %p(%d) owner %s at %p\n", + inline_pc, cpu, lock->task->comm, + lock->previous); + printed = 1; + } + stuck = 1<<30; goto try_again; - } else { - lock->previous = inline_pc; + } + + /* Exiting. Got the lock. */ + lock->saved_ipl = old_ipl; + lock->on_cpu = cpu; + lock->previous = inline_pc; + lock->task = current; + + if (printed) { + printk("spinlock grabbed at %p(%d) %ld ticks\n", + inline_pc, cpu, jiffies - started); + } +} + +int +spin_trylock(spinlock_t * lock) +{ + long old_ipl = spinlock_raise_ipl(lock); + int ret; + if ((ret = !test_and_set_bit(0, lock))) { + mb(); + lock->saved_ipl = old_ipl; + lock->on_cpu = smp_processor_id(); + lock->previous = __builtin_return_address(0); lock->task = current; + } else { + spinlock_restore_ipl(old_ipl); } + return ret; } #endif /* DEBUG_SPINLOCK */ @@ -930,22 +1010,21 @@ __asm__ __volatile__( "1: ldl_l %1,%0\n" " blbs %1,6f\n" - " or %1,1,%2\n" - " stl_c %2,%0\n" - " beq %2,6f\n" " blt %1,8f\n" + " mov 1,%1\n" + " stl_c %1,%0\n" + " beq %1,6f\n" "4: mb\n" ".section .text2,\"ax\"\n" - "6: ldl %1,%0\n" - " blt %3,4b # debug\n" + "6: blt %3,4b # debug\n" " subl %3,1,%3 # debug\n" + " ldl %1,%0\n" " blbs %1,6b\n" - " br 1b\n" - "8: ldl %1,%0\n" - " blt %4,4b # debug\n" + "8: blt %4,4b # debug\n" " subl %4,1,%4 # debug\n" + " ldl %1,%0\n" " blt %1,8b\n" - " br 4b\n" + " br 1b\n" ".previous" : "=m" (__dummy_lock(lock)), "=&r" (regx), "=&r" (regy) , "=&r" (stuck_lock), "=&r" (stuck_reader) diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/sys_jensen.c linux/arch/alpha/kernel/sys_jensen.c --- v2.1.125/linux/arch/alpha/kernel/sys_jensen.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/sys_jensen.c Mon Oct 12 11:40:12 1998 @@ -128,7 +128,7 @@ BUS(jensen), machine_check: jensen_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, - rtc_port: 0x170, rtc_addr: 0, rtc_bcd: 1, + rtc_port: 0x170, nr_irqs: 16, irq_probe_mask: _PROBE_MASK(16), diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/sys_ruffian.c linux/arch/alpha/kernel/sys_ruffian.c --- v2.1.125/linux/arch/alpha/kernel/sys_ruffian.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/sys_ruffian.c Mon Oct 12 11:40:12 1998 @@ -247,8 +247,7 @@ struct alpha_machine_vector ruffian_mv __initmv = { vector_name: "Ruffian", DO_EV5_MMU, - /* RUFFIAN always uses BCD, like a PeeCee. */ - rtc_port: 0x70, rtc_addr: 0x80, rtc_bcd: 1, + DO_DEFAULT_RTC, /* For the moment, do not use BWIO on RUFFIAN. */ IO(PYXIS,pyxis,pyxis), DO_PYXIS_BUS, diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/sys_sx164.c linux/arch/alpha/kernel/sys_sx164.c --- v2.1.125/linux/arch/alpha/kernel/sys_sx164.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/sys_sx164.c Mon Oct 12 11:40:12 1998 @@ -103,7 +103,10 @@ static void sx164_init_irq(void) { - STANDARD_INIT_IRQ_PROLOG; + outb(0, DMA1_RESET_REG); + outb(0, DMA2_RESET_REG); + outb(DMA_MODE_CASCADE, DMA2_MODE_REG); + outb(0, DMA2_MASK_REG); if (alpha_using_srm) { alpha_mv.update_irq_hw = sx164_srm_update_irq_hw; diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c --- v2.1.125/linux/arch/alpha/kernel/time.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/kernel/time.c Tue Oct 20 09:43:21 1998 @@ -62,11 +62,13 @@ time_t last_rtc_update; } state; +unsigned long est_cycle_freq; + static inline __u32 rpcc(void) { __u32 result; - asm volatile ("rpcc %0" : "r="(result)); + asm volatile ("rpcc %0" : "=r"(result)); return result; } @@ -162,7 +164,7 @@ * drivers depend on them being initialized (e.g., joystick driver). */ -/* It is (normally) only counter 1 that presents config problems, so +/* It is (normally) only counter 0 that presents config problems, so provide this support function to do the rest of the job. */ void inline @@ -184,12 +186,20 @@ static inline void rtc_init_pit (void) { + unsigned char control; + /* Setup interval timer if /dev/rtc is being used */ outb(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */ outb(LATCH & 0xff, 0x40); /* LSB */ outb(LATCH >> 8, 0x40); /* MSB */ request_region(0x40, 0x20, "timer"); /* reserve pit */ + /* Turn off RTC interrupts before /dev/rtc is initialized */ + control = CMOS_READ(RTC_CONTROL); + control &= ~(RTC_PIE | RTC_AIE | RTC_UIE); + CMOS_WRITE(control, RTC_CONTROL); + CMOS_READ(RTC_INTR_FLAGS); + init_pit_rest(); } #endif @@ -197,11 +207,25 @@ void generic_init_pit (void) { - int x; - if ((x = (CMOS_READ(RTC_FREQ_SELECT) & 0x3f)) != 0x26) { + unsigned char x; + + /* Reset periodic interrupt frequency. */ + x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f; + if (x != 0x26 && x != 0x19 && x != 0x06) { printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x); CMOS_WRITE(0x26, RTC_FREQ_SELECT); } + + /* Turn on periodic interrupts. */ + x = CMOS_READ(RTC_CONTROL); + if (!(x & RTC_PIE)) { + printk("Turning on RTC interrupts.\n"); + x |= RTC_PIE; + x &= ~(RTC_AIE | RTC_UIE); + CMOS_WRITE(x, RTC_CONTROL); + } + CMOS_READ(RTC_INTR_FLAGS); + request_region(RTC_PORT(0), 0x10, "timer"); /* reserve rtc */ /* Turn off the PIT. */ @@ -223,11 +247,9 @@ void time_init(void) { -#ifdef CONFIG_RTC - unsigned char save_control; -#endif void (*irq_handler)(int, void *, struct pt_regs *); unsigned int year, mon, day, hour, min, sec, cc1, cc2; + unsigned long cycle_freq; /* Initialize the timers. */ init_pit(); @@ -246,16 +268,17 @@ /* If our cycle frequency isn't valid, go another round and give a guess at what it should be. */ - if (hwrpb->cycle_freq == 0) { + cycle_freq = hwrpb->cycle_freq; + if (cycle_freq == 0) { printk("HWRPB cycle frequency bogus. Estimating... "); do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)); do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); cc2 = rpcc(); - hwrpb->cycle_freq = cc2 - cc1; + est_cycle_freq = cycle_freq = cc2 - cc1; cc1 = cc2; - printk("%lu Hz\n", hwrpb->cycle_freq); + printk("%lu Hz\n", cycle_freq); } /* From John Bowman : allow the values @@ -300,18 +323,8 @@ state.last_time = cc1; state.scaled_ticks_per_cycle - = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq; + = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; state.last_rtc_update = 0; - -#ifdef CONFIG_RTC - /* turn off RTC interrupts before /dev/rtc is initialized */ - save_control = CMOS_READ(RTC_CONTROL); - save_control &= ~RTC_PIE; - save_control &= ~RTC_AIE; - save_control &= ~RTC_UIE; - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_READ(RTC_INTR_FLAGS); -#endif /* setup timer */ irq_handler = timer_interrupt; diff -u --recursive --new-file v2.1.125/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c --- v2.1.125/linux/arch/alpha/kernel/traps.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/traps.c Mon Oct 12 11:40:12 1998 @@ -149,8 +149,6 @@ unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs) { - extern int ptrace_cancel_bpt (struct task_struct *who); - lock_kernel(); die_if_kernel("Instruction fault", ®s, type, 0); switch (type) { @@ -558,11 +556,12 @@ #define OP_INT_MASK ( 1L << 0x28 | 1L << 0x2c /* ldl stl */ \ | 1L << 0x29 | 1L << 0x2d /* ldq stq */ \ - | 1L << 0x0c | 1L << 0x0d ) /* ldwu stw */ + | 1L << 0x0c | 1L << 0x0d /* ldwu stw */ \ + | 1L << 0x0a | 1L << 0x0e ) /* ldbu stb */ #define OP_WRITE_MASK ( 1L << 0x26 | 1L << 0x27 /* sts stt */ \ | 1L << 0x2c | 1L << 0x2d /* stl stq */ \ - | 1L << 0xd ) /* stw */ + | 1L << 0x0d | 1L << 0x0e ) /* stw stb */ #define R(x) ((size_t) &((struct pt_regs *)0)->x) diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile --- v2.1.125/linux/arch/alpha/lib/Makefile Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/lib/Makefile Mon Oct 12 11:40:12 1998 @@ -7,7 +7,8 @@ strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \ strchr.o strrchr.o \ copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \ - csum_ipv6_magic.o strcasecmp.o + csum_ipv6_magic.o strcasecmp.o \ + srm_dispatch.o srm_fixup.o srm_puts.o srm_printk.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/srm_dispatch.S linux/arch/alpha/lib/srm_dispatch.S --- v2.1.125/linux/arch/alpha/lib/srm_dispatch.S Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/lib/srm_dispatch.S Mon Oct 12 11:40:12 1998 @@ -0,0 +1,43 @@ +/* + * arch/alpha/lib/srm_dispatch.S + */ + +.globl srm_dispatch +.ent srm_dispatch +srm_dispatch: + .frame $30,30,$26 + subq $30,80,$30 + stq $26,0($30) + stq $8,8($30) + stq $9,16($30) + stq $10,24($30) + stq $11,32($30) + stq $12,40($30) + stq $13,48($30) + stq $14,56($30) + stq $15,64($30) + stq $29,72($30) + .mask 0x2400FF00, -80 + .prologue 0 + + ldq $1,hwrpb + ldq $2,0xc0($1) /* crb offset */ + addq $2,$1,$2 /* crb */ + ldq $27,0($2) /* dispatch procedure value */ + + ldq $2,8($27) /* dispatch call address */ + jsr $26,($2) /* call it (weird VMS call seq) */ + + ldq $26,0($30) + ldq $8,8($30) + ldq $9,16($30) + ldq $10,24($30) + ldq $11,32($30) + ldq $12,40($30) + ldq $13,48($30) + ldq $14,56($30) + ldq $15,64($30) + ldq $29,72($30) + addq $30,80,$30 + ret $31,($26),1 +.end srm_dispatch diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/srm_fixup.S linux/arch/alpha/lib/srm_fixup.S --- v2.1.125/linux/arch/alpha/lib/srm_fixup.S Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/lib/srm_fixup.S Mon Oct 12 11:40:12 1998 @@ -0,0 +1,42 @@ +/* + * arch/alpha/lib/srm_fixup.S + */ + +.globl srm_fixup +.ent srm_fixup +srm_fixup: + .frame $30,30,$26 + subq $30,80,$30 + stq $26,0($30) + stq $8,8($30) + stq $9,16($30) + stq $10,24($30) + stq $11,32($30) + stq $12,40($30) + stq $13,48($30) + stq $14,56($30) + stq $15,64($30) + stq $29,72($30) + .mask 0x2400FF00, -80 + .prologue 0 + + ldq $2,0xc0($17) /* crb offset */ + addq $2,$1,$2 /* crb */ + ldq $27,16($2) /* fixup procedure value */ + + ldq $2,8($27) /* dispatch call address */ + jsr $26,($2) /* call it (weird VMS call seq) */ + + ldq $26,0($30) + ldq $8,8($30) + ldq $9,16($30) + ldq $10,24($30) + ldq $11,32($30) + ldq $12,40($30) + ldq $13,48($30) + ldq $14,56($30) + ldq $15,64($30) + ldq $29,72($30) + addq $30,80,$30 + ret $31,($26),1 +.end srm_fixup diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/srm_printk.c linux/arch/alpha/lib/srm_printk.c --- v2.1.125/linux/arch/alpha/lib/srm_printk.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/lib/srm_printk.c Mon Oct 12 11:40:12 1998 @@ -0,0 +1,21 @@ +/* + * arch/alpha/lib/srm_printk.c + */ + +#include +#include + +long +srm_printk(const char *fmt, ...) +{ + static char buf[1024]; + va_list args; + long i; + + va_start(args, fmt); + i = vsprintf(buf,fmt,args); + va_end(args); + + srm_puts(buf); + return i; +} diff -u --recursive --new-file v2.1.125/linux/arch/alpha/lib/srm_puts.c linux/arch/alpha/lib/srm_puts.c --- v2.1.125/linux/arch/alpha/lib/srm_puts.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/lib/srm_puts.c Mon Oct 12 11:40:12 1998 @@ -0,0 +1,34 @@ +/* + * arch/alpha/lib/srm_puts.c + */ + +#include +#include + +void +srm_puts(const char *str) +{ + /* Expand \n to \r\n as we go. */ + + while (*str) { + long len; + const char *e = str; + + if (*str == '\n') { + if (srm_dispatch(CCB_PUTS, 0, "\r", 1) < 0) + return; + ++e; + } + + e = strchr(e, '\n') ? : strchr(e, '\0'); + len = e - str; + + while (len > 0) { + long written = srm_dispatch(CCB_PUTS, 0, str, len); + if (written < 0) + return; + len -= written & 0xffffffff; + str += written & 0xffffffff; + } + } +} diff -u --recursive --new-file v2.1.125/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c --- v2.1.125/linux/arch/alpha/mm/init.c Wed Sep 9 14:51:04 1998 +++ linux/arch/alpha/mm/init.c Mon Oct 12 11:40:12 1998 @@ -30,7 +30,7 @@ extern void die_if_kernel(char *,struct pt_regs *,long); extern void show_net_buffers(void); -struct thread_struct * original_pcb_ptr; +struct thread_struct original_pcb; #ifndef __SMP__ struct pgtable_cache_struct quicklists; @@ -193,47 +193,66 @@ unsigned long newptbr; struct memclust_struct * cluster; struct memdesc_struct * memdesc; + struct thread_struct *original_pcb_ptr; /* initialize mem_map[] */ start_mem = free_area_init(start_mem, end_mem); /* find free clusters, update mem_map[] accordingly */ memdesc = (struct memdesc_struct *) - (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB); + (hwrpb->mddt_offset + (unsigned long) hwrpb); cluster = memdesc->cluster; for (i = memdesc->numclusters ; i > 0; i--, cluster++) { unsigned long pfn, nr; - if (cluster->usage & 1) + + /* Bit 0 is console/PALcode reserved. Bit 1 is + non-volatile memory -- we might want to mark + this for later */ + if (cluster->usage & 3) continue; pfn = cluster->start_pfn; nr = cluster->numpages; - /* non-volatile memory. We might want to mark this for later */ - if (cluster->usage & 2) - continue; - while (nr--) clear_bit(PG_reserved, &mem_map[pfn++].flags); } - /* unmap the console stuff: we don't need it, and we don't want it */ - /* Also set up the real kernel PCB while we're at it.. */ + /* Initialize the kernel's page tables. Linux puts the vptb in + the last slot of the L1 page table. */ memset((void *) ZERO_PAGE, 0, PAGE_SIZE); memset(swapper_pg_dir, 0, PAGE_SIZE); newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT; pgd_val(swapper_pg_dir[1023]) = (newptbr << 32) | pgprot_val(PAGE_KERNEL); + + /* Set the vptb. This is often done by the bootloader, but + shouldn't be required. */ + if (hwrpb->vptb != 0xfffffffe00000000) { + wrvptptr(0xfffffffe00000000); + hwrpb->vptb = 0xfffffffe00000000; + hwrpb_update_checksum(hwrpb); + } + + /* Also set up the real kernel PCB while we're at it. */ init_task.tss.ptbr = newptbr; init_task.tss.pal_flags = 1; /* set FEN, clear everything else */ init_task.tss.flags = 0; - original_pcb_ptr = - phys_to_virt((unsigned long)load_PCB(&init_task.tss)); -#if 0 -printk("OKSP 0x%lx OPTBR 0x%lx\n", - original_pcb_ptr->ksp, original_pcb_ptr->ptbr); -#endif - + original_pcb_ptr = load_PCB(&init_task.tss); tbia(); + + /* Save off the contents of the original PCB so that we can + restore the original console's page tables for a clean reboot. + + Note that the PCB is supposed to be a physical address, but + since KSEG values also happen to work, folks get confused. + Check this here. */ + + if ((unsigned long)original_pcb_ptr < PAGE_OFFSET) { + original_pcb_ptr = (struct thread_struct *) + phys_to_virt((unsigned long) original_pcb_ptr); + } + original_pcb = *original_pcb_ptr; + return start_mem; } @@ -250,18 +269,29 @@ current->tss.ptbr = init_task.tss.ptbr; current->tss.pal_flags = 1; current->tss.flags = 0; - -#if 0 -printk("paging_init_secondary: KSP 0x%lx PTBR 0x%lx\n", - current->tss.ksp, current->tss.ptbr); -#endif - load_PCB(¤t->tss); tbia(); return; } #endif /* __SMP__ */ + +#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM) +void +srm_paging_stop (void) +{ + /* Move the vptb back to where the SRM console expects it. */ + swapper_pg_dir[1] = swapper_pg_dir[1023]; + tbia(); + wrvptptr(0x200000000); + hwrpb->vptb = 0x200000000; + hwrpb_update_checksum(hwrpb); + + /* Reload the page tables that the console had in use. */ + load_PCB(&original_pcb); + tbia(); +} +#endif #if DEBUG_POISON static void diff -u --recursive --new-file v2.1.125/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.1.125/linux/arch/i386/defconfig Fri Oct 9 13:27:05 1998 +++ linux/arch/i386/defconfig Fri Oct 23 10:13:39 1998 @@ -266,6 +266,7 @@ CONFIG_PROC_FS=y CONFIG_NFS_FS=y CONFIG_NFSD=y +# CONFIG_NFSD_SUN is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_CODA_FS is not set diff -u --recursive --new-file v2.1.125/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c --- v2.1.125/linux/arch/i386/kernel/bios32.c Mon Sep 28 10:51:33 1998 +++ linux/arch/i386/kernel/bios32.c Fri Oct 23 08:25:05 1998 @@ -346,7 +346,7 @@ * attempt to make use of direct access hints provided by the PCI BIOS). * * This should be close to trivial, but it isn't, because there are buggy - * chipsets (yes, you guessed it, by Intel) that have no class ID. + * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. */ __initfunc(int pci_sanity_check(struct pci_access *a)) { @@ -356,9 +356,9 @@ return 1; for(dfn=0; dfn < 0x100; dfn++) if ((!a->read_config_word(0, dfn, PCI_CLASS_DEVICE, &x) && - x == PCI_CLASS_BRIDGE_HOST) || + (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) || (!a->read_config_word(0, dfn, PCI_VENDOR_ID, &x) && - x == PCI_VENDOR_ID_INTEL)) + (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ))) return 1; DBG("PCI: Sanity check failed\n"); return 0; @@ -1063,6 +1063,16 @@ if (pin) { pin--; /* interrupt pins are numbered starting from 1 */ irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); + if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ + struct pci_dev * bridge = dev->bus->self; + + pin = (pin + PCI_SLOT(dev->devfn)) % 4; + irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, + PCI_SLOT(bridge->devfn), pin); + if (irq >= 0) + printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", + bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq); + } if (irq >= 0) { printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n", dev->bus->number, PCI_SLOT(dev->devfn), pin, irq); diff -u --recursive --new-file v2.1.125/linux/arch/i386/kernel/mca.c linux/arch/i386/kernel/mca.c --- v2.1.125/linux/arch/i386/kernel/mca.c Wed Aug 26 11:37:33 1998 +++ linux/arch/i386/kernel/mca.c Sat Oct 17 15:33:45 1998 @@ -3,11 +3,29 @@ * Written by Martin Kolinek, February 1996 * * Changes: - * July 28, 1996: fixed up integrated SCSI detection. Chris Beauregard - * August 3rd, 1996: made mca_info local, made integrated registers - * accessible through standard function calls, added name field, - * more sanity checking. Chris Beauregard - * August 9, 1996: Rewrote /proc/mca. cpbeaure + * + * Chris Beauregard July 28th, 1996 + * - Fixed up integrated SCSI detection + * + * Chris Beauregard August 3rd, 1996 + * - Made mca_info local + * - Made integrated registers accessible through standard function calls + * - Added name field + * - More sanity checking + * + * Chris Beauregard August 9th, 1996 + * - Rewrote /proc/mca + * + * Chris Beauregard January 7th, 1997 + * - Added basic NMI-processing + * - Added more information to mca_info structure + * + * David Weinehall October 12th, 1998 + * - Made a lot of cleaning up in the source + * - Added use of save_flags / restore_flags + * - Added the 'driver_loaded' flag in MCA_adapter + * - Added an alternative implemention of ZP Gu's mca_find_unused_adapter + * */ #include @@ -29,19 +47,38 @@ * eight POS registers. Then the machine may have integrated video and * SCSI subsystems, which also have eight POS registers. * Other miscellaneous information follows. -*/ + */ + +typedef enum { + MCA_ADAPTER_NORMAL = 0, + MCA_ADAPTER_NONE = 1, + MCA_ADAPTER_DISABLED = 2, + MCA_ADAPTER_ERROR = 3 +} MCA_AdapterStatus; + struct MCA_adapter { - unsigned char pos[8]; /* POS registers */ - char name[32]; /* name of the device - provided by driver */ - char procname[8]; /* name of /proc/mca file */ - MCA_ProcFn procfn; /* /proc info callback */ - void* dev; /* device/context info for callback */ + MCA_AdapterStatus status; /* is there a valid adapter? */ + int id; /* adapter id value */ + unsigned char pos[8]; /* POS registers */ + int driver_loaded; /* is there a driver installed? */ + /* 0 - No, 1 - Yes */ + char name[48]; /* adapter-name provided by driver */ + char procname[8]; /* name of /proc/mca file */ + MCA_ProcFn procfn; /* /proc info callback */ + void* dev; /* device/context info for callback */ }; struct MCA_info { - /* one for each of the 8 possible slots, plus one for integrated SCSI - and one for integrated video. */ +/* one for each of the 8 possible slots, plus one for integrated SCSI + and one for integrated video. */ + struct MCA_adapter slot[MCA_NUMADAPTERS]; + +/* two potential addresses for integrated SCSI adapter - this will + * track which one we think it is + */ + + unsigned char which_scsi; }; /* The mca_info structure pointer. If MCA bus is present, the function @@ -49,70 +86,145 @@ * adapters into setup mode, allocates and fills an MCA_info structure, * and points this pointer to the structure. Otherwise the pointer * is set to zero. -*/ + */ + static struct MCA_info* mca_info = 0; -/*MCA registers*/ -#define MCA_MOTHERBOARD_SETUP_REG 0x94 -#define MCA_ADAPTER_SETUP_REG 0x96 -#define MCA_POS_REG(n) (0x100+(n)) +/* MCA registers */ + +#define MCA_MOTHERBOARD_SETUP_REG 0x94 +#define MCA_ADAPTER_SETUP_REG 0x96 +#define MCA_POS_REG(n) (0x100+(n)) #define MCA_ENABLED 0x01 /* POS 2, set if adapter enabled */ /*--------------------------------------------------------------------*/ #ifdef CONFIG_PROC_FS + static void mca_do_proc_init( void ); static int mca_default_procfn( char* buf, int slot ); static ssize_t proc_mca_read( struct file*, char*, size_t, loff_t *); + static struct file_operations proc_mca_operations = { - NULL, proc_mca_read, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, /* array_lseek */ + proc_mca_read, /* array_read */ + NULL, /* array_write */ + NULL, /* array_readdir */ + NULL, /* array_poll */ + NULL, /* array_ioctl */ + NULL, /* mmap */ + NULL, /* no special open code */ + NULL, /* flush */ + NULL, /* no special release code */ + NULL /* can't fsync */ }; + static struct inode_operations proc_mca_inode_operations = { - &proc_mca_operations, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + &proc_mca_operations, /* default base directory file-ops */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL /* permission */ }; #endif /*--------------------------------------------------------------------*/ +/* Build the status info for the adapter */ + +static void mca_configure_adapter_status( int slot ) { + mca_info->slot[slot].status = MCA_ADAPTER_NONE; + + mca_info->slot[slot].id = mca_info->slot[slot].pos[0] + + (mca_info->slot[slot].pos[1] << 8); + + if( !mca_info->slot[slot].id ) { + + /* id = 0x0000 usually indicates hardware failure, + * however, ZP Gu (zpg@castle.net> reports that his 9556 + * has 0x0000 as id and everything still works. + */ + + mca_info->slot[slot].status = MCA_ADAPTER_ERROR; + + return; + } else if( mca_info->slot[slot].id != 0xffff ) { + + /* 0xffff usually indicates that there's no adapter, + * however, some integrated adapters may have 0xffff as + * their id and still be valid. Examples are on-board + * VGA of the 55sx, the integrated SCSI of the 56 & 57, + * and possibly also the 95 ULTIMEDIA. + */ + + mca_info->slot[slot].status = MCA_ADAPTER_NORMAL; + } + + if( (mca_info->slot[slot].id == 0xffff || + mca_info->slot[slot].id == 0x0000) && slot >= MCA_MAX_SLOT_NR ) { + int j; + + for( j = 2; j < 8; j++ ) { + if( mca_info->slot[slot].pos[j] != 0xff ) { + mca_info->slot[slot].status = MCA_ADAPTER_NORMAL; + break; + } + } + } + + if( !(mca_info->slot[slot].pos[2] & MCA_ENABLED) ) { + + /* enabled bit is in pos 2 */ + + mca_info->slot[slot].status = MCA_ADAPTER_DISABLED; + } +} /* mca_configure_adapter_status */ + +/*--------------------------------------------------------------------*/ + __initfunc(void mca_init(void)) { unsigned int i, j; - int foundscsi = 0; + unsigned long flags; /* WARNING: Be careful when making changes here. Putting an adapter * and the motherboard simultaneously into setup mode may result in * damage to chips (according to The Indispensible PC Hardware Book * by Hans-Peter Messmer). Also, we disable system interrupts (so * that we are not disturbed in the middle of this). - */ - - /* - * Make sure the MCA bus is present */ + + /* Make sure the MCA bus is present */ if (!MCA_bus) return; + printk( "Micro Channel bus detected.\n" ); + save_flags( flags ); cli(); - /* - * Allocate MCA_info structure (at address divisible by 8) - */ + /* Allocate MCA_info structure (at address divisible by 8) */ mca_info = kmalloc(sizeof(struct MCA_info), GFP_ATOMIC); - /* - * Make sure adapter setup is off - */ + /* Make sure adapter setup is off */ outb_p(0, MCA_ADAPTER_SETUP_REG); - /* - * Put motherboard into video setup mode, read integrated video + /* Put motherboard into video setup mode, read integrated video * pos registers, and turn motherboard setup off. */ @@ -121,6 +233,7 @@ for (j=0; j<8; j++) { mca_info->slot[MCA_INTEGVIDEO].pos[j] = inb_p(MCA_POS_REG(j)); } + mca_configure_adapter_status(MCA_INTEGVIDEO); /* Put motherboard into scsi setup mode, read integrated scsi * pos registers, and turn motherboard setup off. @@ -132,51 +245,57 @@ * a good bet that only one could be valid at a time. This could * screw up though if one is used for something else on the other * machine. - */ + */ outb_p(0xf7, MCA_MOTHERBOARD_SETUP_REG); mca_info->slot[MCA_INTEGSCSI].name[0] = 0; for (j=0; j<8; j++) { if( (mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j))) != 0xff ) { - /* 0xff all across means no device. 0x00 means something's - broken, but a device is probably there. However, if you get - 0x00 from a motherboard register it won't matter what we - find. For the record, on the 57SLC, the integrated SCSI - adapter has 0xffff for the adapter ID, but nonzero for - other registers. */ - foundscsi = 1; + /* 0xff all across means no device. 0x00 means something's + * broken, but a device is probably there. However, if you get + * 0x00 from a motherboard register it won't matter what we + * find. For the record, on the 57SLC, the integrated SCSI + * adapter has 0xffff for the adapter ID, but nonzero for + * other registers. + */ + + mca_info->which_scsi = 0xf7; } } - if( !foundscsi ) - { - /* - * Didn't find it at 0xfd, try somewhere else... - */ + if( !mca_info->which_scsi ) { + + /* Didn't find it at 0xf7, try somewhere else... */ + mca_info->which_scsi = 0xfd; + outb_p(0xfd, MCA_MOTHERBOARD_SETUP_REG); for (j=0; j<8; j++) mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j)); } - + mca_configure_adapter_status(MCA_INTEGSCSI); + /* turn off motherboard setup */ + outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); - /* - * Now loop over MCA slots: put each adapter into setup mode, and - * read its pos registers. Then put adapter setup off. + /* Now loop over MCA slots: put each adapter into setup mode, and + * read its pos registers. Then put adapter setup off. */ for (i=0; islot[i].pos[j]=inb_p(MCA_POS_REG(j)); + for (j=0; j<8; j++) { + mca_info->slot[i].pos[j]=inb_p(MCA_POS_REG(j)); + } mca_info->slot[i].name[0] = 0; + mca_info->slot[i].driver_loaded = 0; + mca_configure_adapter_status(i); } outb_p(0, MCA_ADAPTER_SETUP_REG); - /* - * Enable interrupts and return memory start - */ - sti(); + /* Enable interrupts and return memory start */ + + restore_flags( flags ); request_region(0x60,0x01,"system control port B (MCA)"); request_region(0x90,0x01,"arbitration (MCA)"); @@ -193,29 +312,89 @@ /*--------------------------------------------------------------------*/ -int mca_find_adapter( int id, int start ) +static void mca_handle_nmi_slot( int slot, int check_flag ) { - int slot_id = 0; - unsigned char status = 0; + if( slot < MCA_MAX_SLOT_NR ) { + printk( "NMI: caused by MCA adapter in slot %d (%s)\n", slot+1, + mca_info->slot[slot].name ); + } else if( slot == MCA_INTEGSCSI ) { + printk( "NMI: caused by MCA integrated SCSI adapter (%s)\n", + mca_info->slot[slot].name ); + } else if( slot == MCA_INTEGVIDEO ) { + printk( "NMI: caused by MCA integrated video adapter (%s)\n", + mca_info->slot[slot].name ); + } + + /* more info available in pos 6 and 7? */ + + if( check_flag ) { + unsigned char pos6, pos7; + + pos6 = mca_read_pos( slot, 6 ); + pos7 = mca_read_pos( slot, 7 ); + + printk( "NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7 ); + } + +} /* mca_handle_nmi_slot */ + +/*--------------------------------------------------------------------*/ + +void mca_handle_nmi( void ) +{ + + int i; + unsigned char pos5; + + /* First try - scan the various adapters and see if a specific + * adapter was responsible for the error + */ + + for( i = 0; i < MCA_NUMADAPTERS; i += 1 ) { + + /* bit 7 of POS 5 is reset when this adapter has a hardware + * error. bit 7 it reset if there's error information + * available in pos 6 and 7. */ + + pos5 = mca_read_pos( i, 5 ); + + if( !(pos5 & 0x80) ) { + mca_handle_nmi_slot( i, !(pos5 & 0x40) ); + return; + } + } + + /* if I recall correctly, there's a whole bunch of other things that + * we can do to check for NMI problems, but that's all I know about + * at the moment. + */ + + printk( "NMI generated from unknown source!\n" ); +} /* mca_handle_nmi */ +/*--------------------------------------------------------------------*/ + +int mca_find_adapter( int id, int start ) +{ if( mca_info == 0 || id == 0 || id == 0xffff ) { return MCA_NOTFOUND; } for( ; start >= 0 && start < MCA_NUMADAPTERS; start += 1 ) { - slot_id = (mca_info->slot[start].pos[1] << 8) - + mca_info->slot[start].pos[0]; - status = mca_info->slot[start].pos[2]; /* not sure about this. There's no point in returning - adapters that aren't enabled, since they can't actually - be used. However, they might be needed for statistical - purposes or something... */ - if( !(status & MCA_ENABLED) ) { + * adapters that aren't enabled, since they can't actually + * be used. However, they might be needed for statistical + * purposes or something... But if that is the case, the + * user is free to write a routine that manually iterates + * through the adapters. + */ + + if( mca_info->slot[start].status == MCA_ADAPTER_DISABLED ) { continue; } - if( id == slot_id ) { + if( id == mca_info->slot[start].id ) { return start; } } @@ -225,6 +404,37 @@ /*--------------------------------------------------------------------*/ +int mca_find_unused_adapter( int id, int start ) +{ + if( mca_info == 0 || id == 0 || id == 0xffff ) { + return MCA_NOTFOUND; + } + + for( ; start >= 0 && start < MCA_NUMADAPTERS; start += 1 ) { + + /* not sure about this. There's no point in returning + * adapters that aren't enabled, since they can't actually + * be used. However, they might be needed for statistical + * purposes or something... But if that is the case, the + * user is free to write a routine that manually iterates + * through the adapters. + */ + + if( mca_info->slot[start].status == MCA_ADAPTER_DISABLED || + mca_info->slot[start].driver_loaded ) { + continue; + } + + if( id == mca_info->slot[start].id ) { + return start; + } + } + + return MCA_NOTFOUND; +} /* mca_find_unused_adapter() */ + +/*--------------------------------------------------------------------*/ + unsigned char mca_read_stored_pos( int slot, int reg ) { if( slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == 0 ) return 0; @@ -237,57 +447,97 @@ unsigned char mca_read_pos( int slot, int reg ) { unsigned int byte = 0; + unsigned long flags; - if( slot < 0 || slot >= MCA_MAX_SLOT_NR || mca_info == 0 ) return 0; + if( slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == 0 ) return 0; if( reg < 0 || reg >= 8 ) return 0; + save_flags( flags ); cli(); - /*make sure motherboard setup is off*/ + /* make sure motherboard setup is off */ + outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); /* read in the appropriate register */ - outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG); - byte = inb_p(MCA_POS_REG(reg)); - outb_p(0, MCA_ADAPTER_SETUP_REG); - sti(); + if( slot == MCA_INTEGSCSI && mca_info->which_scsi ) { + + /* disable adapter setup, enable motherboard setup */ + + outb_p(0, MCA_ADAPTER_SETUP_REG); + outb_p(mca_info->which_scsi, MCA_MOTHERBOARD_SETUP_REG); + + byte = inb_p(MCA_POS_REG(reg)); + outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); + } else if( slot == MCA_INTEGVIDEO ) { + + /* disable adapter setup, enable motherboard setup */ + + outb_p(0, MCA_ADAPTER_SETUP_REG); + outb_p(0xdf, MCA_MOTHERBOARD_SETUP_REG); + + byte = inb_p(MCA_POS_REG(reg)); + outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); + } else if( slot < MCA_MAX_SLOT_NR ) { + + /* make sure motherboard setup is off */ + + outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); + + /* read the appropriate register */ + + outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG); + byte = inb_p(MCA_POS_REG(reg)); + outb_p(0, MCA_ADAPTER_SETUP_REG); + } /* make sure the stored values are consistent, while we're here */ + mca_info->slot[slot].pos[reg] = byte; + restore_flags( flags ); + return byte; } /* mca_read_pos() */ /*--------------------------------------------------------------------*/ + /* Note that this a technically a Bad Thing, as IBM tech stuff says - you should only set POS values through their utilities. - However, some devices such as the 3c523 recommend that you write - back some data to make sure the configuration is consistent. - I'd say that IBM is right, but I like my drivers to work. - This function can't do checks to see if multiple devices end up - with the same resources, so you might see magic smoke if someone - screws up. */ + * you should only set POS values through their utilities. + * However, some devices such as the 3c523 recommend that you write + * back some data to make sure the configuration is consistent. + * I'd say that IBM is right, but I like my drivers to work. + * This function can't do checks to see if multiple devices end up + * with the same resources, so you might see magic smoke if someone + * screws up. + */ void mca_write_pos( int slot, int reg, unsigned char byte ) { + unsigned long flags; + if( slot < 0 || slot >= MCA_MAX_SLOT_NR ) return; if( reg < 0 || reg >= 8 ) return; if (mca_info == 0 ) return; + save_flags( flags ); cli(); - /*make sure motherboard setup is off*/ + /* make sure motherboard setup is off */ + outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); /* read in the appropriate register */ + outb_p(0x8|(slot&0xf), MCA_ADAPTER_SETUP_REG); outb_p( byte, MCA_POS_REG(reg) ); outb_p(0, MCA_ADAPTER_SETUP_REG); - sti(); + restore_flags( flags ); /* update the global register list, while we have the byte */ + mca_info->slot[slot].pos[reg] = byte; } /* mca_write_pos() */ @@ -298,8 +548,14 @@ if( mca_info == 0 ) return; if( slot >= 0 && slot < MCA_NUMADAPTERS ) { - strncpy( mca_info->slot[slot].name, name, - sizeof(mca_info->slot[slot].name) ); + if( name != NULL ) { + strncpy( mca_info->slot[slot].name, name, + sizeof(mca_info->slot[slot].name)-1 ); + mca_info->slot[slot].name[ + sizeof(mca_info->slot[slot].name)-1] = 0; + } else { + mca_info->slot[slot].name[0] = 0; + } } } @@ -313,6 +569,23 @@ } } +int mca_is_adapter_used( int slot ) +{ + return mca_info->slot[slot].driver_loaded; +} + +int mca_mark_as_used( int slot ) +{ + if(mca_info->slot[slot].driver_loaded) return 1; + mca_info->slot[slot].driver_loaded = 1; + return 0; +} + +void mca_mark_as_unused( int slot ) +{ + mca_info->slot[slot].driver_loaded = 0; +} + char *mca_get_adapter_name( int slot ) { if( mca_info == 0 ) return 0; @@ -328,19 +601,9 @@ { if( mca_info == 0 ) return 0; - if( slot >= MCA_MAX_SLOT_NR ) { - /* some integrated adapters have 0xffff for an ID, but - are still there. VGA, for example. */ - int i; - for( i = 0; i < 8; i ++ ) { - if( mca_info->slot[slot].pos[i] != 0xff ) { - return 1; - } - } - return 0; - } else if( slot >= 0 && slot < MCA_NUMADAPTERS ) { - return (mca_info->slot[slot].pos[0] != 0xff || - mca_info->slot[slot].pos[1] != 0xff); + if( slot >= 0 && slot < MCA_NUMADAPTERS ) { + return (( mca_info->slot[slot].status == MCA_ADAPTER_NORMAL ) + || (mca_info->slot[slot].status == MCA_ADAPTER_DISABLED ) ); } return 0; @@ -351,7 +614,7 @@ if( mca_info == 0 ) return 0; if( slot >= 0 && slot < MCA_NUMADAPTERS ) { - return (mca_info->slot[slot].pos[2] & MCA_ENABLED); + return (mca_info->slot[slot].status == MCA_ADAPTER_NORMAL); } return 0; @@ -367,9 +630,8 @@ if( MCA_bus && mca_info != 0 ) { - /* - * Format pos registers of eight MCA slots - */ + /* Format pos registers of eight MCA slots */ + for (i=0; islot[i].name ); } - /* - * Format pos registers of integrated video subsystem - */ + /* Format pos registers of integrated video subsystem */ - len += sprintf(buf+len, "Video: "); + len += sprintf(buf+len, "Video : "); for (j=0; j<8; j++) len += sprintf(buf+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]); len += sprintf( buf+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name ); - /* - * Format pos registers of integrated SCSI subsystem - */ + /* Format pos registers of integrated SCSI subsystem */ - len += sprintf(buf+len, "SCSI: "); + len += sprintf(buf+len, "SCSI : "); for (j=0; j<8; j++) len += sprintf(buf+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]); len += sprintf( buf+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name ); } else { - /* - * Leave it empty if MCA not detected - * this should never happen + /* Leave it empty if MCA not detected - this should *never* + * happen! */ } @@ -409,12 +666,13 @@ /*--------------------------------------------------------------------*/ + __initfunc(void mca_do_proc_init( void )) { int i = 0; struct proc_dir_entry* node = 0; - if( mca_info == 0 ) return; /* never happens */ + if( mca_info == 0 ) return; /* should never happen */ proc_register( &proc_mca, &(struct proc_dir_entry) { PROC_MCA_REGISTERS, 3, "pos", S_IFREG|S_IRUGO, @@ -424,7 +682,8 @@ PROC_MCA_MACHINE, 7, "machine", S_IFREG|S_IRUGO, 1, 0, 0, 0, &proc_mca_inode_operations,} ); - /* initialize /proc entries for existing adapters */ + /* initialize /proc/mca entries for existing adapters */ + for( i = 0; i < MCA_NUMADAPTERS; i += 1 ) { mca_info->slot[i].procfn = 0; mca_info->slot[i].dev = 0; @@ -460,6 +719,7 @@ int len = 0, i; /* this really shouldn't happen... */ + if( mca_info == 0 ) { *buf = 0; return 0; @@ -475,7 +735,9 @@ len += sprintf( buf+len, "Integrated Video Adapter\n" ); } if( mca_info->slot[slot].name[0] ) { + /* drivers might register a name without /proc handler... */ + len += sprintf( buf+len, "Adapter Name: %s\n", mca_info->slot[slot].name ); } else { @@ -485,6 +747,8 @@ mca_info->slot[slot].pos[1], mca_info->slot[slot].pos[0] ); len += sprintf( buf+len, "Enabled: %s\nPOS: ", mca_isenabled(slot) ? "Yes" : "No" ); + len += sprintf( buf+len, "Driver Installed: %s\n", + mca_is_adapter_used(slot) ? "Yes" : "No" ); for (i=0; i<8; i++) { len += sprintf(buf+len, "%02x ", mca_info->slot[slot].pos[i]); } @@ -505,13 +769,6 @@ return len; } -/* -static int mca_not_implemented( char* buf ) -{ - return sprintf( buf, "Sorry, not implemented yet...\n" ); -} -*/ - static int mca_fill( char* page, int pid, int type, char** start, loff_t *offset, int length) { @@ -540,9 +797,11 @@ /* if we made it here, we better have a valid slot */ /* get the standard info */ + len = mca_default_procfn( page, slot ); /* do any device-specific processing, if there is any */ + if( mca_info->slot[slot].procfn ) { len += mca_info->slot[slot].procfn( page+len, slot, mca_info->slot[slot].dev ); @@ -551,9 +810,7 @@ return len; } /* mca_fill() */ -/* - * Blatantly stolen from fs/proc/array.c, and thus is probably overkill - */ +/* Blatantly stolen from fs/proc/array.c, and thus is probably overkill */ #define PROC_BLOCK_SIZE (3*1024) @@ -587,11 +844,13 @@ } if (start != 0) { /* We have had block-adjusting processing! */ + copy_to_user(buf, start, length); *ppos += length; count = length; } else { /* Static 4kB (or whatever) block capacity */ + if (*ppos >= length) { free_page(page); return 0; diff -u --recursive --new-file v2.1.125/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v2.1.125/linux/arch/i386/kernel/setup.c Fri Oct 9 13:27:05 1998 +++ linux/arch/i386/kernel/setup.c Wed Oct 14 11:39:25 1998 @@ -431,9 +431,9 @@ "486 SX/2", NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL, NULL, NULL }}, { X86_VENDOR_INTEL, 5, - { "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75+", + { "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75 - 200", "OverDrive PODP5V83", "Pentium MMX", NULL, NULL, - "Mobile Pentium 75+", "Mobile Pentium MMX", NULL, NULL, NULL, + "Mobile Pentium 75 - 200", "Mobile Pentium MMX", NULL, NULL, NULL, NULL, NULL, NULL, NULL }}, { X86_VENDOR_INTEL, 6, { "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)", diff -u --recursive --new-file v2.1.125/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- v2.1.125/linux/arch/i386/kernel/time.c Thu Jul 16 18:09:23 1998 +++ linux/arch/i386/kernel/time.c Fri Oct 9 12:16:19 1998 @@ -12,7 +12,29 @@ * precision CMOS clock update * 1996-05-03 Ingo Molnar * fixed time warps in do_[slow|fast]_gettimeoffset() + * 1998-09-05 (Various) + * More robust do_fast_gettimeoffset() algorithm implemented + * (works with APM, Cyrix 6x86MX and Centaur C6), + * monotonic gettimeofday() with fast_get_timeoffset(), + * drift-proof precision TSC calibration on boot + * (C. Scott Ananian , Andrew D. + * Balsa , Philip Gladstone ; + * ported from 2.0.35 Jumbo-9 by Michael Krause ). */ + +/* What about the "updated NTP code" stuff in 2.0 time.c? It's not in + * 2.1, perhaps it should be ported, too. + * + * What about the BUGGY_NEPTUN_TIMER stuff in do_slow_gettimeoffset()? + * Whatever it fixes, is it also fixed in the new code from the Jumbo + * patch, so that that code can be used instead? + * + * The CPU Hz should probably be displayed in check_bugs() together + * with the CPU vendor and type. Perhaps even only in MHz, though that + * takes away some of the fun of the new code :) + * + * - Michael Krause */ + #include #include #include @@ -41,100 +63,51 @@ #include "irq.h" extern int setup_x86_irq(int, struct irqaction *); -extern volatile unsigned long lost_ticks; -/* change this if you have some constant time drift */ -#define USECS_PER_JIFFY (1000020/HZ) +unsigned long cpu_hz; /* Detected as we calibrate the TSC */ + +/* Number of usecs that the last interrupt was delayed */ +static int delay_at_last_interrupt; + +static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ -#ifndef CONFIG_APM /* cycle counter may be unreliable */ -/* Cycle counter value at the previous timer interrupt.. */ -static struct { - unsigned long low; - unsigned long high; -} init_timer_cc, last_timer_cc; +/* Cached *multiplier* to convert TSC counts to microseconds. + * (see the equation below). + * Equal to 2^32 * (1 / (clocks per usec) ). + * Initialized in time_init. + */ +static unsigned long fast_gettimeoffset_quotient=0; static unsigned long do_fast_gettimeoffset(void) { register unsigned long eax asm("ax"); register unsigned long edx asm("dx"); - unsigned long tmp, quotient, low_timer; - - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies=0; - - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static unsigned long cached_quotient=0; - - tmp = jiffies; - - quotient = cached_quotient; - low_timer = last_timer_cc.low; - if (last_jiffies != tmp) { - last_jiffies = tmp; - - /* Get last timer tick in absolute kernel time */ - eax = low_timer; - edx = last_timer_cc.high; - __asm__("subl "SYMBOL_NAME_STR(init_timer_cc)",%0\n\t" - "sbbl "SYMBOL_NAME_STR(init_timer_cc)"+4,%1" - :"=a" (eax), "=d" (edx) - :"0" (eax), "1" (edx)); - - /* - * Divide the 64-bit time with the 32-bit jiffy counter, - * getting the quotient in clocks. - * - * Giving quotient = "1/(average internal clocks per usec)*2^32" - * we do this '1/...' trick to get the 'mull' into the critical - * path. 'mull' is much faster than divl (10 vs. 41 clocks) - */ - __asm__("divl %2" - :"=a" (eax), "=d" (edx) - :"r" (tmp), - "0" (eax), "1" (edx)); - - edx = USECS_PER_JIFFY; - tmp = eax; - eax = 0; - - __asm__("divl %2" - :"=a" (eax), "=d" (edx) - :"r" (tmp), - "0" (eax), "1" (edx)); - cached_quotient = eax; - quotient = eax; - } - - /* Read the time counter */ - __asm__("rdtsc" : "=a" (eax), "=d" (edx)); + /* Read the Time Stamp Counter */ + __asm__("rdtsc" + :"=a" (eax), "=d" (edx)); /* .. relative to previous jiffy (32 bits is enough) */ edx = 0; - eax -= low_timer; + eax -= last_tsc_low; /* tsc_low delta */ /* - * Time offset = (USECS_PER_JIFFY * time_low) * quotient. - */ + * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient. + * = (tsc_low delta) / (clocks_per_usec) + * = (tsc_low delta) / (clocks_per_jiffy / usecs_per_jiffy) + * + * Using a mull instead of a divl saves up to 31 clock cycles + * in the critical path. + */ __asm__("mull %2" :"=a" (eax), "=d" (edx) - :"r" (quotient), + :"r" (fast_gettimeoffset_quotient), "0" (eax), "1" (edx)); - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (edx >= USECS_PER_JIFFY) - edx = USECS_PER_JIFFY-1; - - return edx; + /* our adjusted time offset in microseconds */ + return edx + delay_at_last_interrupt; } -#endif /* This function must be called with interrupts disabled * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs @@ -249,20 +222,11 @@ return count; } -#ifndef CONFIG_APM -/* - * this is only used if we have fast gettimeoffset: - */ -static void do_x86_get_fast_time(struct timeval * tv) -{ - do_gettimeofday(tv); -} -#endif - static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset; /* - * This version of gettimeofday has near microsecond resolution. + * This version of gettimeofday has microsecond resolution + * and better than microsecond precision on fast x86 machines with TSC. */ void do_gettimeofday(struct timeval *tv) { @@ -272,20 +236,11 @@ cli(); *tv = xtime; tv->tv_usec += do_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. lost_ticks is - * nonzero if the timer bottom half hasnt executed yet. - */ - if (lost_ticks) - tv->tv_usec += USECS_PER_JIFFY; - - restore_flags(flags); - if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } + restore_flags(flags); } void do_settimeofday(struct timeval *tv) @@ -311,13 +266,15 @@ sti(); } - /* * In order to set the CMOS clock precisely, set_rtc_mmss has to be * called 500 ms after the second nowtime has started, because when * nowtime is written into the registers of the CMOS clock, it will * jump to the next second precisely 500 ms later. Check the Motorola * MC146818A or Dallas DS12887 data sheet for details. + * + * BUG: This routine does not handle hour overflow properly; it just + * sets the minutes. Usually you'll only notice that after reboot! */ static int set_rtc_mmss(unsigned long nowtime) { @@ -354,8 +311,12 @@ } CMOS_WRITE(real_seconds,RTC_SECONDS); CMOS_WRITE(real_minutes,RTC_MINUTES); - } else + } else { + printk(KERN_WARNING + "set_rtc_mmss: can't update from %d to %d\n", + cmos_minutes, real_minutes); retval = -1; + } /* The following flags have to be released exactly in this order, * otherwise the DS12887 (popular MC146818A clone with integrated @@ -431,21 +392,37 @@ #endif } -#ifndef CONFIG_APM /* cycle counter may be unreliable */ /* * This is the same as the above, except we _also_ save the current - * cycle counter value at the time of the timer interrupt, so that + * Time Stamp Counter value at the time of the timer interrupt, so that * we later on can estimate the time of day more exactly. */ static void pentium_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + int count, flags; + + /* It is important that these two operations happen almost at the + * same time. We do the RDTSC stuff first, since it's faster. To + * avoid any inconsistencies, we disable interrupts locally. + */ + + __save_flags(flags); + __cli(); /* read Pentium cycle counter */ __asm__("rdtsc" - :"=a" (last_timer_cc.low), - "=d" (last_timer_cc.high)); + :"=a" (last_tsc_low):: "eax", "edx"); + + outb_p(0x00, 0x43); /* latch the count ASAP */ + + count = inb_p(0x40); /* read the latched count */ + count |= inb(0x40) << 8; + + count = ((LATCH-1) - count) * TICK_SIZE; + delay_at_last_interrupt = (count + LATCH/2) / LATCH; + __restore_flags(flags); + timer_interrupt(irq, NULL, regs); } -#endif /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 @@ -520,6 +497,80 @@ static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; +/* ------ Calibrate the TSC ------- + * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset(). + * Too much 64-bit arithmetic here to do this cleanly in C, and for + * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2) + * output busy loop as low as possible. We avoid reading the CTC registers + * directly because of the awkward 8-bit access mechanism of the 82C54 + * device. + */ + +__initfunc(static unsigned long calibrate_tsc(void)) +{ + unsigned long retval; + + __asm__( /* set the Gate high, program CTC channel 2 for mode 0 + * (interrupt on terminal count mode), binary count, + * load 5 * LATCH count, (LSB and MSB) + * to begin countdown, read the TSC and busy wait. + * BTW LATCH is calculated in timex.h from the HZ value + */ + + /* Set the Gate high, disable speaker */ + "inb $0x61, %%al\n\t" /* Read port */ + "andb $0xfd, %%al\n\t" /* Turn off speaker Data */ + "orb $0x01, %%al\n\t" /* Set Gate high */ + "outb %%al, $0x61\n\t" /* Write port */ + + /* Now let's take care of CTC channel 2 */ + "movb $0xb0, %%al\n\t" /* binary, mode 0, LSB/MSB, ch 2*/ + "outb %%al, $0x43\n\t" /* Write to CTC command port */ + "movb $0x0c, %%al\n\t" + "outb %%al, $0x42\n\t" /* LSB of count */ + "movb $0xe9, %%al\n\t" + "outb %%al, $0x42\n\t" /* MSB of count */ + + /* Read the TSC; counting has just started */ + "rdtsc\n\t" + /* Move the value for safe-keeping. */ + "movl %%eax, %%ebx\n\t" + "movl %%edx, %%ecx\n\t" + + /* Busy wait. Only 50 ms wasted at boot time. */ + "0: inb $0x61, %%al\n\t" /* Read Speaker Output Port */ + "testb $0x20, %%al\n\t" /* Check CTC channel 2 output (bit 5) */ + "jz 0b\n\t" + + /* And read the TSC. 5 jiffies (50.00077ms) have elapsed. */ + "rdtsc\n\t" + + /* Great. So far so good. Store last TSC reading in + * last_tsc_low (only 32 lsb bits needed) */ + "movl %%eax, last_tsc_low\n\t" + /* And now calculate the difference between the readings. */ + "subl %%ebx, %%eax\n\t" + "sbbl %%ecx, %%edx\n\t" /* 64-bit subtract */ + /* but probably edx = 0 at this point (see below). */ + /* Now we have 5 * (TSC counts per jiffy) in eax. We want + * to calculate TSC->microsecond conversion factor. */ + + /* Note that edx (high 32-bits of difference) will now be + * zero iff CPU clock speed is less than 85 GHz. Moore's + * law says that this is likely to be true for the next + * 12 years or so. You will have to change this code to + * do a real 64-by-64 divide before that time's up. */ + "movl %%eax, %%ecx\n\t" + "xorl %%eax, %%eax\n\t" + "movl %1, %%edx\n\t" + "divl %%ecx\n\t" /* eax= 2^32 / (1 * TSC counts per microsecond) */ + /* Return eax for the use of fast_gettimeoffset */ + "movl %%eax, %0\n\t" + : "=r" (retval) + : "r" (5 * 1000020/HZ) + : /* we clobber: */ "ax", "bx", "cx", "dx", "cc", "memory"); + return retval; +} __initfunc(void time_init(void)) { @@ -527,36 +578,36 @@ xtime.tv_usec = 0; /* - * If we have APM enabled we can't currently depend - * on the cycle counter, because a suspend to disk - * will reset it. Somebody should come up with a - * better solution than to just disable the fast time - * code.. - */ -#ifndef CONFIG_APM - /* If we have the CPU hardware time counters, use them */ - if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) { + * If we have APM enabled or the CPU clock speed is variable + * (CPU stops clock on HLT or slows clock to save power) + * then the TSC timestamps may diverge by up to 1 jiffy from + * 'real time' but nothing will break. + * The most frequent case is that the CPU is "woken" from a halt + * state by the timer interrupt itself, so we get 0 error. In the + * rare cases where a driver would "wake" the CPU and request a + * timestamp, the maximum error is < 1 jiffy. But timestamps are + * still perfectly ordered. + * Note that the TSC counter will be reset if APM suspends + * to disk; this won't break the kernel, though, 'cuz we're + * smart. See devices/char/apm_bios.c. + */ + if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) { do_gettimeoffset = do_fast_gettimeoffset; - do_get_fast_time = do_x86_get_fast_time; - - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && - boot_cpu_data.x86 == 5 && - boot_cpu_data.x86_model == 0) { - /* turn on cycle counters during power down */ - __asm__ __volatile__ (" movl $0x83, %%ecx \n \ - rdmsr \n \ - orl $1,%%eax \n \ - wrmsr \n " - : : : "ax", "cx", "dx" ); - udelay(500); - } - - /* read Pentium cycle counter */ - __asm__("rdtsc" - :"=a" (init_timer_cc.low), - "=d" (init_timer_cc.high)); + do_get_fast_time = do_gettimeofday; irq0.handler = pentium_timer_interrupt; + fast_gettimeoffset_quotient = calibrate_tsc(); + + /* report CPU clock rate in Hz. + * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = + * clock/second. Our precision is about 100 ppm. + */ + { unsigned long eax=0, edx=1000000; + __asm__("divl %2" + :"=a" (cpu_hz), "=d" (edx) + :"r" (fast_gettimeoffset_quotient), + "0" (eax), "1" (edx)); + printk("Detected %ld Hz processor.\n", cpu_hz); + } } -#endif setup_x86_irq(0, &irq0); } diff -u --recursive --new-file v2.1.125/linux/arch/mips/Makefile linux/arch/mips/Makefile --- v2.1.125/linux/arch/mips/Makefile Fri May 8 23:14:42 1998 +++ linux/arch/mips/Makefile Tue Oct 20 13:52:54 1998 @@ -1,10 +1,4 @@ -# -# arch/mips/Makefile -# -# This file is included by the global makefile so that you can add your own -# architecture-specific flags and dependencies. Remember to do have actions -# for "archclean" and "archdep" for cleaning up and making dependencies for -# this architecture +# $Id: Makefile,v 1.13 1998/08/17 10:16:23 ralf Exp $ # # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive @@ -13,7 +7,10 @@ # Copyright (C) 1994, 1995, 1996 by Ralf Baechle # DECStation modifications by Paul M. Antoine, 1996 # -# $Id: Makefile,v 1.14 1998/05/01 01:33:20 ralf Exp $ +# This file is included by the global makefile so that you can add your own +# architecture-specific flags and dependencies. Remember to do have actions +# for "archclean" and "archdep" for cleaning up and making dependencies for +# this architecture # # @@ -39,7 +36,7 @@ CROSS_COMPILE = $(tool-prefix) endif -LINKFLAGS = -static -N +LINKFLAGS = -static #-N MODFLAGS += -mlong-calls # @@ -74,7 +71,7 @@ CFLAGS := $(CFLAGS) -mcpu=r6000 -mips2 endif ifdef CONFIG_CPU_R4300 -CFLAGS := $(CFLAGS) -mcpu=r4600 -Wa,-mcpu=vr4300 -mips2 +CFLAGS := $(CFLAGS) -mcpu=r4300 -mips2 endif ifdef CONFIG_CPU_R4X00 CFLAGS := $(CFLAGS) -mcpu=r4600 -mips2 @@ -169,6 +166,8 @@ @$(MAKEBOOT) clean $(MAKE) -C arch/$(ARCH)/kernel clean $(MAKE) -C arch/$(ARCH)/tools clean + +archmrproper: archdep: @$(MAKEBOOT) dep diff -u --recursive --new-file v2.1.125/linux/arch/mips/config.in linux/arch/mips/config.in --- v2.1.125/linux/arch/mips/config.in Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/config.in Tue Oct 20 13:52:54 1998 @@ -98,6 +98,11 @@ bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS bool 'Kernel module loader' CONFIG_KMOD fi + +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB +fi + endmenu source drivers/block/Config.in @@ -189,6 +194,9 @@ source fs/nls/Config.in +comment 'Console drivers' +source drivers/video/Config.in + mainmenu_option next_comment comment 'Sound' @@ -211,4 +219,5 @@ bool ' Build fp execption handler module' CONFIG_MIPS_FPE_MODULE fi bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG +bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu diff -u --recursive --new-file v2.1.125/linux/arch/mips/defconfig linux/arch/mips/defconfig --- v2.1.125/linux/arch/mips/defconfig Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/defconfig Tue Oct 20 13:52:54 1998 @@ -48,7 +48,9 @@ # # Loadable module support # -# CONFIG_MODULES is not set +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y # # Block devices @@ -173,7 +175,8 @@ # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_ULTRASTOR is not set -# CONFIG_JAZZ_ESP is not set +CONFIG_JAZZ_ESP=y +CONFIG_JAZZ_ESP=y # # Network device support @@ -195,10 +198,12 @@ # CONFIG_CS89x0 is not set # CONFIG_DE4X5 is not set # CONFIG_DEC_ELCP is not set +# CONFIG_DEC_ELCP is not set # CONFIG_DGRS is not set # CONFIG_EEXPRESS_PRO100 is not set # CONFIG_NE2K_PCI is not set # CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set # CONFIG_NET_POCKET is not set # CONFIG_FDDI is not set # CONFIG_DLCI is not set @@ -206,6 +211,7 @@ # CONFIG_SLIP is not set # CONFIG_NET_RADIO is not set # CONFIG_TR is not set +# CONFIG_HOSTESS_SV11 is not set # CONFIG_WAN_DRIVERS is not set # CONFIG_LAPBETHER is not set # CONFIG_X25_ASY is not set @@ -243,11 +249,9 @@ # CONFIG_SERIAL_CONSOLE is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_UNIX98_PTYS is not set # CONFIG_MOUSE is not set # CONFIG_QIC02_TAPE is not set -# CONFIG_APM is not set # CONFIG_WATCHDOG is not set # CONFIG_RTC is not set # CONFIG_VIDEO_DEV is not set @@ -286,7 +290,9 @@ # CONFIG_ROMFS_FS is not set # CONFIG_AUTOFS_FS is not set # CONFIG_UFS_FS is not set -CONFIG_DEVPTS_FS=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_SMD_DISKLABEL is not set +# CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_MAC_PARTITION is not set CONFIG_NLS=y @@ -321,6 +327,10 @@ # CONFIG_NLS_KOI8_R is not set # +# Console drivers +# + +# # Sound # # CONFIG_SOUND is not set @@ -329,4 +339,6 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y +# CONFIG_MIPS_FPE_MODULE is not set # CONFIG_REMOTE_DEBUG is not set +# CONFIG_MAGIC_SYSRQ is not set diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/Makefile linux/arch/mips/jazz/Makefile --- v2.1.125/linux/arch/mips/jazz/Makefile Thu Jun 26 12:33:37 1997 +++ linux/arch/mips/jazz/Makefile Tue Oct 20 13:52:54 1998 @@ -13,11 +13,7 @@ all: jazz.o O_TARGET := jazz.o -O_OBJS := hw-access.o int-handler.o jazzdma.o reset.o setup.o - -ifdef CONFIG_VIDEO_G364 -O_OBJS += g364.o -endif +O_OBJS := hw-access.o int-handler.o jazzdma.o reset.o rtc-jazz.o setup.o int-handler.o: int-handler.S diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/floppy-jazz.c linux/arch/mips/jazz/floppy-jazz.c --- v2.1.125/linux/arch/mips/jazz/floppy-jazz.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/jazz/floppy-jazz.c Tue Oct 20 13:52:54 1998 @@ -0,0 +1,166 @@ +/* $Id: floppy-jazz.c,v 1.1 1998/05/07 18:38:29 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Low-level floppy stuff for Jazz family machines. + * + * Copyright (C) 1998 by Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned char jazz_fd_inb(unsigned int port) +{ + unsigned char c; + + c = *(volatile unsigned char *) port; + udelay(1); + + return c; +} + +static void jazz_fd_outb(unsigned char value, unsigned int port) +{ + *(volatile unsigned char *) port = value; +} + +/* + * How to access the floppy DMA functions. + */ +static void jazz_fd_enable_dma(int channel) +{ + vdma_enable(JAZZ_FLOPPY_DMA); +} + +static void jazz_fd_disable_dma(int channel) +{ + vdma_disable(JAZZ_FLOPPY_DMA); +} + +static int jazz_fd_request_dma(int channel) +{ + return 0; +} + +static void jazz_fd_free_dma(int channel) +{ +} + +static void jazz_fd_clear_dma_ff(int channel) +{ +} + +static void jazz_fd_set_dma_mode(int channel, char mode) +{ + vdma_set_mode(JAZZ_FLOPPY_DMA, mode); +} + +static void jazz_fd_set_dma_addr(int channel, unsigned int a) +{ + vdma_set_addr(JAZZ_FLOPPY_DMA, vdma_phys2log(PHYSADDR(a))); +} + +static void jazz_fd_set_dma_count(int channel, unsigned int count) +{ + vdma_set_count(JAZZ_FLOPPY_DMA, count); +} + +static int jazz_fd_get_dma_residue(int channel) +{ + return vdma_get_residue(JAZZ_FLOPPY_DMA); +} + +static void jazz_fd_enable_irq(int irq) +{ +} + +static void jazz_fd_disable_irq(int irq) +{ +} + +static unsigned long jazz_fd_getfdaddr1(void) +{ + return JAZZ_FDC_BASE; +} + +/* Pure 2^n version of get_order */ +extern inline int __get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +extern inline unsigned long jazz_fd_dma_mem_alloc(unsigned long size) +{ + int order = __get_order(size); + unsigned long mem; + + mem = __get_dma_pages(GFP_KERNEL, order); + if(!mem) + return 0; + vdma_alloc(PHYSADDR(mem), size); /* XXX error checking */ + + return mem; +} + +extern inline void jazz_fd_dma_mem_free(unsigned long addr, + unsigned long size) +{ + vdma_free(PHYSADDR(addr)); + free_pages(addr, __get_order(size)); +} + +static void std_fd_drive_type(unsigned long n) +{ + /* XXX This is wrong for machines with ED 2.88mb disk drives like the + Olivetti M700. Anyway, we should suck this from the ARC + firmware. */ + if (n == 0) + return 4; /* 3,5", 1.44mb */ + + return 0; +} + +struct fd_ops jazz_fd_ops = { + /* + * How to access the floppy controller's ports + */ + jazz_fd_inb, + jazz_fd_outb, + /* + * How to access the floppy DMA functions. + */ + jazz_fd_enable_dma, + jazz_fd_disable_dma, + jazz_fd_request_dma, + jazz_fd_free_dma, + jazz_fd_clear_dma_ff, + jazz_fd_set_dma_mode, + jazz_fd_set_dma_addr, + jazz_fd_set_dma_count, + jazz_fd_get_dma_residue, + jazz_fd_enable_irq, + jazz_fd_disable_irq, + jazz_fd_getfdaddr1, + jazz_fd_dma_mem_alloc, + jazz_fd_dma_mem_free, + jazz_fd_drive_type +}; diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/g364.c linux/arch/mips/jazz/g364.c --- v2.1.125/linux/arch/mips/jazz/g364.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/jazz/g364.c Wed Dec 31 16:00:00 1969 @@ -1,444 +0,0 @@ -/* - * linux/drivers/char/g364.c - * - * Copyright (C) 1996 Wayne Hodgen - * - * Based on and using chunks of Jay Estabrooks tga.c - * - * This module exports the console io support for Inmos's G364 controller - * used in Mips Magnums and clones. Based on the hardware desc for the - * Olivetti M700-10 ie. an Inmos G364 based card in a dedicated video slot, - * 2MB dual ported VRAM with a 64 bit data path, 256 color lookup table, - * palette of 16.7M and a user definable 64x64 hardware cursor. - * - * $Id: g364.c,v 1.7 1998/05/01 01:33:35 ralf Exp $ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -extern void register_console(void (*proc)(const char *)); -extern void console_print(const char *); -unsigned video_res_x; - -/* - * Various defines for the G364 - */ -#define G364_MEM_BASE 0xe4400000 -#define G364_PORT_BASE 0xe4000000 -#define ID_REG 0xe4000000 /* Read only */ -#define BOOT_REG 0xe4080000 -#define TIMING_REG 0xe4080108 /* to 0x080170 - DON'T TOUCH! */ -#define MASK_REG 0xe4080200 -#define CTLA_REG 0xe4080300 -#define CURS_TOGGLE 0x800000 -#define BIT_PER_PIX 0x700000 /* bits 22 to 20 of Control A */ -#define DELAY_SAMPLE 0x080000 -#define PORT_INTER 0x040000 -#define PIX_PIPE_DEL 0x030000 /* bits 17 and 16 of Control A */ -#define PIX_PIPE_DEL2 0x008000 /* same as above - don't ask me why */ -#define TR_CYCLE_TOG 0x004000 -#define VRAM_ADR_INC 0x003000 /* bits 13 and 12 of Control A */ -#define BLANK_OFF 0x000800 -#define FORCE_BLANK 0x000400 -#define BLK_FUN_SWTCH 0x000200 -#define BLANK_IO 0x000100 -#define BLANK_LEVEL 0x000080 -#define A_VID_FORM 0x000040 -#define D_SYNC_FORM 0x000020 -#define FRAME_FLY_PAT 0x000010 -#define OP_MODE 0x000008 -#define INTL_STAND 0x000004 -#define SCRN_FORM 0x000002 -#define ENABLE_VTG 0x000001 -#define TOP_REG 0xe4080400 -#define CURS_PAL_REG 0xe4080508 /* to 0x080518 */ -#define CHKSUM_REG 0xe4080600 /* to 0x080610 - unused */ -#define CURS_POS_REG 0xe4080638 -#define CLR_PAL_REG 0xe4080800 /* to 0x080ff8 */ -#define CURS_PAT_REG 0xe4081000 /* to 0x081ff8 */ -#define MON_ID_REG 0xe4100000 /* unused */ -#define RESET_REG 0xe4180000 /* Write only */ - -/* - * built-in font management constants - * - * NOTE: the built-in font is 8x16, and the video resolution - * is either 1280x1024 @ 60Hz or 1024x768 @ 60 or 78Hz. - */ -#define FONTSIZE_X 8 /* 8 pixels wide */ -#define FONTSIZE_Y 16 /* 16 pixels high */ - -unsigned char g364_font[] = { -#include "g364.fnt" -}; - -#ifdef CONFIG_REMOTE_DEBUG -/* #define DEBUG_G364 */ - -extern int putDebugChar(char c); - -void -putDebugString(char *d_str) -{ - while (*d_str != '\0') { - putDebugChar(*d_str); - d_str++; - } - if (*--d_str != '\n') - putDebugChar('\n'); -} -#endif - -void g364_clear_screen(void); - -int cursor_initialised=0; - -__initfunc(unsigned long -con_type_init(unsigned long kmem_start, const char **display_desc)) -{ - can_do_color = 1; - - /* - * fake the screen memory with some CPU memory - */ - video_mem_base = kmem_start; - kmem_start += video_screen_size; - video_mem_term = kmem_start; - video_type = VIDEO_TYPE_MIPS_G364; - video_res_x = video_num_columns * FONTSIZE_X; - - *display_desc = "G364"; - - return kmem_start; -} - -__initfunc(void -con_type_init_finish(void)) -{ -} - -void -__set_origin(unsigned short offset) -{ - /* - * should not be called, but if so, do nothing... - */ -} - -/* - * Hide the cursor from view, during blanking, usually... - */ -void -hide_cursor(void) -{ - *(unsigned int *) CTLA_REG |= CURS_TOGGLE; -} - -void -init_g364_cursor(void) -{ - volatile unsigned int *ptr = (unsigned int *) CURS_PAL_REG; - int i; - - *ptr |= 0x00ffffff; - ptr[2] |= 0x00ffffff; - ptr[4] |= 0x00ffffff; - - /* - * first set the whole cursor to transparent - */ - for (i = 0; i < 512; i++) - *(unsigned short *)(CURS_PAT_REG+i*8) = 0; - - /* - * switch the last to lines to cursor palette 3 - * we assume here, that FONTSIZE_X is 8 - */ - *(unsigned short *)(CURS_PAT_REG + (FONTSIZE_Y-2)*64) = 0xffff; - *(unsigned short *)(CURS_PAT_REG + (FONTSIZE_Y-1)*64) = 0xffff; - cursor_initialised = 1; -} - -/* - * Set the cursor on. - */ -void -set_cursor(int currcons) -{ - unsigned int idx, xt, yt, row, col; - - if (!cursor_initialised) - init_g364_cursor(); - - if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS) - return; - - *(unsigned int *) CTLA_REG &= ~CURS_TOGGLE; - - if (__real_origin != __origin) - __set_origin (__real_origin); - - if (deccm) { - idx = (pos - video_mem_base) >> 1; - col = idx % video_num_columns; - row = (idx - col) / video_num_columns; - - xt = col * FONTSIZE_X; - yt = row * FONTSIZE_Y; - *(unsigned int *)CURS_POS_REG = (xt << 12) | yt; - } else - hide_cursor(); -} - -/* - * NOTE: get_scrmem() and set_scrmem() are here only because - * the VGA version of set_scrmem() has some direct VGA references. - */ -void -get_scrmem(int currcons) -{ - memcpyw((unsigned short *)vc_scrbuf[currcons], - (unsigned short *)origin, video_screen_size); - origin = video_mem_start = (unsigned long)vc_scrbuf[currcons]; - scr_end = video_mem_end = video_mem_start + video_screen_size; - pos = origin + y*video_size_row + (x<<1); -} - -void -set_scrmem(int currcons, long offset) -{ - if (video_mem_term - video_mem_base < offset + video_screen_size) - offset = 0; /* strange ... */ - memcpyw((unsigned short *)(video_mem_base + offset), - (unsigned short *) origin, video_screen_size); - video_mem_start = video_mem_base; - video_mem_end = video_mem_term; - origin = video_mem_base + offset; - scr_end = origin + video_screen_size; - pos = origin + y*video_size_row + (x<<1); -} - -/* - * Fill out later - */ -void -set_palette(void) -{ - int i, j; - volatile unsigned int *ptr = (volatile unsigned int *) CLR_PAL_REG; - - for (i = 0; i < 16; i++,ptr+=2) { - j = color_table[i]; - *ptr = ((default_red[j] << 16) | - (default_grn[j] << 8) | - (default_blu[j])); - } -} - -/* - * NOTE: - * this is here, and not in console.c, because the VGA version - * tests the controller type to see if color can be done. We *KNOW* - * that we can do color on the G364. - * - */ - -int -set_get_cmap(unsigned char * arg, int set) -{ - int i; - - for (i=0; i<16; i++) { - if (set) { - if (!access_ok(VERIFY_READ, (void *)arg, 16*3)) goto fault; - if (__get_user(default_red[i], arg++)) goto fault; - if (__get_user(default_grn[i], arg++)) goto fault; - if (__get_user(default_blu[i], arg++)) goto fault; - } else { - if (!access_ok(VERIFY_WRITE, (void *)arg, 16*3)) goto fault; - if (__put_user(default_red[i], arg++)) goto fault; - if (__put_user(default_grn[i], arg++)) goto fault; - if (__put_user(default_blu[i], arg++)) goto fault; - } - } - if (set) { - for (i=0; ivc_palette[k++] = default_red[j]; - vc_cons[i].d->vc_palette[k++] = default_grn[j]; - vc_cons[i].d->vc_palette[k++] = default_blu[j]; - } - } - set_palette() ; - } - - return 0; - -fault: - return -EFAULT; -} - -/* - * Adjust the screen to fit a font of a certain height - * - * Returns < 0 for error, 0 if nothing changed, and the number - * of lines on the adjusted console if changed. - * - * for now, we only support the built-in font... - */ -int -con_adjust_height(unsigned long fontheight) -{ - return -EINVAL; -} - -/* - * PIO_FONT support. - * - * for now, we will use/allow *only* our built-in font... - */ -int -set_get_font(char * arg, int set, int ch512) -{ - return -EINVAL; -} - -/* - * print a character to a graphics console. - */ -void -g364_blitc(unsigned short charattr, unsigned long addr) -{ - int row, col, temp; - register unsigned long long *dst, *font_row; - register int i; - char c; - - /* - * calculate (row,col) from addr and video_mem_base - */ - temp = (addr - video_mem_base) >> 1; - col = temp % 128; - row = (temp - col) / 128; - - /* - * calculate destination address - */ - dst = (unsigned long long *) ( G364_MEM_BASE - + ( row * video_res_x * FONTSIZE_Y ) - + ( col * FONTSIZE_X ) ); - - c = charattr & 0x00ff; - if (c == 0x20) { - for (i=0; i < FONTSIZE_Y; i++, dst += video_num_columns) - *dst = 0x00000000; - } else { - font_row = (unsigned long long *) &g364_font[(c << 7)]; - for (i=0; i < FONTSIZE_Y; i++, font_row++, dst += video_num_columns) - *dst = *font_row; - } -} - -/* - * print a character to a graphics console. Colour version, slower! - */ -void -g364_blitc_colour(unsigned short charattr, unsigned long addr) -{ - int row, col, temp, c, attrib; - register unsigned int fgmask, bgmask; - register unsigned long long *dst, *font_row; - register int i, stride; - - c = charattr & 0x00ff; - attrib = (charattr >> 8) & 0x00ff; - - /* - * extract foreground and background indices - * NOTE: we always treat blink/underline bits as color for now... - */ - fgmask = attrib & 0x0f; - bgmask = (attrib >> 4) & 0x0f; - - /* i = (c & 0xff) << 7; NOTE: assumption of 128 bytes per character bitmap */ - - /* - * calculate (row,col) from addr and video_mem_base - */ - temp = (addr - video_mem_base) >> 1; - col = temp % 128; - row = (temp - col) / 128; - stride = video_res_x / 8; - - /* - * calculate destination address - */ - dst = (unsigned long long *) ( G364_MEM_BASE - + ( row * video_res_x * FONTSIZE_Y ) - + ( col * FONTSIZE_X ) ); - - font_row = (unsigned long long *) &g364_font[((c & 0xff) << 7)]; - - for (i=0; i < FONTSIZE_Y; i++, font_row++, dst += stride) { - *dst = *font_row; - } -} - -/* - * dummy routines for the VESA blanking code, which is VGA only, - * so we don't have to carry that stuff around for the G364... - */ -void -vesa_powerdown(void) -{ -} - -void -vesa_blank(void) -{ -} - -void -vesa_unblank(void) -{ -} - -void -set_vesa_blanking(const unsigned long arg) -{ -} - -/* - * FIXME: how can we probe for the video board? - */ -__initfunc(int con_is_present()) -{ - return; -} diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/g364.fnt linux/arch/mips/jazz/g364.fnt --- v2.1.125/linux/arch/mips/jazz/g364.fnt Thu Jun 26 12:33:37 1997 +++ linux/arch/mips/jazz/g364.fnt Wed Dec 31 16:00:00 1969 @@ -1,4097 +0,0 @@ -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x07,0x00,0x07,0x07,0x07, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x00,0x07,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x00, -0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x07,0x00, -0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x07, -0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x07, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07, -0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x07, -0x07,0x00,0x00,0x07,0x07,0x00,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x07, -0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x07, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x07, -0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x07, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07, -0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00, -0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07, -0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x07, -0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07, -0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07, -0x07,0x07,0x07,0x07,0x00,0x07,0x00,0x07, -0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07, -0x07,0x07,0x07,0x07,0x00,0x07,0x00,0x07, -0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07, -0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07, -0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x00,0x00,0x07,0x00,0x07,0x00,0x00, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x07,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07, -0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x00,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x07, -0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x07, -0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x07, -0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x07,0x07,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x07,0x07,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x00, -0x07,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x00,0x00,0x07,0x07,0x00,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x07,0x07,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x07,0x07,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x07, -0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00, -0x07,0x07,0x00,0x07,0x00,0x00,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x07, -0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07, -0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07, -0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07, -0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x07, -0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x07, -0x00,0x07,0x00,0x07,0x07,0x00,0x07,0x07, -0x00,0x07,0x00,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07, -0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x07,0x00,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x07, -0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x07, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07, -0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x07, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00, -0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00, -0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00, -0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00, -0x07,0x00,0x00,0x07,0x00,0x00,0x07,0x00, -0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x07, -0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07, -0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00, -0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00, -0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00, -0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00, -0x00,0x07,0x00,0x00,0x07,0x00,0x00,0x00, -0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0 diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/hw-access.c linux/arch/mips/jazz/hw-access.c --- v2.1.125/linux/arch/mips/jazz/hw-access.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/jazz/hw-access.c Tue Oct 20 13:52:54 1998 @@ -1,11 +1,12 @@ -/* $Id: hw-access.c,v 1.5 1998/05/07 00:39:27 ralf Exp $ +/* $Id: hw-access.c,v 1.11 1998/09/16 22:50:39 ralf Exp $ + * * Low-level hardware access stuff for Jazz family machines. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1996, 1997 by Ralf Baechle + * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle */ #include #include @@ -13,141 +14,10 @@ #include #include #include -#include #include #include #include #include -#include - -static unsigned char -fd_inb(unsigned int port) -{ - unsigned char c; - - c = *(volatile unsigned char *) port; - udelay(1); - - return c; -} - -static void -fd_outb(unsigned char value, unsigned int port) -{ - *(volatile unsigned char *) port = value; -} - -/* - * How to access the floppy DMA functions. - */ -static void -fd_enable_dma(int channel) -{ - vdma_enable(JAZZ_FLOPPY_DMA); -} - -static void -fd_disable_dma(int channel) -{ - vdma_disable(JAZZ_FLOPPY_DMA); -} - -static int -fd_request_dma(int channel) -{ - return 0; -} - -static void -fd_free_dma(int channel) -{ -} - -static void -fd_clear_dma_ff(int channel) -{ -} - -static void -fd_set_dma_mode(int channel, char mode) -{ - vdma_set_mode(JAZZ_FLOPPY_DMA, mode); -} - -static void -fd_set_dma_addr(int channel, unsigned int a) -{ - vdma_set_addr(JAZZ_FLOPPY_DMA, vdma_phys2log(PHYSADDR(a))); -} - -static void -fd_set_dma_count(int channel, unsigned int count) -{ - vdma_set_count(JAZZ_FLOPPY_DMA, count); -} - -static int -fd_get_dma_residue(int channel) -{ - return vdma_get_residue(JAZZ_FLOPPY_DMA); -} - -static void -fd_enable_irq(int irq) -{ -} - -static void -fd_disable_irq(int irq) -{ -} - -void -jazz_fd_cacheflush(const void *addr, size_t size) -{ - flush_cache_all(); -} - -static unsigned char -rtc_read_data(unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - return *(char *)JAZZ_RTC_BASE; -} - -static void -rtc_write_data(unsigned char data, unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - *(char *)JAZZ_RTC_BASE = data; -} - -struct feature jazz_feature = { - /* - * How to access the floppy controller's ports - */ - fd_inb, - fd_outb, - /* - * How to access the floppy DMA functions. - */ - fd_enable_dma, - fd_disable_dma, - fd_request_dma, - fd_free_dma, - fd_clear_dma_ff, - fd_set_dma_mode, - fd_set_dma_addr, - fd_set_dma_count, - fd_get_dma_residue, - fd_enable_irq, - fd_disable_irq, - /* - * How to access the RTC functions. - */ - rtc_read_data, - rtc_write_data -}; static volatile keyboard_hardware *jazz_kh = (keyboard_hardware *) JAZZ_KEYBOARD_ADDRESS; @@ -190,6 +60,31 @@ kbd_write_output = jazz_write_output; kbd_write_command = jazz_write_command; kbd_read_status = jazz_read_status; + request_irq(JAZZ_KEYBOARD_IRQ, keyboard_interrupt, + 0, "keyboard", NULL); request_region(0x60, 16, "keyboard"); - r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | JAZZ_IE_KEYBOARD); + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, + r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) + | JAZZ_IE_KEYBOARD); +} + +int jazz_ps2_request_irq(void) +{ + extern void aux_interrupt(int, void *, struct pt_regs *); + int ret; + + ret = request_irq(JAZZ_MOUSE_IRQ, aux_interrupt, 0, "PS/2 Mouse", NULL); + if (!ret) + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, + r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | + JAZZ_IE_MOUSE); + return ret; +} + +void jazz_ps2_free_irq(void) +{ + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, + r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | + JAZZ_IE_MOUSE); + free_irq(JAZZ_MOUSE_IRQ, NULL); } diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/int-handler.S linux/arch/mips/jazz/int-handler.S --- v2.1.125/linux/arch/mips/jazz/int-handler.S Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/jazz/int-handler.S Tue Oct 20 13:52:54 1998 @@ -1,4 +1,4 @@ -/* $Id: int-handler.S,v 1.6 1998/05/08 01:44:08 ralf Exp $ +/* $Id: int-handler.S,v 1.6 1998/08/28 15:55:19 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -261,7 +261,12 @@ li a0,JAZZ_KEYBOARD_IRQ b loc_call -loc_mouse: PANIC("Unimplemented loc_mouse handler") +/* + * Mouse interrupt handler + */ +loc_mouse: li s1,~JAZZ_IE_MOUSE + li a0,JAZZ_MOUSE_IRQ + b loc_call /* * Serial port 1 IRQ diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/reset.c linux/arch/mips/jazz/reset.c --- v2.1.125/linux/arch/mips/jazz/reset.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/jazz/reset.c Tue Oct 20 13:52:54 1998 @@ -3,7 +3,7 @@ * * Reset a Jazz machine. * - * $Id: reset.c,v 1.2 1998/05/01 01:33:40 ralf Exp $ + * $Id: reset.c,v 1.2 1998/03/04 12:17:40 ralf Exp $ */ #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/rtc-jazz.c linux/arch/mips/jazz/rtc-jazz.c --- v2.1.125/linux/arch/mips/jazz/rtc-jazz.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/jazz/rtc-jazz.c Tue Oct 20 13:52:54 1998 @@ -0,0 +1,36 @@ +/* $Id: rtc-jazz.c,v 1.3 1998/08/28 15:55:19 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * RTC routines for Jazz style attached Dallas chip. + * + * Copyright (C) 1998 by Ralf Baechle + */ +#include +#include +#include + +static unsigned char jazz_rtc_read_data(unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + return *(char *)JAZZ_RTC_BASE; +} + +static void jazz_rtc_write_data(unsigned char data, unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + *(char *)JAZZ_RTC_BASE = data; +} + +static int jazz_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops jazz_rtc_ops = { + &jazz_rtc_read_data, + &jazz_rtc_write_data, + &jazz_rtc_bcd_mode +}; diff -u --recursive --new-file v2.1.125/linux/arch/mips/jazz/setup.c linux/arch/mips/jazz/setup.c --- v2.1.125/linux/arch/mips/jazz/setup.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/jazz/setup.c Tue Oct 20 13:52:54 1998 @@ -1,21 +1,24 @@ -/* +/* $Id: setup.c,v 1.14 1998/09/16 22:50:40 ralf Exp $ + * * Setup pointers to hardware-dependent routines. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1997 by Ralf Baechle - * - * $Id: setup.c,v 1.7 1998/06/10 07:21:07 davem Exp $ + * Copyright (C) 1996, 1997, 1998 by Ralf Baechle */ #include #include #include #include +#include #include #include #include +#include +#include +#include #include #include #include @@ -23,7 +26,6 @@ #include #include #include -#include #include #include @@ -38,8 +40,6 @@ static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; extern asmlinkage void jazz_handle_int(void); -extern asmlinkage void jazz_fd_cacheflush(const void *addr, size_t size); -extern struct feature jazz_feature; extern void jazz_keyboard_setup(void); extern void jazz_machine_restart(char *command); @@ -47,6 +47,7 @@ extern void jazz_machine_power_off(void); extern struct ide_ops std_ide_ops; +extern struct rtc_ops jazz_rtc_ops; void (*board_time_init)(struct irqaction *irq); @@ -110,9 +111,7 @@ add_wired_entry (0x01800017, 0x01000017, 0xe4000000, PM_4M); irq_setup = jazz_irq_setup; - fd_cacheflush = jazz_fd_cacheflush; keyboard_setup = jazz_keyboard_setup; - feature = &jazz_feature; // Will go away mips_io_port_base = JAZZ_PORT_BASE; isa_slot_offset = 0xe3000000; request_region(0x00,0x20,"dma1"); @@ -129,4 +128,6 @@ #ifdef CONFIG_BLK_DEV_IDE ide_ops = &std_ide_ops; #endif + conswitchp = &fb_con; + rtc_ops = &jazz_rtc_ops; } diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/Makefile linux/arch/mips/kernel/Makefile --- v2.1.125/linux/arch/mips/kernel/Makefile Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/Makefile Tue Oct 20 13:52:54 1998 @@ -15,7 +15,7 @@ O_OBJS := branch.o process.o signal.o entry.o traps.o ptrace.o vm86.o \ ioport.o pci.o reset.o setup.o syscall.o sysmips.o ipc.o \ r4k_switch.o r4k_misc.o r4k_fpu.o r2300_switch.o r2300_misc.o \ - r2300_fpu.o r6000_fpu.o scall_o32.o unaligned.o + r2300_fpu.o r6000_fpu.o scall_o32.o softfp.o unaligned.o OX_OBJS := mips_ksyms.o ifdef CONFIG_MIPS_FPE_MODULE diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/entry.S linux/arch/mips/kernel/entry.S --- v2.1.125/linux/arch/mips/kernel/entry.S Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/entry.S Tue Oct 20 13:52:54 1998 @@ -7,7 +7,7 @@ * * Copyright (C) 1994, 1995 by Ralf Baechle * - * $Id: entry.S,v 1.10 1998/07/26 03:02:06 davem Exp $ + * $Id: entry.S,v 1.15 1998/10/14 20:26:26 ralf Exp $ */ /* @@ -59,8 +59,7 @@ andi t1, t0, 0x10 beqz t1, return # -> yes -#error Change this to current->need_resched --DaveM - lw t1, need_resched + lw t1, TASK_NEED_RESCHED($28) bnez t1, reschedule lw v0, TASK_SIGPENDING($28) move a0, zero @@ -101,8 +100,6 @@ STI #define __BUILD_clear_cli(exception) \ CLI -#define __BUILD_clear_kmode(exception) \ - KMODE #define __BUILD_clear_fpe(exception) \ cfc1 a1,fcr31; \ li a2,~(0x3f<<12); \ @@ -112,7 +109,7 @@ #define __BUILD_clear_ade(exception) \ MFC0 t0,CP0_BADVADDR; \ REG_S t0,PT_BVADDR(sp); \ - STI + KMODE #define __BUILD_silent(exception) #define fmt "Got %s at %08lx.\n" @@ -146,8 +143,8 @@ nop; \ END(handle_##exception) - BUILD_HANDLER(adel,ade,kmode,silent) /* #4 */ - BUILD_HANDLER(ades,ade,kmode,silent) /* #5 */ + BUILD_HANDLER(adel,ade,ade,silent) /* #4 */ + BUILD_HANDLER(ades,ade,ade,silent) /* #5 */ BUILD_HANDLER(ibe,ibe,cli,verbose) /* #6 */ BUILD_HANDLER(dbe,dbe,cli,verbose) /* #7 */ BUILD_HANDLER(bp,bp,sti,silent) /* #9 */ @@ -155,10 +152,8 @@ BUILD_HANDLER(cpu,cpu,sti,silent) /* #11 */ BUILD_HANDLER(ov,ov,sti,silent) /* #12 */ BUILD_HANDLER(tr,tr,sti,silent) /* #13 */ - BUILD_HANDLER(vcei,vcei,sti,verbose) /* #14 */ BUILD_HANDLER(fpe,fpe,fpe,silent) /* #15 */ BUILD_HANDLER(watch,watch,sti,verbose) /* #23 */ - BUILD_HANDLER(vced,vced,sti,verbose) /* #31 */ BUILD_HANDLER(reserved,reserved,sti,verbose) /* others */ /* diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/fpe.c linux/arch/mips/kernel/fpe.c --- v2.1.125/linux/arch/mips/kernel/fpe.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/fpe.c Tue Oct 20 13:52:54 1998 @@ -6,7 +6,7 @@ * * Copyright (C) 1997 Ralf Baechle * - * $Id: fpe.c,v 1.2 1998/05/01 01:33:48 ralf Exp $ + * $Id: fpe.c,v 1.2 1998/03/27 08:53:39 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/gdb-low.S linux/arch/mips/kernel/gdb-low.S --- v2.1.125/linux/arch/mips/kernel/gdb-low.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/gdb-low.S Tue Oct 20 13:52:54 1998 @@ -5,7 +5,7 @@ * * Copyright (C) 1995 Andreas Busse * - * $Id: gdb-low.S,v 1.4 1998/05/01 01:33:50 ralf Exp $ + * $Id: gdb-low.S,v 1.3 1997/12/02 05:51:05 ralf Exp $ */ #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/gdb-stub.c linux/arch/mips/kernel/gdb-stub.c --- v2.1.125/linux/arch/mips/kernel/gdb-stub.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/gdb-stub.c Tue Oct 20 13:52:54 1998 @@ -12,7 +12,7 @@ * * Copyright (C) 1995 Andreas Busse * - * $Id: gdb-stub.c,v 1.7 1998/05/01 01:33:51 ralf Exp $ + * $Id: gdb-stub.c,v 1.4 1997/12/02 05:51:06 ralf Exp $ */ /* diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/head.S linux/arch/mips/kernel/head.S --- v2.1.125/linux/arch/mips/kernel/head.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/head.S Tue Oct 20 13:52:54 1998 @@ -1,19 +1,25 @@ -/* - * arch/mips/kernel/head.S +/* $Id: head.S,v 1.13 1998/10/14 20:26:27 ralf Exp $ + * + * arch/mips/kernel/head.S * - * Copyright (C) 1994, 1995 Waldorf Electronics, 1996 Paul M. Antoine - * Written by Ralf Baechle and Andreas Busse - * Modified for DECStation and hence R3000 support by Paul M. Antoine - * Further modifications by David S. Miller + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * Head.S contains the MIPS exception handler and startup code. + * Copyright (C) 1994, 1995 Waldorf Electronics + * Written by Ralf Baechle and Andreas Busse + * Copyright (C) 1995, 1996, 1997, 1998 Ralf Baechle + * Copyright (C) 1996 Paul M. Antoine + * Modified for DECStation and hence R3000 support by Paul M. Antoine + * Further modifications by David S. Miller * - * $Id: head.S,v 1.9 1998/05/01 01:33:53 ralf Exp $ + * Head.S contains the MIPS exception handler and startup code. */ #include #include #include +#include #include #include #include @@ -29,10 +35,10 @@ /* * Reserved space for exception handlers. * Necessary for machines which link their kernels at KSEG0. - * FIXME: We could overwrite some of the useless handlers - * with those actually being used. + * FIXME: Use the initcode feature to get rid of unused handler + * variants. */ - .fill 520 + .fill 0x280 /* * This is space for the interrupt handlers. * After trap_init() they are located at virtual address KSEG0. @@ -317,16 +323,48 @@ NESTED(except_vec3_r4000, 0, sp) .set noat mfc0 k1, CP0_CAUSE - - /* XXX Have to check for VCE's _before_ we do a load or store. */ - - la k0, exception_handlers andi k1, k1, 0x7c + li k0, 31<<2 + beq k1, k0, handle_vced + li k0, 14<<2 + beq k1, k0, handle_vcei + la k0, exception_handlers addu k0, k0, k1 lw k0, (k0) nop jr k0 nop + +/* + * Big shit, we now may have two dirty primary cache lines for the same + * physical address. We can savely invalidate the line pointed to by + * c0_badvaddr because after return from this exception handler the load / + * store will be re-executed. + */ +handle_vced: + mfc0 k0, CP0_BADVADDR + li k1, -4 + and k0, k1 + mtc0 zero, CP0_TAGLO + // nop;nop + cache Index_Store_Tag_D,(k0) + // nop;nop + cache Hit_Writeback_Inv_SD,(k0) + lui k0, %hi(vced_count) + lw k1, %lo(vced_count)(k0) + addiu k1, 1 + sw k1, %lo(vced_count)(k0) + eret + +handle_vcei: + mfc0 k0, CP0_BADVADDR + cache Hit_Writeback_Inv_SD,(k0) # also cleans pi + lui k0, %hi(vcei_count) + lw k1, %lo(vcei_count)(k0) + addiu k1, 1 + sw k1, %lo(vcei_count)(k0) + eret + END(except_vec3_r4000) .set at @@ -779,32 +817,35 @@ .word 0 # no. wired TLB entries .word 0 # dummy - .text - - .org 0x1000 - EXPORT(swapper_pg_dir) - - .org 0x2000 - EXPORT(empty_bad_page) +/* + * This buffer is reserved for the use of the cache error handler. + */ + .data + EXPORT(cache_error_buffer) + .fill 32*4,1,0 - .org 0x3000 - EXPORT(empty_bad_page_table) +EXPORT(kernelsp) + PTR 0 + .text - .org 0x4000 - EXPORT(empty_zero_page) + .org 0x1000 +EXPORT(swapper_pg_dir) - .org 0x5000 - EXPORT(invalid_pte_table) + .org 0x2000 +EXPORT(empty_bad_page) - .org 0x6000 + .org 0x3000 +EXPORT(empty_bad_page_table) - /* - * init_task_union follows here in the .text segment. - * Keep this aligned to a 8kb boundary! - */ - .data - EXPORT(cache_error_buffer) - .fill 32*4,1,0 + .org 0x4000 +EXPORT(invalid_pte_table) - EXPORT(kernelsp) - PTR 0 + .org 0x5000 +/* XXX This label is required to keep GAS trying to be too clever ... + Bug? */ +dummy: +/* + * Align to 8kb boundary for init_task_union which follows in the + * .text segment. + */ + .align 13 diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irix5sys.h linux/arch/mips/kernel/irix5sys.h --- v2.1.125/linux/arch/mips/kernel/irix5sys.h Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/irix5sys.h Tue Oct 20 13:52:54 1998 @@ -1,4 +1,5 @@ -/* $Id: irix5sys.h,v 1.3 1998/05/01 01:33:55 ralf Exp $ +/* $Id: irix5sys.h,v 1.2 1998/08/17 10:16:25 ralf Exp $ + * * irix5sys.h: 32-bit IRIX5 ABI system call table. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) @@ -34,7 +35,7 @@ SYS(irix_gtime, 0) /* 1013 time() V*/ SYS(irix_unimp, 0) /* 1014 (XXX IRIX 4 mknod) V*/ SYS(sys_chmod, 2) /* 1015 chmod() V*/ -SYS(irix_chown, 3) /* 1016 chown() V*/ +SYS(sys_chown, 3) /* 1016 chown() V*/ SYS(irix_brk, 1) /* 1017 break() V*/ SYS(irix_unimp, 0) /* 1018 (XXX IRIX 4 stat) V*/ SYS(sys_lseek, 3) /* 1019 lseek() XXX64bit HV*/ @@ -196,7 +197,7 @@ SYS(irix_fstatvfs, 2) /* 1175 fstatvfs() V*/ SYS(irix_unimp, 0) /* 1176 XXX getpmsg() DC*/ SYS(irix_unimp, 0) /* 1177 XXX putpmsg() DC*/ -SYS(irix_lchown, 3) /* 1178 lchown() V*/ +SYS(sys_lchown, 3) /* 1178 lchown() V*/ SYS(irix_priocntl, 0) /* 1179 priocntl() DC*/ SYS(irix_sigqueue, 4) /* 1180 sigqueue() IV*/ SYS(sys_readv, 3) /* 1181 readv() V*/ diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c --- v2.1.125/linux/arch/mips/kernel/irixelf.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/irixelf.c Tue Oct 20 13:52:54 1998 @@ -378,8 +378,8 @@ /* Now fill out the bss section. First pad the last page up * to the page boundary, and then perform a mmap to make sure - * that there are zeromapped pages up to and including the last - * bss page. + * that there are zero-mapped pages up to and including the + * last bss page. */ #ifdef DEBUG_ELF printk("padzero(%08lx) ", (unsigned long) (elf_bss)); @@ -1254,10 +1254,9 @@ notes[1].type = NT_PRPSINFO; notes[1].datasz = sizeof(psinfo); notes[1].data = &psinfo; - psinfo.pr_state = current->state; - psinfo.pr_sname = - ((current->state < 0 || current->state > 5) ? - ('.') : ("RSDZTD"[current->state])); + i = current->state ? ffz(~current->state) + 1 : 0; + psinfo.pr_state = i; + psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i]; psinfo.pr_zomb = psinfo.pr_sname == 'Z'; psinfo.pr_nice = current->priority-15; psinfo.pr_flag = current->flags; @@ -1286,7 +1285,7 @@ notes[2].datasz = sizeof(*current); notes[2].data = current; - /* Try to dump the fpu. */ + /* Try to dump the FPU. */ prstatus.pr_fpvalid = dump_fpu (&fpu); if (!prstatus.pr_fpvalid) { numnote--; @@ -1388,7 +1387,7 @@ return has_dumped; } -__initfunc(int init_irix_binfmt(void)) +int __init init_irix_binfmt(void) { return register_binfmt(&irix_format); } diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irixinv.c linux/arch/mips/kernel/irixinv.c --- v2.1.125/linux/arch/mips/kernel/irixinv.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/irixinv.c Tue Oct 20 13:52:54 1998 @@ -5,7 +5,7 @@ * * Miguel de Icaza, 1997. * - * $Id: irixinv.c,v 1.2 1998/05/01 01:33:58 ralf Exp $ + * $Id: irixinv.c,v 1.3 1998/03/27 08:53:40 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irixioctl.c linux/arch/mips/kernel/irixioctl.c --- v2.1.125/linux/arch/mips/kernel/irixioctl.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/irixioctl.c Tue Oct 20 13:52:54 1998 @@ -1,4 +1,4 @@ -/* $Id: irixioctl.c,v 1.6 1998/05/01 01:33:59 ralf Exp $ +/* $Id: irixioctl.c,v 1.4 1998/03/04 12:17:41 ralf Exp $ * irixioctl.c: A fucking mess... * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irixsig.c linux/arch/mips/kernel/irixsig.c --- v2.1.125/linux/arch/mips/kernel/irixsig.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/irixsig.c Tue Oct 20 13:52:54 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: irixsig.c,v 1.8 1998/05/01 01:34:00 ralf Exp $ + * $Id: irixsig.c,v 1.11 1998/03/26 07:39:09 ralf Exp $ */ #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c --- v2.1.125/linux/arch/mips/kernel/irq.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/irq.c Tue Oct 20 13:52:54 1998 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.13 1998/05/08 01:44:12 ralf Exp $ +/* $Id: irq.c,v 1.13 1998/05/28 03:17:55 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -27,7 +27,6 @@ #include #include #include -#include unsigned char cache_21 = 0xff; unsigned char cache_A1 = 0xff; diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/mips_ksyms.c linux/arch/mips/kernel/mips_ksyms.c --- v2.1.125/linux/arch/mips/kernel/mips_ksyms.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/mips_ksyms.c Tue Oct 20 13:52:54 1998 @@ -1,13 +1,12 @@ -/* +/* $Id: mips_ksyms.c,v 1.12 1998/09/16 22:50:41 ralf Exp $ + * * Export MIPS-specific functions needed for loadable modules. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1997 by Ralf Baechle - * - * $Id: mips_ksyms.c,v 1.7 1998/05/04 09:17:52 ralf Exp $ + * Copyright (C) 1996, 1997, 1998 by Ralf Baechle */ #include #include @@ -27,6 +26,14 @@ #include #include +extern void *__bzero(void *__s, size_t __count); +extern long __strncpy_from_user_nocheck_asm(char *__to, + const char *__from, long __len); +extern long __strncpy_from_user_asm(char *__to, const char *__from, + long __len); +extern long __strlen_user_nocheck_asm(const char *s); +extern long __strlen_user_asm(const char *s); + EXPORT_SYMBOL(EISA_bus); /* @@ -48,11 +55,19 @@ EXPORT_SYMBOL(__mips_bh_counter); EXPORT_SYMBOL(local_bh_count); EXPORT_SYMBOL(local_irq_count); +//EXPORT_SYMBOL(enable_irq); +//EXPORT_SYMBOL(disable_irq); /* * Userspace access stuff. */ EXPORT_SYMBOL(__copy_user); +EXPORT_SYMBOL(__bzero); +EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm); +EXPORT_SYMBOL(__strncpy_from_user_asm); +EXPORT_SYMBOL(__strlen_user_nocheck_asm); +EXPORT_SYMBOL(__strlen_user_asm); + /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); @@ -61,7 +76,6 @@ * Functions to control caches. */ EXPORT_SYMBOL(flush_page_to_ram); -EXPORT_SYMBOL(fd_cacheflush); EXPORT_SYMBOL(flush_cache_all); /* diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/pci.c linux/arch/mips/kernel/pci.c --- v2.1.125/linux/arch/mips/kernel/pci.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/pci.c Tue Oct 20 13:52:54 1998 @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.11 1998/07/15 20:34:33 mj Exp $ +/* $Id: pci.c,v 1.6 1998/08/19 21:53:50 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -40,7 +40,7 @@ * each PCI chipset configuration. We just run the hook to the machine * specific implementation. */ -__initfunc(void pcibios_fixup (void)) +void pcibios_fixup (void) { return pci_ops->pcibios_fixup(); } @@ -79,6 +79,11 @@ unsigned char where, unsigned int val) { return pci_ops->pcibios_write_config_dword(bus, dev_fn, where, val); +} + +__initfunc(char *pcibios_setup(char *str)) +{ + return str; } __initfunc(void pcibios_fixup_bus(struct pci_bus *bus)) diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/proc.c linux/arch/mips/kernel/proc.c --- v2.1.125/linux/arch/mips/kernel/proc.c Wed Dec 10 10:31:09 1997 +++ linux/arch/mips/kernel/proc.c Tue Oct 20 13:52:54 1998 @@ -12,6 +12,7 @@ #include unsigned long unaligned_instructions; +unsigned int vced_count, vcei_count; /* * BUFFER is PAGE_SIZE bytes long. @@ -21,6 +22,7 @@ */ int get_cpuinfo(char *buffer) { + char fmt [64]; const char *cpu_name[] = CPU_NAMES; const char *mach_group_names[] = GROUP_NAMES; const char *mach_unknown_names[] = GROUP_UNKNOWN_NAMES; @@ -69,6 +71,11 @@ dedicated_iv_available ? "yes" : "no"); len += sprintf(buffer + len, "hardware watchpoint\t: %s\n", watch_available ? "yes" : "no"); + + sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", + vce_available ? "%d" : "not available"); + len += sprintf(buffer + len, fmt, 'D', vced_count); + len += sprintf(buffer + len, fmt, 'I', vcei_count); return len; } diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c --- v2.1.125/linux/arch/mips/kernel/process.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/process.c Tue Oct 20 13:52:54 1998 @@ -1,13 +1,10 @@ -/* - * linux/arch/mips/kernel/process.c +/* $Id: process.c,v 1.11 1998/08/17 12:14:53 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1994 - 1998 by Ralf Baechle and others. - * - * $Id: process.c,v 1.11 1998/05/15 13:04:01 davem Exp $ */ #include #include @@ -31,6 +28,8 @@ #include #include #include + +struct task_struct *last_task_used_math = NULL; asmlinkage void ret_from_sys_call(void); diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c --- v2.1.125/linux/arch/mips/kernel/ptrace.c Wed Sep 9 14:51:06 1998 +++ linux/arch/mips/kernel/ptrace.c Tue Oct 20 13:52:54 1998 @@ -1,8 +1,14 @@ -/* ptrace.c */ -/* By Ross Biro 1/23/92 */ -/* edited by Linus Torvalds */ -/* further hacked for MIPS by David S. Miller (dm@engr.sgi.com) */ - +/* $Id: ptrace.c,v 1.11 1998/10/19 16:26:31 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 Ross Biro + * Copyright (C) Linus Torvalds + * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle + * Copyright (C) 1996 David S. Miller + */ #include #include #include @@ -12,10 +18,12 @@ #include #include -#include +#include +#include #include #include #include +#include /* * This routine gets a long from any process space by following the page @@ -67,6 +75,7 @@ */ flush_cache_all(); retval = *(unsigned long *) page; + flush_cache_all(); /* VCED avoidance */ return retval; } @@ -121,10 +130,10 @@ } /* This is a hack for non-kernel-mapped video buffers and similar */ if (MAP_NR(page) < MAP_NR(high_memory)) - flush_cache_page(vma, addr); + flush_cache_all(); *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data; if (MAP_NR(page) < MAP_NR(high_memory)) - flush_page_to_ram(page); + flush_cache_all(); /* * We're bypassing pagetables, so we have to set the dirty bit * ourselves this should also re-instate whatever read-only mode @@ -324,163 +333,182 @@ } switch (request) { - /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ - case PTRACE_PEEKDATA: { - unsigned long tmp; + case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKDATA: { + unsigned long tmp; - res = read_long(child, addr, &tmp); - if (res < 0) - goto out; - res = put_user(tmp,(unsigned long *) data); + res = read_long(child, addr, &tmp); + if (res < 0) goto out; + res = put_user(tmp,(unsigned long *) data); + goto out; } /* read the word at location addr in the USER area. */ /* #define DEBUG_PEEKUSR */ - case PTRACE_PEEKUSR: { - struct pt_regs *regs; - unsigned long tmp; - - regs = (struct pt_regs *) ((unsigned long) child + - KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); - tmp = 0; /* Default return value. */ - if(addr < 32 && addr >= 0) { - tmp = regs->regs[addr]; - } else if(addr >= 32 && addr < 64) { - unsigned long long *fregs; - - /* We don't want to do a FPU operation here. */ + case PTRACE_PEEKUSR: { + struct pt_regs *regs; + unsigned long tmp; + + regs = (struct pt_regs *) ((unsigned long) child + + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); + tmp = 0; /* Default return value. */ + if (addr < 32 && addr >= 0) + tmp = regs->regs[addr]; + else if (addr >= 32 && addr < 64) { + unsigned long long *fregs; + + if (child->used_math) { + if (last_task_used_math == child) { + enable_cp1(); + r4xx0_save_fp(child); + disable_cp1(); + last_task_used_math = NULL; + } fregs = (unsigned long long *) &child->tss.fpu.hard.fp_regs[0]; tmp = (unsigned long) fregs[(addr - 32)]; } else { - addr -= 64; - switch(addr) { - case 0: - tmp = regs->cp0_epc; - break; - case 1: - tmp = regs->cp0_cause; - break; - case 2: - tmp = regs->cp0_badvaddr; - break; - case 3: - tmp = regs->lo; - break; - case 4: - tmp = regs->hi; - break; - case 5: - tmp = child->tss.fpu.hard.control; - break; - case 6: /* implementation / version register */ - tmp = 0; - break; - default: - tmp = 0; - res = -EIO; - goto out; - }; + tmp = -1; /* FP not yet used */ + } + } else { + addr -= 64; + switch(addr) { + case 0: + tmp = regs->cp0_epc; + break; + case 1: + tmp = regs->cp0_cause; + break; + case 2: + tmp = regs->cp0_badvaddr; + break; + case 3: + tmp = regs->lo; + break; + case 4: + tmp = regs->hi; + break; + case 5: + tmp = child->tss.fpu.hard.control; + break; + case 6: /* implementation / version register */ + tmp = 0; /* XXX */ + break; + default: + tmp = 0; + res = -EIO; + goto out; } - res = put_user(tmp, (unsigned long *) data); - goto out; + } + res = put_user(tmp, (unsigned long *) data); + goto out; } - /* when I and D space are separate, this will have to be fixed. */ - case PTRACE_POKETEXT: /* write the word at location addr. */ - case PTRACE_POKEDATA: - res = write_long(child,addr,data); - goto out; - - case PTRACE_POKEUSR: { - struct pt_regs *regs; - int res = 0; - - regs = (struct pt_regs *) ((unsigned long) child + - KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); - if(addr < 32 && addr >= 0) { - regs->regs[addr] = data; - } else if(addr >= 32 && addr < 64) { - unsigned long long *fregs; + case PTRACE_POKETEXT: /* write the word at location addr. */ + case PTRACE_POKEDATA: + res = write_long(child,addr,data); + goto out; - /* We don't want to do a FPU operation here. */ - fregs = (unsigned long long *) - &child->tss.fpu.hard.fp_regs[0]; - fregs[(addr - 32)] = (unsigned long long) data; + case PTRACE_POKEUSR: { + struct pt_regs *regs; + int res = 0; + + regs = (struct pt_regs *) ((unsigned long) child + + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); + if (addr < 32 && addr >= 0) + regs->regs[addr] = data; + else if (addr >= 32 && addr < 64) { + unsigned long long *fregs; + + if (child->used_math) { + if (last_task_used_math == child) { + enable_cp1(); + r4xx0_save_fp(child); + disable_cp1(); + last_task_used_math = NULL; + } } else { - addr -= 64; - switch(addr) { - case 0: - regs->cp0_epc = data; - break; - case 3: - regs->lo = data; - break; - case 4: - regs->hi = data; - break; - case 5: - child->tss.fpu.hard.control = data; - break; - default: - /* The rest are not allowed. */ - res = -EIO; - break; - }; + /* FP not yet used */ + memset(&child->tss.fpu.hard, ~0, + sizeof(child->tss.fpu.hard)); + child->tss.fpu.hard.control = 0; } - goto out; - } - - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: { /* restart after signal. */ - if ((unsigned long) data > _NSIG) { + fregs = (unsigned long long *) + &child->tss.fpu.hard.fp_regs[0]; + fregs[(addr - 32)] = (unsigned long long) data; + } else { + addr -= 64; + switch (addr) { + case 0: + regs->cp0_epc = data; + break; + case 3: + regs->lo = data; + break; + case 4: + regs->hi = data; + break; + case 5: + child->tss.fpu.hard.control = data; + break; + default: + /* The rest are not allowed. */ res = -EIO; - goto out; - } - if (request == PTRACE_SYSCALL) - child->flags |= PF_TRACESYS; - else - child->flags &= ~PF_TRACESYS; - child->exit_code = data; - wake_up_process(child); - res = data; - goto out; + break; + }; + } + goto out; } -/* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to - * exit. - */ - case PTRACE_KILL: { - if (child->state != TASK_ZOMBIE) { - wake_up_process(child); - child->exit_code = SIGKILL; - } - res = 0; + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ + case PTRACE_CONT: { /* restart after signal. */ + if ((unsigned long) data > _NSIG) { + res = -EIO; goto out; } + if (request == PTRACE_SYSCALL) + child->flags |= PF_TRACESYS; + else + child->flags &= ~PF_TRACESYS; + child->exit_code = data; + wake_up_process(child); + res = data; + goto out; + } - case PTRACE_DETACH: { /* detach a process that was attached. */ - if ((unsigned long) data > _NSIG) { - res = -EIO; - goto out; - } - child->flags &= ~(PF_PTRACED|PF_TRACESYS); + /* + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to + * exit. + */ + case PTRACE_KILL: { + if (child->state != TASK_ZOMBIE) { + child->exit_code = SIGKILL; wake_up_process(child); - child->exit_code = data; - REMOVE_LINKS(child); - child->p_pptr = child->p_opptr; - SET_LINKS(child); - res = 0; - goto out; + } + res = 0; + goto out; } - default: + case PTRACE_DETACH: { /* detach a process that was attached. */ + if ((unsigned long) data > _NSIG) { res = -EIO; goto out; + } + child->flags &= ~(PF_PTRACED|PF_TRACESYS); + child->exit_code = data; + REMOVE_LINKS(child); + child->p_pptr = child->p_opptr; + SET_LINKS(child); + wake_up_process(child); + res = 0; + goto out; + } + + default: + res = -EIO; + goto out; } out: unlock_kernel(); diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r2300_fpu.S linux/arch/mips/kernel/r2300_fpu.S --- v2.1.125/linux/arch/mips/kernel/r2300_fpu.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/r2300_fpu.S Tue Oct 20 13:52:54 1998 @@ -10,7 +10,7 @@ * Multi-arch abstraction and asm macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r2300_fpu.S,v 1.4 1998/05/01 01:34:08 ralf Exp $ + * $Id: r2300_fpu.S,v 1.3 1997/12/01 16:54:20 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r2300_misc.S linux/arch/mips/kernel/r2300_misc.S --- v2.1.125/linux/arch/mips/kernel/r2300_misc.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/r2300_misc.S Tue Oct 20 13:52:54 1998 @@ -1,4 +1,4 @@ -/* $Id: r2300_misc.S,v 1.2 1998/05/01 01:34:10 ralf Exp $ +/* $Id: r2300_misc.S,v 1.1.1.1 1997/06/01 03:16:42 ralf Exp $ * r2300_misc.S: Misc. exception handling code for R3000/R2000. * * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r2300_switch.S linux/arch/mips/kernel/r2300_switch.S --- v2.1.125/linux/arch/mips/kernel/r2300_switch.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/r2300_switch.S Tue Oct 20 13:52:54 1998 @@ -6,7 +6,7 @@ * Multi-cpu abstraction and macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r2300_switch.S,v 1.2 1998/05/01 01:34:14 ralf Exp $ + * $Id: r2300_switch.S,v 1.4 1998/04/04 13:59:38 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r4k_fpu.S linux/arch/mips/kernel/r4k_fpu.S --- v2.1.125/linux/arch/mips/kernel/r4k_fpu.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/r4k_fpu.S Tue Oct 20 13:52:54 1998 @@ -10,7 +10,7 @@ * Multi-arch abstraction and asm macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r4k_fpu.S,v 1.4 1998/05/01 01:34:15 ralf Exp $ + * $Id: r4k_fpu.S,v 1.4 1998/04/04 13:59:38 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r4k_misc.S linux/arch/mips/kernel/r4k_misc.S --- v2.1.125/linux/arch/mips/kernel/r4k_misc.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/r4k_misc.S Tue Oct 20 13:52:54 1998 @@ -6,7 +6,7 @@ * Multi-cpu abstraction and reworking: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r4k_misc.S,v 1.4 1998/05/01 01:34:17 ralf Exp $ + * $Id: r4k_misc.S,v 1.3 1997/09/07 04:51:07 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r4k_switch.S linux/arch/mips/kernel/r4k_switch.S --- v2.1.125/linux/arch/mips/kernel/r4k_switch.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/r4k_switch.S Tue Oct 20 13:52:54 1998 @@ -1,12 +1,12 @@ -/* - * r4k_switch.S: R4xx0 specific task switching code. +/* $Id: r4k_switch.S,v 1.4 1998/07/14 09:15:33 ralf Exp $ * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * Multi-cpu abstraction and macros for easier reading: + * Copyright (C) 1994, 1995, 1996, 1998 by Ralf Baechle * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: r4k_switch.S,v 1.2 1998/05/01 01:34:19 ralf Exp $ + * Copyright (C) 1994, 1995, 1996, by Andreas Busse */ #include #include @@ -28,12 +28,8 @@ .set mips3 .align 5 LEAF(r4xx0_resume) - mfc0 t1, CP0_STATUS # fp exception boundary - sll t0, t1, 2 - bgez t0, 1f - nop - cfc1 zero, fcr31 -1: sw t1, THREAD_STATUS($28) + mfc0 t1, CP0_STATUS + sw t1, THREAD_STATUS($28) CPU_SAVE_NONSCRATCH($28) sw ra, THREAD_REG31($28) @@ -114,7 +110,7 @@ * We initialize fcr31 to rounding to nearest, no exceptions. */ -#define FPU_DEFAULT 0x00000600 +#define FPU_DEFAULT 0x00000000 LEAF(r4xx0_init_fpu) mfc0 t0, CP0_STATUS diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/r6000_fpu.S linux/arch/mips/kernel/r6000_fpu.S --- v2.1.125/linux/arch/mips/kernel/r6000_fpu.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/r6000_fpu.S Tue Oct 20 13:52:54 1998 @@ -10,7 +10,7 @@ * Multi-arch abstraction and asm macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r6000_fpu.S,v 1.4 1998/05/01 01:34:20 ralf Exp $ + * $Id: r6000_fpu.S,v 1.3 1997/12/01 16:56:56 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/scall_o32.S linux/arch/mips/kernel/scall_o32.S --- v2.1.125/linux/arch/mips/kernel/scall_o32.S Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/scall_o32.S Tue Oct 20 13:52:54 1998 @@ -1,13 +1,10 @@ -/* - * arch/mips/kernel/scall_o32.S +/* $Id: scall_o32.S,v 1.5 1998/08/19 21:53:50 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1997, 1998 by Ralf Baechle - * - * $Id: scall_o32.S,v 1.2 1998/07/26 03:02:07 davem Exp $ */ #include #include @@ -73,8 +70,7 @@ 9: lw t0,PT_STATUS(sp) # returning to kernel mode? andi t1, t0, 0x10 -#error Change this to current->need_resched --DaveM - lw t2, need_resched + lw t2, TASK_NEED_RESCHED($28) beqz t1, o32_return # -> yes bnez t2, o32_reschedule lw v0, TASK_SIGPENDING($28) @@ -105,9 +101,13 @@ SAVE_STATIC sw t2,PT_R1(sp) jal syscall_trace - sw t2,PT_R1(sp) + lw t2,PT_R1(sp) - jalr t2 # Do The Real Thing (TM) + lw a0, PT_R4(sp) # Restore argument registers + lw a1, PT_R5(sp) + lw a2, PT_R6(sp) + lw a3, PT_R7(sp) + jalr t2 li t0, -EMAXERRNO - 1 # error? sltu t0, t0, v0 diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c --- v2.1.125/linux/arch/mips/kernel/setup.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/setup.c Tue Oct 20 13:52:54 1998 @@ -1,11 +1,12 @@ -/* - * linux/arch/mips/kernel/setup.c +/* $Id: setup.c,v 1.12 1998/08/18 20:45:06 ralf Exp $ * - * Copyright (C) 1995 Linus Torvalds - * Copyright (C) 1995, 1996 Ralf Baechle - * Copyright (C) 1996 Stoned Elipot + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * $Id: setup.c,v 1.10 1998/06/10 07:21:10 davem Exp $ + * Copyright (C) 1995 Linus Torvalds + * Copyright (C) 1995, 1996, 1997, 1998 Ralf Baechle + * Copyright (C) 1996 Stoned Elipot */ #include #include @@ -37,23 +38,13 @@ #include #include #include -#include #include #include #ifdef CONFIG_SGI #include #endif -/* - * How to handle the machine's features - */ -struct feature *feature; - -/* - * What to do to keep the caches consistent with memory - * We don't use the normal cacheflush routine to keep Tyne caches happier. - */ -void (*fd_cacheflush)(const void *addr, size_t size); +struct mips_cpuinfo boot_cpu_data = { NULL, NULL, 0 }; /* * Not all of the MIPS CPUs have the "wait" instruction available. This @@ -88,13 +79,21 @@ struct drive_info_struct drive_info = DEFAULT_DRIVE_INFO; struct screen_info screen_info = DEFAULT_SCREEN_INFO; +#ifdef CONFIG_BLK_DEV_FD +extern struct fd_ops no_fd_ops; +struct fd_ops *fd_ops; +#endif + #ifdef CONFIG_BLK_DEV_IDE extern struct ide_ops no_ide_ops; struct ide_ops *ide_ops; #endif +extern struct rtc_ops no_rtc_ops; +struct rtc_ops *rtc_ops; + /* - * setup informations + * Setup information * * These are intialized so they are in the .data section */ @@ -150,15 +149,12 @@ panic("Unknown machtype in init_IRQ"); } -__initfunc(static void default_fd_cacheflush(const void *addr, size_t size)) -{ -} - __initfunc(void setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)) { unsigned long memory_end; tag* atag; + void cobalt_setup(void); void decstation_setup(void); void deskstation_setup(void); void jazz_setup(void); @@ -179,13 +175,24 @@ /* Save defaults for configuration-dependent routines. */ irq_setup = default_irq_setup; - fd_cacheflush = default_fd_cacheflush; + +#ifdef CONFIG_BLK_DEV_FD + fd_ops = &no_fd_ops; +#endif + #ifdef CONFIG_BLK_DEV_IDE ide_ops = &no_ide_ops; #endif + rtc_ops = &no_rtc_ops; + switch(mips_machgroup) { +#ifdef CONFIG_COBALT_MICRO_SERVER + case MACH_GROUP_COBALT: + cobalt_setup(); + break; +#endif #ifdef CONFIG_MIPS_JAZZ case MACH_GROUP_JAZZ: jazz_setup(); diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/signal.c linux/arch/mips/kernel/signal.c --- v2.1.125/linux/arch/mips/kernel/signal.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/signal.c Tue Oct 20 13:52:54 1998 @@ -1,10 +1,9 @@ -/* +/* $Id: signal.c,v 1.24 1998/09/16 22:50:42 ralf Exp $ + * * linux/arch/mips/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 1994, 1995, 1996 Ralf Baechle - * - * $Id: signal.c,v 1.13 1998/06/10 07:21:12 davem Exp $ + * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle * * XXX Handle lazy fp context switches correctly. */ @@ -23,6 +22,7 @@ #include #include #include +#include #include #define DEBUG_SIG 0 @@ -43,6 +43,7 @@ { sigset_t *uset, saveset, newset; + save_static(®s); uset = (sigset_t *) regs.regs[4]; if (copy_from_user(&newset, uset, sizeof(sigset_t))) return -EFAULT; @@ -53,7 +54,8 @@ current->blocked = newset; spin_unlock_irq(¤t->sigmask_lock); - regs.regs[2] = -EINTR; + regs.regs[2] = EINTR; + regs.regs[7] = 1; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); @@ -67,6 +69,7 @@ { sigset_t *uset, saveset, newset; + save_static(®s); uset = (sigset_t *) regs.regs[4]; if (copy_from_user(&newset, uset, sizeof(sigset_t))) return -EFAULT; @@ -77,7 +80,8 @@ current->blocked = newset; spin_unlock_irq(¤t->sigmask_lock); - regs.regs[2] = -EINTR; + regs.regs[2] = EINTR; + regs.regs[7] = 1; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); @@ -116,6 +120,14 @@ } return ret; +} + +asmlinkage int +sys_sigaltstack(const stack_t *uss, stack_t *uoss) +{ + struct pt_regs *regs = (struct pt_regs *) &uss; + + return do_sigaltstack(uss, uoss, regs->regs[29]); } /* diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/softfp.S linux/arch/mips/kernel/softfp.S --- v2.1.125/linux/arch/mips/kernel/softfp.S Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/kernel/softfp.S Tue Oct 20 13:52:54 1998 @@ -0,0 +1,667 @@ +/* $Id: softfp.S,v 1.1 1998/07/14 09:33:48 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1998 by Ralf Baechle + * + * For now it's just a crude hack good enough to run certain fp programs like + * Mozilla. + * XXX: Handle MIPS II/III/IV/V enhancements, exceptions, ... + */ +#include +#include + +#ifndef __KERNEL__ +#define printk printf +#endif + +#define LOCK_KERNEL +#define UNLOCK_KERNEL + +/* + * This duplicates definitions from . + */ +#define KERN_EMERG "<0>" /* system is unusable */ +#define KERN_ALERT "<1>" /* action must be taken immediately */ +#define KERN_CRIT "<2>" /* critical conditions */ +#define KERN_ERR "<3>" /* error conditions */ +#define KERN_WARNING "<4>" /* warning conditions */ +#define KERN_NOTICE "<5>" /* normal but significant condition */ +#define KERN_INFO "<6>" /* informational */ +#define KERN_DEBUG "<7>" /* debug-level messages */ + +/* + * This duplicates definitions from + */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ + +/* + * Definitions about the instruction format + */ +#define fd_shift 6 +#define fr_shift 21 +#define fs_shift 11 +#define ft_shift 16 + +/* + * NaNs as use by the MIPS architecture + */ +#define S_QNaN 0x7fbfffff +#define D_QNaN 0x7ff7ffffffffffff +#define W_QNaN 0x7fffffff +#define L_QNaN 0x7fffffffffffffff + +/* + * Checking for NaNs + */ +#define S_is_QNaN(reg,res) \ + sll res, reg, S_F_size - S_F_bits +#define D_is_QNaN(reg1,reg2,res) \ + sll res, reg1, (D_F_size - 32) - (D_F_bits - 32); \ + or res, reg2 + +/* + * Checking for Denorms + */ +#define S_is_Denorm(reg,res) \ + li res, 1 << (S_F_bits - 1); \ + and reg, res + +/* + * Some constants that define the properties of single precission numbers. + */ +#define S_M_prec 24 +#define S_E_max 127 +#define S_E_min -126 +#define S_E_bias 127 +#define S_E_bits 8 +#define S_F_bits 23 +#define S_F_size 32 + +/* Set temp0, if exponent of reg is S_E_max + 1. */ +#define S_is_E_max(reg,temp0,temp1) \ + li temp0, (S_E_max + 1 + S_E_bias) << S_F_bits; \ + and temp1, temp0, reg; \ + seq temp0, temp1 /* temp0 != 0 if NaN */ + +/* Clear temp0, if exponent of reg is S_E_min - 1. */ +#define S_is_E_min(reg,temp0) \ + li temp0, (S_E_min - 1 + S_E_bias) << S_F_bits; \ + and temp0, reg /* temp0 == 0 if denorm or zero */ + +/* Set temp0 if reg is a NaN assuming S_is_E_max is true */ +#define S_get_F(reg,temp0) \ + li temp0, (1 << S_F_bits) - 1; \ + and temp0, reg /* temp0 != 0 if NaN */ + +/* Set res if fraction of reg is != 0. */ +#define S_is_Inf(reg,res) \ + li res, (1 << S_F_bits) - 1; \ + and res, reg /* temp0 == 0 if Inf */ + + +/* + * Some constants that define the properties of double precission numbers. + */ +#define D_M_prec 53 +#define D_E_max 1023 +#define D_E_min -1022 +#define D_E_bias 1023 +#define D_E_bits 8 +#define D_F_bits 52 +#define D_F_size 64 + +/* Set temp0, if exponent of reg1/reg2 is D_E_max. */ +#define D_is_E_max(reg1,reg2,temp0,temp1) \ + li temp0, (D_E_max + 1 + D_E_bias) << (D_F_bits - 32); \ + and temp1, temp0, reg1; \ + seq temp0, temp1 /* temp0 != 0 if NaN */ + +/* Clear temp0, if exponent of reg is D_E_min. */ +#define D_is_E_min(reg1,reg2,res) \ + li res, (D_E_min + 1 + D_E_bias) << (D_F_bits - 32); \ + and res, reg1 /* temp0 == 0 if NaN or zero */ + +/* Set res if reg is a NaN assuming S_is_E_max is true */ +#define D_get_F(reg1,reg2,res) \ + li res, (1 << (D_F_bits - 32)) - 1; \ + and res, reg1 /* temp0 != 0 if NaN */ + +/* Set temp0 if reg1/reg2 is a NaN */ +#define D_is_NAN(reg1,reg2,temp0,temp1) \ + li temp0, (1 << (D_F_bits - 32) - 1; \ + and temp0, reg1; \ + or temp0, reg2; \ + sne temp0, zero, temp0 /* temp0 != 0 if NaN */ + +/* Set res if fraction of reg1/reg2 is != 0. */ +#define D_is_Inf(reg1,reg2,res) \ + li res, (1 << (D_F_bits - 32)) - 1; \ + and res, reg1; \ + or res, reg2 /* temp0 == 0 if Inf */ + +/* Complain about yet unhandled instruction. */ +#define BITCH(insn) \ +insn: LOCK_KERNEL; \ + la a1, 8f; \ + TEXT(#insn); \ + la a1, nosim; \ + UNLOCK_KERNEL; \ + j done + + .data +nosim: .asciz KERN_DEBUG "Don't know how to simulate %s instruction\n" + .previous + +/* + * When we come here, we've saved some of the integer registers and + * reenabled interrupts. + */ +LEAF(simfp) + .set noreorder + .cpload $25 + .set reorder + + subu sp, 16 + .cprestore 20 + sw ra, 16(sp) + + /* For now we assume that we get the opcode to simulate passed in as + an argument. */ + move t0, a0 + + /* + * First table lookup using insn[5:0] + */ + la t1, lowtab + andi t2, t0, 0x3f + sll t2, t2, 2 + addu t1, t2 + lw t1, (t1) + jr t1 + END(simfp) + +/* + * We only decode the lower 3 of the 5 bit in the fmt field. That way we + * can keep the jump table significantly shorter. + */ +#define FMT_switch(insn,opc,temp0,temp1) \ +insn: srl temp0, opc, 19; \ + andi temp0, 0x1c; \ + la temp1, insn ## .tab; \ + addu temp0, temp1; \ + lw temp0, (temp0); \ + jr temp0; \ + \ + .data; \ +insn ## .tab: \ + .word insn ## .s, insn ## .d, unimp, unimp; \ + .word insn ## .w, insn ## .l, unimp, unimp; \ + .previous + + BITCH(add) + BITCH(sub) + BITCH(mul) + BITCH(div) + BITCH(sqrt) + BITCH(abs) + BITCH(mov) + BITCH(neg) + BITCH(round.l) + BITCH(trunc.l) + BITCH(ceil.l) + BITCH(floor.l) + BITCH(round.w) + BITCH(trunc.w) + BITCH(ceil.w) + BITCH(floor.w) + BITCH(cvt.s) + BITCH(cvt.d) + +/* ------------------------------------------------------------------------ */ + +FMT_switch(cvt.w,t0,t1,t2) + +/* Convert a single fp to a fixed point integer. */ +cvt.w.s: + srl t1, t0, fs_shift # Get source register + andi t1, 31 + jal s_get_fpreg + + S_is_E_max(t1,t2,t3) + beqz t2, 3f + /* Might be a NaN or Inf. */ + S_get_F(t1,t2) + beqz t2, 2f + + /* It's a NaN. IEEE says undefined. */ + /* Is it a QNaN? Then the result is a QNaN as well. */ + S_is_QNaN(t1,t2) + bltz t2, 1f + + /* XXX Ok, it's a SNaN. Signal invalid exception, if enabled. + For now we don't signal and supply a QNaN for result. */ + +1: li t2, W_QNaN + srl t1, t0, fd_shift # Put result register + andi t1, 31 + jal s_put_fpreg + j done +2: + + S_is_Inf(t1,t2) + bnez t2, 2f + + /* It's +/- Inf. Set register to +/- max. integer. */ + /* XXX Send invalid operation exception instead, if enabled. */ + srl t1, t1, 31 # Extract sign bit + li t2, 0x7fffffff + addu t2, t1 + + srl t1, t0, fd_shift # Put result register + andi t1, 31 + jal s_put_fpreg + j done +2: +3: + + /* But then it might be a denorm or zero? */ + S_is_E_min(t1,t2) + bnez t2, 2f + + /* Ok, it's a denorm or zero. */ + S_get_F(t1,t2) + beqz t2, 1f + + /* It's a denorm. */ + /* XXX Should be signaling inexact exception, if enabled. */ + /* Fall through. */ +1: + /* Yes, it is a denorm or zero. Supply a zero as result. */ + move t2, zero + srl t1, t0, fd_shift # Put result register + andi t1, 31 + jal s_put_fpreg + j done +2: + + /* XXX Ok, it's a normal number. We don't handle that case yet. + If we have fp hardware this case is unreached. Add this for + full fp simulation. */ + + /* Done, return. */ + lw ra, 16(sp) + addu sp, 16 + jr ra + +/* Convert a double fp to a fixed point integer. */ +cvt.w.d: + srl t1, t0, fs_shift # Get source register + andi t1, 31 + jal d_get_fpreg + + D_is_E_max(t1,t2,t3,t4) + beqz t3, 3f + + /* Might be a NaN or Inf. */ + D_get_F(t1,t2,t3) + or t3, t2 + beqz t3, 2f + + /* It's a NaN. IEEE says undefined. */ + /* Is it a QNaN? Then the result is a QNaN as well. */ + D_is_QNaN(t1,t2,t3) + bltz t3, 1f + + /* XXX Ok, it's a SNaN. Signal invalid exception, if enabled. + For now we don't signal and supply a QNaN for result. */ + +1: li t2, W_QNaN + srl t1, t0, fd_shift # Put result register + andi t1, 31 + jal s_put_fpreg + j done +2: + + D_is_Inf(t1,t2,t3) + bnez t3, 2f + + /* It's +/- Inf. Set register to +/- max. integer. */ + /* XXX Send invalid operation exception instead, if enabled. */ + srl t1, t1, 31 # Extract sign bit + li t2, 0x7fffffff + addu t2, t1 + + srl t1, t0, fd_shift # Put result register + andi t1, 31 + jal s_put_fpreg + j done +2: +3: + + /* But then it might be a denorm or zero? */ + D_is_E_min(t1,t2,t3) + bnez t3, 2f + + /* Ok, it's a denorm or zero. */ + D_get_F(t1,t2,t3) + or t3, t2 + beqz t3, 1f + + /* It's a denorm. */ + /* XXX Should be signaling inexact exception, if enabled. */ + /* Fall through. */ +1: + /* Yes, it is a denorm or zero. Supply a zero as result. */ + move t2, zero + srl t1, t0, fd_shift # Put result register + andi t1, 31 + jal s_put_fpreg + j done +2: + + /* XXX Ok, it's a normal number. We don't handle that case yet. + If we have fp hardware this case is only reached if the value + of the source register exceeds the range which is representable + in a single precission register. For now we kludge by returning + +/- maxint and don't signal overflow. */ + + srl t1, t1, 31 # Extract sign bit + li t2, 0x7fffffff + addu t2, t1 + + srl t1, t0, fd_shift # Put result register + andi t1, 31 + jal s_put_fpreg + + /* Done, return. */ + lw ra, 16(sp) + addu sp, 16 + jr ra + +cvt.w.w = unimp # undefined result +cvt.w.l = unimp # undefined result + +/* MIPS III extension, no need to handle for 32bit OS. */ +cvt.l = unimp + +/* ------------------------------------------------------------------------ */ + + BITCH(c.f) + BITCH(c.un) + BITCH(c.eq) + BITCH(c.ueq) + BITCH(c.olt) + BITCH(c.ult) + BITCH(c.ole) + BITCH(c.ule) + BITCH(c.sf) + BITCH(c.ngle) + BITCH(c.seq) + BITCH(c.ngl) + BITCH(c.lt) + BITCH(c.nge) + BITCH(c.le) + BITCH(c.ngt) + +/* Get the single precission register which's number is in t1. */ +s_get_fpreg: + .set noat + sll AT, t1, 2 + sll t1, 3 + addu t1, AT + la AT, 1f + addu AT, t1 + jr AT + .set at + +1: mfc1 t1, $0 + jr ra + mfc1 t1, $1 + jr ra + mfc1 t1, $2 + jr ra + mfc1 t1, $3 + jr ra + mfc1 t1, $4 + jr ra + mfc1 t1, $5 + jr ra + mfc1 t1, $6 + jr ra + mfc1 t1, $7 + jr ra + mfc1 t1, $8 + jr ra + mfc1 t1, $9 + jr ra + mfc1 t1, $10 + jr ra + mfc1 t1, $11 + jr ra + mfc1 t1, $12 + jr ra + mfc1 t1, $13 + jr ra + mfc1 t1, $14 + jr ra + mfc1 t1, $15 + jr ra + mfc1 t1, $16 + jr ra + mfc1 t1, $17 + jr ra + mfc1 t1, $18 + jr ra + mfc1 t1, $19 + jr ra + mfc1 t1, $20 + jr ra + mfc1 t1, $21 + jr ra + mfc1 t1, $22 + jr ra + mfc1 t1, $23 + jr ra + mfc1 t1, $24 + jr ra + mfc1 t1, $25 + jr ra + mfc1 t1, $26 + jr ra + mfc1 t1, $27 + jr ra + mfc1 t1, $28 + jr ra + mfc1 t1, $29 + jr ra + mfc1 t1, $30 + jr ra + mfc1 t1, $31 + jr ra + +/* + * Put the value in t2 into the single precission register which's number + * is in t1. + */ +s_put_fpreg: + .set noat + sll AT, t1, 2 + sll t1, 3 + addu t1, AT + la AT, 1f + addu AT, t1 + jr AT + .set at + +1: mtc1 t2, $0 + jr ra + mtc1 t2, $1 + jr ra + mtc1 t2, $2 + jr ra + mtc1 t2, $3 + jr ra + mtc1 t2, $4 + jr ra + mtc1 t2, $5 + jr ra + mtc1 t2, $6 + jr ra + mtc1 t2, $7 + jr ra + mtc1 t2, $8 + jr ra + mtc1 t2, $9 + jr ra + mtc1 t2, $10 + jr ra + mtc1 t2, $11 + jr ra + mtc1 t2, $12 + jr ra + mtc1 t2, $13 + jr ra + mtc1 t2, $14 + jr ra + mtc1 t2, $15 + jr ra + mtc1 t2, $16 + jr ra + mtc1 t2, $17 + jr ra + mtc1 t2, $18 + jr ra + mtc1 t2, $19 + jr ra + mtc1 t2, $20 + jr ra + mtc1 t2, $21 + jr ra + mtc1 t2, $22 + jr ra + mtc1 t2, $23 + jr ra + mtc1 t2, $24 + jr ra + mtc1 t2, $25 + jr ra + mtc1 t2, $26 + jr ra + mtc1 t2, $27 + jr ra + mtc1 t2, $28 + jr ra + mtc1 t2, $29 + jr ra + mtc1 t2, $30 + jr ra + mtc1 t2, $31 + jr ra + +/* Get the double precission register which's number is in t1 into t1/t2. */ +d_get_fpreg: + .set noat + sll t1, 3 + la AT, 1f + addu AT, t1 + jr AT + .set at + +1: mfc1 t1, $0 + mfc1 t2, $1 + jr ra + mfc1 t1, $2 + mfc1 t2, $3 + jr ra + mfc1 t1, $4 + mfc1 t2, $5 + jr ra + mfc1 t1, $6 + mfc1 t2, $7 + jr ra + mfc1 t1, $8 + mfc1 t2, $9 + jr ra + mfc1 t1, $10 + mfc1 t2, $11 + jr ra + mfc1 t1, $12 + mfc1 t2, $13 + jr ra + mfc1 t1, $14 + mfc1 t2, $15 + jr ra + mfc1 t1, $16 + mfc1 t2, $17 + jr ra + mfc1 t1, $18 + mfc1 t2, $19 + jr ra + mfc1 t1, $20 + mfc1 t2, $21 + jr ra + mfc1 t1, $22 + mfc1 t2, $23 + jr ra + mfc1 t1, $24 + mfc1 t2, $25 + jr ra + mfc1 t1, $26 + mfc1 t2, $27 + jr ra + mfc1 t1, $28 + mfc1 t2, $29 + jr ra + mfc1 t1, $30 + mfc1 t2, $31 + jr ra + +/* + * Send an invalid operation exception. + */ +invalid: + lw ra, 16(sp) + addu sp, 16 + jr ra + +/* + * Done, just skip over the current instruction + */ +done: + lw ra, 16(sp) + addu sp, 16 + jr ra + +unimp: + /* We've run into an yet unknown instruction. This happens either + on new, yet unsupported CPU types or when the faulting instruction + is being executed for cache but has been overwritten in memory. */ + LOCK_KERNEL + move a0, t0 + PRINT(KERN_DEBUG "FP support: unknown fp op %08lx, ") + PRINT("please mail to ralf@gnu.org.\n") + + li a0, SIGILL # Die, sucker ... + move a1, $28 + jal force_sig + UNLOCK_KERNEL + + lw ra, 16(sp) + addu sp, 16 + jr ra + +/* + * Jump table for the lowest 6 bits of a cp1 instruction. + */ + .data +lowtab: .word add, sub, mul, div, sqrt, abs, mov, neg + .word round.l,trunc.l,ceil.l,floor.l,round.w,trunc.w,ceil.w,floor.w + .word unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp + .word unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp + .word cvt.s, cvt.d, unimp, unimp, cvt.w, cvt.l, unimp, unimp + .word unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp + .word c.f, c.un, c.eq, c.ueq, c.olt, c.ult, c.ole, c.ule + .word c.sf, c.ngle,c.seq, c.ngl, c.lt, c.nge, c.le, c.ngt diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/syscall.c linux/arch/mips/kernel/syscall.c --- v2.1.125/linux/arch/mips/kernel/syscall.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/syscall.c Tue Oct 20 13:52:54 1998 @@ -1,17 +1,14 @@ -/* - * MIPS specific syscall handling functions and syscalls +/* $Id: syscall.c,v 1.10 1998/08/20 14:38:40 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1996 by Ralf Baechle + * Copyright (C) 1995 - 1998 by Ralf Baechle * * TODO: Implement the compatibility syscalls. * Don't waste that much memory for empty entries in the syscall * table. - * - * $Id: syscall.c,v 1.12 1998/07/26 03:02:09 davem Exp $ */ #undef CONF_PRINT_SYSCALLS #undef CONF_DEBUG_IRIX @@ -82,14 +79,15 @@ asmlinkage int sys_idle(void) { + unsigned long start_idle = 0; int ret = -EPERM; lock_kernel(); if (current->pid != 0) goto out; /* endless idle loop with no priority at all */ - current->priority = -100; - current->counter = -100; + current->priority = 0; + current->counter = 0; for (;;) { /* * R4[36]00 have wait, R4[04]00 don't. @@ -99,13 +97,20 @@ * same for logic clocked with the processor generated * clocks. */ + if (!start_idle) { + check_pgt_cache(); + start_idle = jiffies; + } if (wait_available && !current->need_resched) __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); run_task_queue(&tq_scheduler); + if (current->need_resched) + start_idle = 0; schedule(); } + ret = 0; out: unlock_kernel(); return ret; diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/syscalls.h linux/arch/mips/kernel/syscalls.h --- v2.1.125/linux/arch/mips/kernel/syscalls.h Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/syscalls.h Tue Oct 20 13:52:54 1998 @@ -1,13 +1,10 @@ -/* - * List of Linux/MIPS syscalls. +/* $Id: syscalls.h,v 1.16 1998/09/16 22:50:43 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1996 by Ralf Baechle - * - * $Id: syscalls.h,v 1.14 1998/05/07 00:39:37 ralf Exp $ + * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle */ /* @@ -16,7 +13,7 @@ * accepts. Syscalls that receive a pointer to the saved registers are * marked as having zero arguments. * - * The binary compatibility calls are still missing in this list. + * The binary compatibility calls are in a separate list. */ SYS(sys_syscall, 0) /* 4000 */ SYS(sys_exit, 1) @@ -40,7 +37,7 @@ SYS(sys_lseek, 3) SYS(sys_getpid, 0) /* 4020 */ SYS(sys_mount, 5) -SYS(sys_umount, 1) +SYS(sys_oldumount, 1) SYS(sys_setuid, 1) SYS(sys_getuid, 0) SYS(sys_stime, 1) /* 4025 */ @@ -70,7 +67,7 @@ SYS(sys_geteuid, 0) SYS(sys_getegid, 0) /* 4050 */ SYS(sys_acct, 0) -SYS(sys_ni_syscall, 0) +SYS(sys_umount, 2) SYS(sys_ni_syscall, 0) SYS(sys_ioctl, 3) SYS(sys_fcntl, 3) /* 4055 */ @@ -168,7 +165,7 @@ SYS(sys_cacheflush, 3) SYS(sys_cachectl, 3) SYS(sys_sysmips, 4) -SYS(sys_setup, 1) /* 4150 */ +SYS(sys_ni_syscall, 0) /* 4150 */ SYS(sys_getsid, 1) SYS(sys_fdatasync, 0) SYS(sys_sysctl, 1) @@ -222,3 +219,9 @@ SYS(sys_pwrite, 4) SYS(sys_chown, 3) SYS(sys_getcwd, 2) +SYS(sys_capget, 2) +SYS(sys_capset, 2) /* 4205 */ +SYS(sys_sigaltstack, 2) +SYS(sys_sendfile, 3) +SYS(sys_ni_syscall, 0) +SYS(sys_ni_syscall, 0) diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/sysirix.c linux/arch/mips/kernel/sysirix.c --- v2.1.125/linux/arch/mips/kernel/sysirix.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/sysirix.c Tue Oct 20 13:52:54 1998 @@ -1,10 +1,10 @@ -/* +/* $Id: sysirix.c,v 1.12 1998/08/17 10:16:27 ralf Exp $ + * * sysirix.c: IRIX system call emulation. * * Copyright (C) 1996 David S. Miller * Copyright (C) 1997 Miguel de Icaza - * - * $Id: sysirix.c,v 1.10 1998/05/08 21:01:33 davem Exp $ + * Copyright (C) 1997, 1998 Ralf Baechle */ #include @@ -1638,96 +1638,6 @@ out: unlock_kernel(); return error; -} - -#define NOFOLLOW_LINKS 0 -#define FOLLOW_LINKS 1 - -static inline int chown_common(uid_t user, gid_t group, struct dentry *dentry) -{ - struct inode * inode; - int error; - struct iattr newattrs; - - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto out; - inode = dentry->d_inode; - - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; - - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto dput_and_out; - - if (user == (uid_t) -1) - user = inode->i_uid; - if (group == (gid_t) -1) - group = inode->i_gid; - newattrs.ia_mode = inode->i_mode; - newattrs.ia_uid = user; - newattrs.ia_gid = group; - newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME; - /* - * If the owner has been changed, remove the setuid bit - */ - if (inode->i_mode & S_ISUID) { - newattrs.ia_mode &= ~S_ISUID; - newattrs.ia_valid |= ATTR_MODE; - } - /* - * If the group has been changed, remove the setgid bit - * - * Don't remove the setgid bit if no group execute bit. - * This is a file marked for mandatory locking. - */ - if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) { - newattrs.ia_mode &= ~S_ISGID; - newattrs.ia_valid |= ATTR_MODE; - } - if (inode->i_sb->dq_op) { - inode->i_sb->dq_op->initialize(inode, -1); - error = -EDQUOT; - if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0)) - goto dput_and_out; - error = notify_change(dentry, &newattrs); - if (error) - inode->i_sb->dq_op->transfer(inode, &newattrs, 1); - } else - error = notify_change(dentry, &newattrs); - -dput_and_out: - dput(dentry); -out: - return error; -} - -asmlinkage int irix_chown(const char *filename, int uid, int gid) -{ - int retval; - struct dentry *dentry; - - lock_kernel(); - /* Do follow any and all links... */ - dentry = namei(filename); - retval = chown_common(uid, gid, dentry); - unlock_kernel(); - return retval; -} - -asmlinkage int irix_lchown(const char *filename, int uid, int gid) -{ - int retval; - struct dentry *dentry; - - lock_kernel(); - /* Do _not_ follow any links... */ - dentry = lnamei(filename); - retval = chown_common(uid, gid, dentry); - unlock_kernel(); - return retval; } asmlinkage int irix_priocntl(struct pt_regs *regs) diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/sysmips.c linux/arch/mips/kernel/sysmips.c --- v2.1.125/linux/arch/mips/kernel/sysmips.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/sysmips.c Tue Oct 20 13:52:54 1998 @@ -7,7 +7,7 @@ * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle * - * $Id: sysmips.c,v 1.8 1998/05/08 21:01:35 davem Exp $ + * $Id: sysmips.c,v 1.4 1998/05/07 15:20:05 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c --- v2.1.125/linux/arch/mips/kernel/time.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/time.c Tue Oct 20 13:52:54 1998 @@ -6,7 +6,7 @@ * This file contains the time handling details for PC-style clocks as * found in some MIPS systems. * - * $Id: time.c,v 1.9 1998/06/10 07:21:13 davem Exp $ + * $Id: time.c,v 1.6 1998/08/17 13:57:44 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c --- v2.1.125/linux/arch/mips/kernel/traps.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/kernel/traps.c Tue Oct 20 13:52:54 1998 @@ -1,14 +1,11 @@ -/* - * arch/mips/kernel/traps.c +/* $Id: traps.c,v 1.20 1998/10/14 20:26:26 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright 1994, 1995, 1996, 1997 by Ralf Baechle + * Copyright 1994, 1995, 1996, 1997, 1998 by Ralf Baechle * Modified for R3000 by Paul M. Antoine, 1995, 1996 - * - * $Id: traps.c,v 1.10 1998/05/04 09:17:57 ralf Exp $ */ #include #include @@ -20,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -28,8 +24,6 @@ #include #include -#undef CONF_DEBUG_EXCEPTIONS - static inline void console_verbose(void) { extern int console_loglevel; @@ -61,9 +55,7 @@ extern asmlinkage void handle_cpu(void); extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); -extern asmlinkage void handle_vcei(void); extern asmlinkage void handle_fpe(void); -extern asmlinkage void handle_vced(void); extern asmlinkage void handle_watch(void); extern asmlinkage void handle_reserved(void); @@ -71,6 +63,7 @@ char watch_available = 0; char dedicated_iv_available = 0; +char vce_available = 0; void (*ibe_board_handler)(struct pt_regs *regs); void (*dbe_board_handler)(struct pt_regs *regs); @@ -159,10 +152,9 @@ } else printk("(Bad address in epc)\n"); - do_exit(SIGSEGV); } -void die_if_kernel(const char * str, struct pt_regs * regs, long err) +void die(const char * str, struct pt_regs * regs, unsigned long err) { if (user_mode(regs)) /* Just return if in user mode. */ return; @@ -173,6 +165,12 @@ do_exit(SIGSEGV); } +void die_if_kernel(const char * str, struct pt_regs * regs, unsigned long err) +{ + if (!user_mode(regs)) + die(str, regs, err); +} + static void default_be_board_handler(struct pt_regs *regs) { /* @@ -183,31 +181,21 @@ void do_ibe(struct pt_regs *regs) { - lock_kernel(); show_regs(regs); while(1); ibe_board_handler(regs); - unlock_kernel(); } void do_dbe(struct pt_regs *regs) { - lock_kernel(); show_regs(regs); while(1); dbe_board_handler(regs); - unlock_kernel(); } void do_ov(struct pt_regs *regs) { - lock_kernel(); -#ifdef CONF_DEBUG_EXCEPTIONS - show_regs(regs); -#endif if (compute_return_epc(regs)) - goto out; + return; force_sig(SIGFPE, current); -out: - unlock_kernel(); } #ifdef CONFIG_MIPS_FPE_MODULE @@ -235,6 +223,9 @@ */ void do_fpe(struct pt_regs *regs, unsigned long fcr31) { + unsigned long pc; + unsigned int insn; + #ifdef CONFIG_MIPS_FPE_MODULE if (fpe_handler != NULL) { fpe_handler(regs, fcr31); @@ -242,9 +233,6 @@ } #endif lock_kernel(); -#ifdef CONF_DEBUG_EXCEPTIONS - show_regs(regs); -#endif if (fcr31 & 0x20000) { /* Retry instruction with flush to zero ... */ if (!(fcr31 & (1<<24))) { @@ -258,13 +246,22 @@ : "r" (fcr31)); goto out; } - printk("Unimplemented exception at 0x%08lx in %s.\n", - regs->cp0_epc, current->comm); + pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0); + if (get_user(insn, (unsigned int *)pc)) { + /* XXX Can this happen? */ + force_sig(SIGSEGV, current); + } + + printk(KERN_DEBUG "Unimplemented exception for insn %08x at 0x%08lx in %s.\n", + insn, regs->cp0_epc, current->comm); + simfp(insn); } if (compute_return_epc(regs)) goto out; - force_sig(SIGFPE, current); + //force_sig(SIGFPE, current); + printk(KERN_DEBUG "Should send SIGFPE to %s\n", current->comm); + out: unlock_kernel(); } @@ -286,72 +283,53 @@ return 0; } -static inline void -do_bp_and_tr(struct pt_regs *regs, char *exc, unsigned int trapcode) -{ - /* - * (A short test says that IRIX 5.3 sends SIGTRAP for all break - * insns, even for break codes that indicate arithmetic failures. - * Wiered ...) - */ - force_sig(SIGTRAP, current); -#ifdef CONF_DEBUG_EXCEPTIONS - show_regs(regs); -#endif -} void do_bp(struct pt_regs *regs) { unsigned int opcode, bcode; - lock_kernel(); /* * There is the ancient bug in the MIPS assemblers that the break * code starts left to bit 16 instead to bit 6 in the opcode. * Gas is bug-compatible ... */ -#ifdef CONF_DEBUG_EXCEPTIONS - printk("BREAKPOINT at %08lx\n", regs->cp0_epc); -#endif if (get_insn_opcode(regs, &opcode)) - goto out; + return; bcode = ((opcode >> 16) & ((1 << 20) - 1)); - do_bp_and_tr(regs, "bp", bcode); - - if (compute_return_epc(regs)) - goto out; -out: - unlock_kernel(); + /* + * (A short test says that IRIX 5.3 sends SIGTRAP for all break + * insns, even for break codes that indicate arithmetic failures. + * Wiered ...) + */ + force_sig(SIGTRAP, current); } void do_tr(struct pt_regs *regs) { unsigned int opcode, bcode; - lock_kernel(); if (get_insn_opcode(regs, &opcode)) - goto out; + return; bcode = ((opcode >> 6) & ((1 << 20) - 1)); - do_bp_and_tr(regs, "tr", bcode); -out: - unlock_kernel(); + /* + * (A short test says that IRIX 5.3 sends SIGTRAP for all break + * insns, even for break codes that indicate arithmetic failures. + * Wiered ...) + */ + force_sig(SIGTRAP, current); } void do_ri(struct pt_regs *regs) { lock_kernel(); -#ifdef CONF_DEBUG_EXCEPTIONS - show_regs(regs); -#endif printk("[%s:%ld] Illegal instruction at %08lx ra=%08lx\n", current->comm, current->pid, regs->cp0_epc, regs->regs[31]); + unlock_kernel(); if (compute_return_epc(regs)) - goto out; + return; force_sig(SIGILL, current); -out: - unlock_kernel(); } void do_cpu(struct pt_regs *regs) @@ -364,7 +342,7 @@ regs->cp0_status |= ST0_CU1; if (last_task_used_math == current) - goto out; + return; if (current->used_math) { /* Using the FPU again. */ r4xx0_lazy_fpu_switch(last_task_used_math); @@ -377,56 +355,27 @@ return; bad_cid: - lock_kernel(); force_sig(SIGILL, current); - unlock_kernel(); -out: -} - -void do_vcei(struct pt_regs *regs) -{ - lock_kernel(); - /* - * Only possible on R4[04]00[SM]C. No handler because I don't have - * such a cpu. Theory says this exception doesn't happen. - */ - panic("Caught VCEI exception - should not happen"); - unlock_kernel(); -} - -void do_vced(struct pt_regs *regs) -{ - lock_kernel(); - /* - * Only possible on R4[04]00[SM]C. No handler because I don't have - * such a cpu. Theory says this exception doesn't happen. - */ - panic("Caught VCE exception - should not happen"); - unlock_kernel(); } void do_watch(struct pt_regs *regs) { - lock_kernel(); /* * We use the watch exception where available to detect stack * overflows. */ show_regs(regs); panic("Caught WATCH exception - probably caused by stack overflow."); - unlock_kernel(); } void do_reserved(struct pt_regs *regs) { - lock_kernel(); /* * Game over - no way to handle this if it ever occurs. * Most probably caused by a new unknown cpu type or * after another deadly hard/software error. */ panic("Caught reserved exception - should not happen."); - unlock_kernel(); } static inline void watch_init(unsigned long cputype) @@ -545,11 +494,8 @@ case CPU_R4400MC: case CPU_R4000SC: case CPU_R4400SC: - /* XXX The following won't work because we _cannot_ - * XXX perform any load/store before the VCE handler. - */ - set_except_vector(14, handle_vcei); - set_except_vector(31, handle_vced); + vce_available = 1; + /* Fall through ... */ case CPU_R4000PC: case CPU_R4400PC: case CPU_R4200: @@ -565,13 +511,16 @@ else memcpy((void *)KSEG0, &except_vec0_r4000, 0x80); - /* - * The idea is that this special r4000 general exception - * vector will check for VCE exceptions before calling - * out of the exception array. XXX TODO - */ + /* Cache error vector */ memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80); - memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80); + + if (vce_available) { + memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, + 0x180); + } else { + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, + 0x100); + } save_fp_context = r4k_save_fp_context; restore_fp_context = r4k_restore_fp_context; diff -u --recursive --new-file v2.1.125/linux/arch/mips/kernel/unaligned.c linux/arch/mips/kernel/unaligned.c --- v2.1.125/linux/arch/mips/kernel/unaligned.c Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/kernel/unaligned.c Tue Oct 20 13:52:54 1998 @@ -7,7 +7,7 @@ * * Copyright (C) 1996, 1998 by Ralf Baechle * - * $Id: unaligned.c,v 1.4 1998/06/10 07:21:15 davem Exp $ + * $Id: unaligned.c,v 1.5 1998/08/17 13:57:44 ralf Exp $ * * This file contains exception handler for address error exception with the * special capability to execute faulting instructions in software. The diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/Makefile linux/arch/mips/lib/Makefile --- v2.1.125/linux/arch/mips/lib/Makefile Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/lib/Makefile Tue Oct 20 13:52:54 1998 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.8 1998/05/08 01:44:18 ralf Exp $ +# $Id: Makefile,v 1.12 1998/05/28 03:17:57 ralf Exp $ # # Makefile for MIPS-specific library files.. # @@ -9,12 +9,8 @@ $(CC) $(CFLAGS) -c $< -o $*.o L_TARGET = lib.a -L_OBJS = csum_partial.o csum_partial_copy.o dump_tlb.o ide-std.o ide-no.o \ - memset.o memcpy.o strlen_user.o strncpy_user.o tags.o watch.o - -# -# Debug console, works without other support from the kernel -# -L_OBJS += tinycon.o +L_OBJS = csum_partial.o csum_partial_copy.o dump_tlb.o floppy-std.o \ + floppy-no.o ide-std.o ide-no.o rtc-std.o rtc-no.o memset.o memcpy.o \ + strlen_user.o strncpy_user.o tags.o watch.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/csum_partial.S linux/arch/mips/lib/csum_partial.S --- v2.1.125/linux/arch/mips/lib/csum_partial.S Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/lib/csum_partial.S Tue Oct 20 13:52:54 1998 @@ -1,4 +1,4 @@ -/* $Id: csum_partial.S,v 1.2 1998/05/08 01:44:20 ralf Exp $ +/* $Id: csum_partial.S,v 1.3 1998/05/07 14:17:45 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/csum_partial_copy.S linux/arch/mips/lib/csum_partial_copy.S --- v2.1.125/linux/arch/mips/lib/csum_partial_copy.S Thu Aug 6 14:06:28 1998 +++ linux/arch/mips/lib/csum_partial_copy.S Wed Dec 31 16:00:00 1969 @@ -1,519 +0,0 @@ -/* $Id: csum_partial_copy.S,v 1.2 1998/05/07 00:39:47 ralf Exp $ - * - * Unified implementation of csum_copy_partial, csum_copy_partial_from_user - * and csum_copy_partial_nocheck. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1998 Ralf Baechle - */ -#include -#include -#include - -/* - * The fixup routine for csum_partial_copy_from_user depends on copying - * strictly in increasing order. Gas expands ulw/usw macros in the wrong order - * for little endian machines, so we cannot depend on them. - */ -#ifdef __MIPSEB__ -#define ulwL lwl -#define ulwU lwr -#endif -#ifdef __MIPSEL__ -#define ulwL lwr -#define ulwU lwl -#endif - -#define EX(insn,reg,addr,handler) \ -9: insn reg, addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - .previous - -#define UEX(insn,reg,addr,handler) \ -9: insn ## L reg, addr; \ -10: insn ## U reg, 3 + addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - PTR 10b, handler; \ - .previous - -#define ADDC(sum,reg) \ - addu sum, reg; \ - sltu v1, sum, reg; \ - addu sum, v1 - -/* ascending order, destination aligned */ -#define CSUM_BIGCHUNK(src, dst, offset, sum, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - ADDC(sum, t0); \ - ADDC(sum, t1); \ - ADDC(sum, t2); \ - ADDC(sum, t3); \ - sw t0, (offset + 0x00)(dst); \ - sw t1, (offset + 0x04)(dst); \ - sw t2, (offset + 0x08)(dst); \ - sw t3, (offset + 0x0c)(dst); \ - EX(lw, t0, (offset + 0x10)(src), l_fixup); \ - EX(lw, t1, (offset + 0x14)(src), l_fixup); \ - EX(lw, t2, (offset + 0x18)(src), l_fixup); \ - EX(lw, t3, (offset + 0x1c)(src), l_fixup); \ - ADDC(sum, t0); \ - ADDC(sum, t1); \ - ADDC(sum, t2); \ - ADDC(sum, t3); \ - sw t0, (offset + 0x10)(dst); \ - sw t1, (offset + 0x14)(dst); \ - sw t2, (offset + 0x18)(dst); \ - sw t3, (offset + 0x1c)(dst) - -/* ascending order, destination unaligned */ -#define UCSUM_BIGCHUNK(src, dst, offset, sum, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - ADDC(sum, t0); \ - ADDC(sum, t1); \ - ADDC(sum, t2); \ - ADDC(sum, t3); \ - usw t0, (offset + 0x00)(dst); \ - usw t1, (offset + 0x04)(dst); \ - usw t2, (offset + 0x08)(dst); \ - usw t3, (offset + 0x0c)(dst); \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - ADDC(sum, t0); \ - ADDC(sum, t1); \ - ADDC(sum, t2); \ - ADDC(sum, t3); \ - usw t0, (offset + 0x10)(dst); \ - usw t1, (offset + 0x14)(dst); \ - usw t2, (offset + 0x18)(dst); \ - usw t3, (offset + 0x1c)(dst) - -# -# a0: source address -# a1: destination address -# a2: length of the area to checksum -# a3: partial checksum -# - -#define src a0 -#define dest a1 -#define sum v0 - - .text - .set noreorder - -/* unknown src/dst alignment and < 8 bytes to go */ -small_csumcpy: - move a2, t2 - - andi t0, a2, 4 - beqz t0, 1f - andi t0, a2, 2 - - /* Still a full word to go */ - UEX(ulw, t1, 0(src), l_fixup) - addiu src, 4 - usw t1, 0(dest) - addiu dest, 4 - ADDC(sum, t1) - -1: move t1, zero - beqz t0, 1f - andi t0, a2, 1 - - /* Still a halfword to go */ - ulhu t1, (src) - addiu src, 2 - ush t1, (dest) - addiu dest, 2 - -1: beqz t0, 1f - sll t1, t1, 16 - - lbu t2, (src) - nop - sb t2, (dest) - -#ifdef __MIPSEB__ - sll t2, t2, 8 -#endif - or t1, t2 - -1: ADDC(sum, t1) - - /* fold checksum */ - sll v1, sum, 16 - addu sum, v1 - sltu v1, sum, v1 - srl sum, sum, 16 - addu sum, v1 - - /* odd buffer alignment? */ - beqz t7, 1f - nop - sll v1, sum, 8 - srl sum, sum, 8 - or sum, v1 - andi sum, 0xffff -1: - .set reorder - /* Add the passed partial csum. */ - ADDC(sum, a3) - jr ra - .set noreorder - -/* ------------------------------------------------------------------------- */ - - .align 5 -LEAF(csum_partial_copy_from_user) - addu t5, src, a2 # end address for fixup -EXPORT(csum_partial_copy_nocheck) -EXPORT(csum_partial_copy) - move sum, zero # clear computed sum - move t7, zero # clear odd flag - xor t0, dest, src - andi t0, t0, 0x3 - beqz t0, can_align - sltiu t8, a2, 0x8 - - b memcpy_u_src # bad alignment - move t2, a2 - -can_align: - bnez t8, small_csumcpy # < 8 bytes to copy - move t2, a2 - - beqz a2, out - andi t7, src, 0x1 # odd buffer? - -hword_align: - beqz t7, word_align - andi t8, src, 0x2 - - EX(lbu, t0, (src), l_fixup) - subu a2, a2, 0x1 - EX(sb, t0, (dest), l_fixup) -#ifdef __MIPSEL__ - sll t0, t0, 8 -#endif - ADDC(sum, t0) - addu src, src, 0x1 - addu dest, dest, 0x1 - andi t8, src, 0x2 - -word_align: - beqz t8, dword_align - sltiu t8, a2, 56 - - EX(lhu, t0, (src), l_fixup) - subu a2, a2, 0x2 - sh t0, (dest) - ADDC(sum, t0) - sltiu t8, a2, 56 - addu dest, dest, 0x2 - addu src, src, 0x2 - -dword_align: - bnez t8, do_end_words - move t8, a2 - - andi t8, src, 0x4 - beqz t8, qword_align - andi t8, src, 0x8 - - EX(lw, t0, 0x00(src), l_fixup) - subu a2, a2, 0x4 - ADDC(sum, t0) - sw t0, 0x00(dest) - addu src, src, 0x4 - addu dest, dest, 0x4 - andi t8, src, 0x8 - -qword_align: - beqz t8, oword_align - andi t8, src, 0x10 - - EX(lw, t0, 0x00(src), l_fixup) - EX(lw, t1, 0x04(src), l_fixup) - subu a2, a2, 0x8 - ADDC(sum, t0) - ADDC(sum, t1) - sw t0, 0x00(dest) - addu src, src, 0x8 - sw t1, 0x04(dest) - andi t8, src, 0x10 - addu dest, dest, 0x8 - -oword_align: - beqz t8, begin_movement - srl t8, a2, 0x7 - - EX(lw, t3, 0x08(src), l_fixup) # assumes subblock ordering - EX(lw, t4, 0x0c(src), l_fixup) - EX(lw, t0, 0x00(src), l_fixup) - EX(lw, t1, 0x04(src), l_fixup) - ADDC(sum, t3) - ADDC(sum, t4) - ADDC(sum, t0) - ADDC(sum, t1) - sw t3, 0x08(dest) - subu a2, a2, 0x10 - sw t4, 0x0c(dest) - addu src, src, 0x10 - sw t0, 0x00(dest) - srl t8, a2, 0x7 - addu dest, dest, 0x10 - sw t1, -0x0c(dest) - -begin_movement: - beqz t8, 0f - andi t2, a2, 0x40 - -move_128bytes: - CSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4) - CSUM_BIGCHUNK(src, dest, 0x20, sum, t0, t1, t3, t4) - CSUM_BIGCHUNK(src, dest, 0x40, sum, t0, t1, t3, t4) - CSUM_BIGCHUNK(src, dest, 0x60, sum, t0, t1, t3, t4) - subu t8, t8, 0x01 - addu src, src, 0x80 - bnez t8, move_128bytes - addu dest, dest, 0x80 - -0: - beqz t2, 1f - andi t2, a2, 0x20 - -move_64bytes: - CSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4) - CSUM_BIGCHUNK(src, dest, 0x20, sum, t0, t1, t3, t4) - addu src, src, 0x40 - addu dest, dest, 0x40 - -1: - beqz t2, do_end_words - andi t8, a2, 0x1c - -move_32bytes: - CSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4) - andi t8, a2, 0x1c - addu src, src, 0x20 - addu dest, dest, 0x20 - -do_end_words: - beqz t8, maybe_end_cruft - srl t8, t8, 0x2 - -end_words: - EX(lw, t0, (src), l_fixup) - subu t8, t8, 0x1 - ADDC(sum, t0) - sw t0, (dest) - addu src, src, 0x4 - bnez t8, end_words - addu dest, dest, 0x4 - -maybe_end_cruft: - andi t2, a2, 0x3 - -small_memcpy: - j small_csumcpy; move a2, t2 - beqz t2, out - move a2, t2 - -end_bytes: - EX(lb, t0, (src), l_fixup) - subu a2, a2, 0x1 - sb t0, (dest) - addu src, src, 0x1 - bnez a2, end_bytes - addu dest, dest, 0x1 - -out: - jr ra - move v0, sum - -/* ------------------------------------------------------------------------- */ - -/* Bad, bad. At least try to align the source */ - -memcpy_u_src: - bnez t8, small_memcpy # < 8 bytes? - move t2, a2 - - beqz a2, out - andi t7, src, 0x1 # odd alignment? - -u_hword_align: - beqz t7, u_word_align - andi t8, src, 0x2 - - EX(lbu, t0, (src), l_fixup) - subu a2, a2, 0x1 - sb t0, (dest) -#ifdef __MIPSEL__ - sll t0, t0, 8 -#endif - ADDC(sum, t0) - addu src, src, 0x1 - addu dest, dest, 0x1 - andi t8, src, 0x2 - -u_word_align: - beqz t8, u_dword_align - sltiu t8, a2, 56 - - EX(lhu, t0, (src), l_fixup) - subu a2, a2, 0x2 - ush t0, (dest) - ADDC(sum, t0) - sltiu t8, a2, 56 - addu dest, dest, 0x2 - addu src, src, 0x2 - -u_dword_align: - bnez t8, u_do_end_words - move t8, a2 - - andi t8, src, 0x4 - beqz t8, u_qword_align - andi t8, src, 0x8 - - EX(lw, t0, 0x00(src), l_fixup) - subu a2, a2, 0x4 - ADDC(sum, t0) - usw t0, 0x00(dest) - addu src, src, 0x4 - addu dest, dest, 0x4 - andi t8, src, 0x8 - -u_qword_align: - beqz t8, u_oword_align - andi t8, src, 0x10 - - EX(lw, t0, 0x00(src), l_fixup) - EX(lw, t1, 0x04(src), l_fixup) - subu a2, a2, 0x8 - ADDC(sum, t0) - ADDC(sum, t1) - usw t0, 0x00(dest) - addu src, src, 0x8 - usw t1, 0x04(dest) - andi t8, src, 0x10 - addu dest, dest, 0x8 - -u_oword_align: - beqz t8, u_begin_movement - srl t8, a2, 0x7 - - EX(lw, t3, 0x08(src), l_fixup) - EX(lw, t4, 0x0c(src), l_fixup) - EX(lw, t0, 0x00(src), l_fixup) - EX(lw, t1, 0x04(src), l_fixup) - ADDC(sum, t3) - ADDC(sum, t4) - ADDC(sum, t0) - ADDC(sum, t1) - usw t3, 0x08(dest) - subu a2, a2, 0x10 - usw t4, 0x0c(dest) - addu src, src, 0x10 - usw t0, 0x00(dest) - srl t8, a2, 0x7 - addu dest, dest, 0x10 - usw t1, -0x0c(dest) - -u_begin_movement: - beqz t8, 0f - andi t2, a2, 0x40 - -u_move_128bytes: - UCSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4) - UCSUM_BIGCHUNK(src, dest, 0x20, sum, t0, t1, t3, t4) - UCSUM_BIGCHUNK(src, dest, 0x40, sum, t0, t1, t3, t4) - UCSUM_BIGCHUNK(src, dest, 0x60, sum, t0, t1, t3, t4) - subu t8, t8, 0x01 - addu src, src, 0x80 - bnez t8, u_move_128bytes - addu dest, dest, 0x80 - -0: - beqz t2, 1f - andi t2, a2, 0x20 - -u_move_64bytes: - UCSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4) - UCSUM_BIGCHUNK(src, dest, 0x20, sum, t0, t1, t3, t4) - addu src, src, 0x40 - addu dest, dest, 0x40 - -1: - beqz t2, u_do_end_words - andi t8, a2, 0x1c - -u_move_32bytes: - UCSUM_BIGCHUNK(src, dest, 0x00, sum, t0, t1, t3, t4) - andi t8, a2, 0x1c - addu src, src, 0x20 - addu dest, dest, 0x20 - -u_do_end_words: - beqz t8, u_maybe_end_cruft - srl t8, t8, 0x2 - -u_end_words: - EX(lw, t0, 0x00(src), l_fixup) - subu t8, t8, 0x1 - ADDC(sum, t0) - usw t0, 0x00(dest) - addu src, src, 0x4 - bnez t8, u_end_words - addu dest, dest, 0x4 - -u_maybe_end_cruft: - andi t2, a2, 0x3 - -u_cannot_optimize: - j small_csumcpy; move a2, t2 - beqz t2, out - move a2, t2 - -u_end_bytes: - EX(lb, t0, (src), l_fixup) - subu a2, a2, 0x1 - sb t0, (dest) - addu src, src, 0x1 - bnez a2, u_end_bytes - addu dest, dest, 0x1 - - jr ra - move v0, sum - END(csum_partial_copy_from_user) - -l_fixup: - beqz t7, 1f # odd buffer alignment? - nop - sll v1, sum, 8 # swap bytes - srl sum, sum, 8 - or sum, v1 - andi sum, 0xffff -1: ADDC(sum, a3) # Add csum argument. - - lw t0, THREAD_BUADDR($28) # clear the rest of the buffer - nop - subu t1, t0, src # where to start clearing - addu a0, dest, t1 - move a1, zero # zero fill - j __bzero - subu a2, t5, t0 # a2 = bad - srcend bytes to go diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/csum_partial_copy.c linux/arch/mips/lib/csum_partial_copy.c --- v2.1.125/linux/arch/mips/lib/csum_partial_copy.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/lib/csum_partial_copy.c Tue Oct 20 13:52:54 1998 @@ -0,0 +1,75 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * MIPS specific IP/TCP/UDP checksumming routines + * + * Authors: Ralf Baechle, + * Lots of code moved from tcp.c and ip.c; see those files + * for more names. + * + * 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. + * + * $Id: csum_partial_copy.c,v 1.2 1998/09/16 13:29:32 ralf Exp $ + */ +#include +#include +#include +#include +#include + +/* + * copy while checksumming, otherwise like csum_partial + */ +unsigned int csum_partial_copy(const char *src, char *dst, + int len, unsigned int sum) +{ + /* + * It's 2:30 am and I don't feel like doing it real ... + * This is lots slower than the real thing (tm) + */ + sum = csum_partial(src, len, sum); + memcpy(dst, src, len); + + return sum; +} + +/* + * Copy from userspace and compute checksum. If we catch an exception + * then zero the rest of the buffer. + */ +unsigned int csum_partial_copy_from_user (const char *src, char *dst, + int len, unsigned int sum, + int *err_ptr) +{ + int missing; + + missing = copy_from_user(dst, src, len); + if (missing) { + memset(dst + len - missing, 0, missing); + *err_ptr = -EFAULT; + } + + return csum_partial(dst, len, sum); +} + +/* + * Copy to userspace and compute checksum. + */ +unsigned int csum_partial_copy_to_user (const char *src, char *dst, + int len, unsigned int sum, + int *err_ptr) +{ + sum = csum_partial(src, len, sum); + + if (copy_to_user(dst, src, len)) { + *err_ptr = -EFAULT; + return sum; + } + + return sum; +} diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/floppy-no.c linux/arch/mips/lib/floppy-no.c --- v2.1.125/linux/arch/mips/lib/floppy-no.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/lib/floppy-no.c Tue Oct 20 13:52:54 1998 @@ -0,0 +1,58 @@ +/* $Id: floppy-no.c,v 1.1 1998/05/07 18:38:32 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Dummy file for machines without standard floppy drives. + * + * Copyright (C) 1998 by Ralf Baechle + */ +#include +#include +#include +#include + +/* + * How to access the FDC's registers. + */ +static void no_fd_dummy(void) +{ + panic("no_fd_dummy called - shouldn't happen"); +} + +static unsigned long no_fd_getfdaddr1(void) +{ + return (unsigned long)-1; /* No FDC nowhere ... */ +} + +static unsigned long no_fd_drive_type(unsigned long n) +{ + return 0; +} + +struct fd_ops no_fd_ops = { + /* + * How to access the floppy controller's ports + */ + (void *) no_fd_dummy, + (void *) no_fd_dummy, + /* + * How to access the floppy DMA functions. + */ + (void *) no_fd_dummy, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + no_fd_getfdaddr1, + (void *) no_fd_dummy, + (void *) no_fd_dummy, + no_fd_drive_type +}; diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/floppy-std.c linux/arch/mips/lib/floppy-std.c --- v2.1.125/linux/arch/mips/lib/floppy-std.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/lib/floppy-std.c Tue Oct 20 13:52:54 1998 @@ -0,0 +1,167 @@ +/* $Id: floppy-std.c,v 1.2 1998/05/28 03:17:57 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Access the floppy hardware on PC style hardware + * + * Copyright (C) 1996, 1997, 1998 by Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * How to access the FDC's registers. + */ +static unsigned char std_fd_inb(unsigned int port) +{ + return inb_p(port); +} + +static void std_fd_outb(unsigned char value, unsigned int port) +{ + outb_p(value, port); +} + +/* + * How to access the floppy DMA functions. + */ +static void std_fd_enable_dma(int channel) +{ + enable_dma(channel); +} + +static void std_fd_disable_dma(int channel) +{ + disable_dma(channel); +} + +static int std_fd_request_dma(int channel) +{ + return request_dma(channel, "floppy"); +} + +static void std_fd_free_dma(int channel) +{ + free_dma(channel); +} + +static void std_fd_clear_dma_ff(int channel) +{ + clear_dma_ff(channel); +} + +static void std_fd_set_dma_mode(int channel, char mode) +{ + set_dma_mode(channel, mode); +} + +static void std_fd_set_dma_addr(int channel, unsigned int addr) +{ + set_dma_addr(channel, addr); +} + +static void std_fd_set_dma_count(int channel, unsigned int count) +{ + set_dma_count(channel, count); +} + +static int std_fd_get_dma_residue(int channel) +{ + return get_dma_residue(channel); +} + +static void std_fd_enable_irq(int irq) +{ + enable_irq(irq); +} + +static void std_fd_disable_irq(int irq) +{ + disable_irq(irq); +} + +static unsigned long std_fd_getfdaddr1(void) +{ + return 0x3f0; +} + +/* Pure 2^n version of get_order */ +static int __get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +static unsigned long std_fd_dma_mem_alloc(unsigned long size) +{ + int order = __get_order(size); + unsigned long mem; + + mem = __get_dma_pages(GFP_KERNEL,order); + + return mem; +} + +static void std_fd_dma_mem_free(unsigned long addr, unsigned long size) +{ + free_pages(addr, __get_order(size)); +} + +static unsigned long std_fd_drive_type(unsigned long n) +{ + if (n == 0) + return 4; /* 3,5", 1.44mb */ + + return 0; +} + +struct fd_ops std_fd_ops = { + /* + * How to access the floppy controller's ports + */ + std_fd_inb, + std_fd_outb, + /* + * How to access the floppy DMA functions. + */ + std_fd_enable_dma, + std_fd_disable_dma, + std_fd_request_dma, + std_fd_free_dma, + std_fd_clear_dma_ff, + std_fd_set_dma_mode, + std_fd_set_dma_addr, + std_fd_set_dma_count, + std_fd_get_dma_residue, + std_fd_enable_irq, + std_fd_disable_irq, + std_fd_getfdaddr1, + std_fd_dma_mem_alloc, + std_fd_dma_mem_free, + std_fd_drive_type +}; diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/ide-no.c linux/arch/mips/lib/ide-no.c --- v2.1.125/linux/arch/mips/lib/ide-no.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/lib/ide-no.c Tue Oct 20 13:52:54 1998 @@ -1,5 +1,4 @@ -/* - * arch/mips/kernel/ide-none.c +/* $Id: ide-no.c,v 1.2 1998/05/28 03:17:57 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -9,8 +8,6 @@ * have IDE like the Indy. * * Copyright (C) 1998 by Ralf Baechle - * - * $Id: ide-no.c,v 1.1 1998/05/04 09:18:13 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/memcpy.S linux/arch/mips/lib/memcpy.S --- v2.1.125/linux/arch/mips/lib/memcpy.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/lib/memcpy.S Tue Oct 20 13:52:54 1998 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * $Id: memcpy.S,v 1.2 1998/05/04 09:18:16 ralf Exp $ + * $Id: memcpy.S,v 1.4 1998/07/03 14:05:33 ralf Exp $ * * Unified implementation of memcpy, memmove and the __copy_user backend. * For __rmemcpy and memmove an exception is always a kernel bug, therefore @@ -416,6 +416,7 @@ addu a0, a2 # dst = dst + len addu a1, a2 # src = src + len +#if 0 /* Horror fix */ xor t0, a0, a1 andi t0, t0, 0x3 move t7, a0 @@ -552,6 +553,7 @@ r_small_memcpy: beqz t2, r_out move a2, t2 +#endif /* Horror fix */ r_end_bytes: lb t0, -1(a1) @@ -565,6 +567,7 @@ jr ra move a2, zero +#if 0 /* Horror fix */ /* ------------------------------------------------------------------------- */ /* Bad, bad. At least try to align the source */ @@ -686,6 +689,7 @@ jr ra move a2, zero END(__rmemcpy) +#endif /* Horror fix */ l_fixup: # clear the rest of the buffer lw t0, THREAD_BUADDR($28) diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/memset.S linux/arch/mips/lib/memset.S --- v2.1.125/linux/arch/mips/lib/memset.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/lib/memset.S Tue Oct 20 13:52:54 1998 @@ -7,7 +7,7 @@ * * Copyright (C) 1998 by Ralf Baechle * - * $Id: memset.S,v 1.1 1998/05/04 09:18:18 ralf Exp $ + * $Id: memset.S,v 1.2 1998/04/25 17:01:45 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/rtc-no.c linux/arch/mips/lib/rtc-no.c --- v2.1.125/linux/arch/mips/lib/rtc-no.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/lib/rtc-no.c Tue Oct 20 13:52:54 1998 @@ -0,0 +1,34 @@ +/* $Id: rtc-no.c,v 1.2 1998/06/25 20:19:15 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Stub RTC routines to keep Linux from crashing on machine which don't + * have a RTC chip. + * + * Copyright (C) 1998 by Ralf Baechle + */ +#include +#include + +static unsigned char no_rtc_read_data(unsigned long addr) +{ + panic("no_rtc_read_data called - shouldn't happen."); +} + +static void no_rtc_write_data(unsigned char data, unsigned long addr) +{ + panic("no_rtc_write_data called - shouldn't happen."); +} + +static int no_rtc_bcd_mode(void) +{ + panic("no_rtc_bcd_mode called - shouldn't happen."); +} + +struct rtc_ops no_rtc_ops = { + &no_rtc_read_data, + &no_rtc_write_data, + &no_rtc_bcd_mode +}; diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/rtc-std.c linux/arch/mips/lib/rtc-std.c --- v2.1.125/linux/arch/mips/lib/rtc-std.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/lib/rtc-std.c Tue Oct 20 13:52:54 1998 @@ -0,0 +1,35 @@ +/* $Id: rtc-std.c,v 1.2 1998/06/25 20:19:16 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * RTC routines for PC style attached Dallas chip. + * + * Copyright (C) 1998 by Ralf Baechle + */ +#include +#include + +static unsigned char std_rtc_read_data(unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + return inb_p(RTC_PORT(1)); +} + +static void std_rtc_write_data(unsigned char data, unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + outb_p(data, RTC_PORT(1)); +} + +static int std_rtc_bcd_mode(void) +{ + return 1; +} + +struct rtc_ops std_rtc_ops = { + &std_rtc_read_data, + &std_rtc_write_data, + &std_rtc_bcd_mode +}; diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/strlen_user.S linux/arch/mips/lib/strlen_user.S --- v2.1.125/linux/arch/mips/lib/strlen_user.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/lib/strlen_user.S Tue Oct 20 13:52:54 1998 @@ -7,7 +7,7 @@ * * Copyright (c) 1996, 1998 by Ralf Baechle * - * $Id: strlen_user.S,v 1.2 1998/05/04 09:18:20 ralf Exp $ + * $Id: strlen_user.S,v 1.3 1998/05/03 11:13:45 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/lib/strncpy_user.S linux/arch/mips/lib/strncpy_user.S --- v2.1.125/linux/arch/mips/lib/strncpy_user.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/lib/strncpy_user.S Tue Oct 20 13:52:54 1998 @@ -7,7 +7,7 @@ * * Copyright (c) 1996 by Ralf Baechle * - * $Id: strncpy_user.S,v 1.2 1998/05/04 09:18:22 ralf Exp $ + * $Id: strncpy_user.S,v 1.3 1998/05/03 11:13:45 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/andes.c linux/arch/mips/mm/andes.c --- v2.1.125/linux/arch/mips/mm/andes.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/mm/andes.c Tue Oct 20 13:52:54 1998 @@ -1,9 +1,8 @@ -/* +/* $Id: andes.c,v 1.6 1998/10/16 19:22:42 ralf Exp $ + * * andes.c: MMU and cache operations for the R10000 (ANDES). * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: andes.c,v 1.5 1998/05/04 09:18:26 ralf Exp $ */ #include #include @@ -13,6 +12,7 @@ #include #include #include +#include extern unsigned long mips_tlb_entries; @@ -104,6 +104,7 @@ flush_tlb_mm = andes_flush_tlb_mm; flush_tlb_range = andes_flush_tlb_range; flush_tlb_page = andes_flush_tlb_page; + andes_asid_setup(); add_wired_entry = andes_add_wired_entry; diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/fault.c linux/arch/mips/mm/fault.c --- v2.1.125/linux/arch/mips/mm/fault.c Wed Sep 9 14:51:06 1998 +++ linux/arch/mips/mm/fault.c Tue Oct 20 13:52:54 1998 @@ -1,10 +1,14 @@ -/* - * arch/mips/mm/fault.c +/* $Id: fault.c,v 1.12 1998/10/19 21:27:37 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * Copyright (C) 1995, 1996, 1997 by Ralf Baechle + * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle */ #include #include +#include #include #include #include @@ -14,16 +18,20 @@ #include #include #include +#include #include #include #include +#include #include #include -extern void die_if_kernel(char *, struct pt_regs *, long); +#define development_version (LINUX_VERSION_CODE & 0x100) + +extern void die(char *, struct pt_regs *, unsigned long write); -unsigned long asid_cache = ASID_FIRST_VERSION; +unsigned long asid_cache; /* * Macro for exception fixup code to access integer registers. @@ -43,9 +51,12 @@ struct mm_struct *mm = tsk->mm; unsigned long fixup; - if (local_irq_count[smp_processor_id()] != 0) - die_if_kernel("page fault from irq handler", regs, writeaccess); - lock_kernel(); + /* + * If we're in an interrupt or have no user + * context, we must not take the fault.. + */ + if (in_interrupt() || mm == &init_mm) + goto no_context; #if 0 printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid, address, writeaccess, regs->cp0_epc); @@ -74,8 +85,7 @@ } handle_mm_fault(tsk, vma, address, writeaccess); up(&mm->mmap_sem); - - goto out; + return; /* * Something tried to access memory that isn't in our memory map.. @@ -97,20 +107,22 @@ (unsigned long) regs->regs[31]); #endif force_sig(SIGSEGV, tsk); - goto out; + return; } - /* Did we have an exception handler installed? */ +no_context: + /* Are we prepared to handle this kernel fault? */ fixup = search_exception_table(regs->cp0_epc); if (fixup) { long new_epc; tsk->tss.cp0_baduaddr = address; new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); - printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n", - tsk->comm, regs->cp0_epc, new_epc); + if (development_version) + printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n", + tsk->comm, regs->cp0_epc, new_epc); regs->cp0_epc = new_epc; - goto out; + return; } /* @@ -120,8 +132,6 @@ printk(KERN_ALERT "Unable to handle kernel paging request at virtual " "address %08lx, epc == %08lx, ra == %08lx\n", address, regs->cp0_epc, regs->regs[31]); - die_if_kernel("Oops", regs, writeaccess); + die("Oops", regs, writeaccess); do_exit(SIGKILL); -out: - unlock_kernel(); } diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/init.c linux/arch/mips/mm/init.c --- v2.1.125/linux/arch/mips/mm/init.c Wed Sep 9 14:51:06 1998 +++ linux/arch/mips/mm/init.c Tue Oct 20 13:52:54 1998 @@ -1,11 +1,10 @@ -/* +/* $Id: init.c,v 1.13 1998/10/16 19:22:42 ralf Exp $ + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle - * - * $Id: init.c,v 1.15 1998/08/04 20:48:30 davem Exp $ + * Copyright (C) 1994 - 1998 by Ralf Baechle */ #include #include @@ -15,10 +14,12 @@ #include #include #include +#include #include #include #include #include +#include #ifdef CONFIG_BLK_DEV_INITRD #include #endif @@ -27,17 +28,77 @@ #include #include #include -#include #include #include #ifdef CONFIG_SGI #include #endif +#include + +/* + * Define this to effectivly disable the userpage colouring shit. + */ +#define CONF_GIVE_A_SHIT_ABOUT_COLOURS extern void deskstation_tyne_dma_init(void); extern void show_net_buffers(void); -const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n"; +void __bad_pte_kernel(pmd_t *pmd) +{ + printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd)); + pmd_val(*pmd) = BAD_PAGETABLE; +} + +void __bad_pte(pmd_t *pmd) +{ + printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); + pmd_val(*pmd) = BAD_PAGETABLE; +} + +pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) +{ + pte_t *page; + + page = (pte_t *) __get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + clear_page((unsigned long)page); + pmd_val(*pmd) = (unsigned long)page; + return page + offset; + } + pmd_val(*pmd) = BAD_PAGETABLE; + return NULL; + } + free_page((unsigned long)page); + if (pmd_bad(*pmd)) { + __bad_pte_kernel(pmd); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + offset; +} + +pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) +{ + pte_t *page; + + page = (pte_t *) __get_free_page(GFP_KERNEL); + if (pmd_none(*pmd)) { + if (page) { + clear_page((unsigned long)page); + pmd_val(*pmd) = (unsigned long)page; + return page + offset; + } + pmd_val(*pmd) = BAD_PAGETABLE; + return NULL; + } + free_page((unsigned long)page); + if (pmd_bad(*pmd)) { + __bad_pte(pmd); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + offset; +} + asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) { @@ -46,9 +107,50 @@ return 0; } +/* + * We have upto 8 empty zeroed pages so we can map one of the right colour + * when needed. This is necessary only on R4000 / R4400 SC and MC versions + * where we have to avoid VCED / VECI exceptions for good performance at + * any price. Since page is never written to after the initialization we + * don't have to care about aliases on other CPUs. + */ +unsigned long empty_zero_page, zero_page_mask; + +static inline unsigned long setup_zero_pages(void) +{ + unsigned long order, size, pg; + + switch (mips_cputype) { + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400SC: + case CPU_R4400MC: + order = 3; + default: + order = 0; + } + + empty_zero_page = __get_free_pages(GFP_KERNEL, order); + if (!empty_zero_page) + panic("Oh boy, that early out of memory?"); + + pg = MAP_NR(empty_zero_page); + while(pg < MAP_NR(empty_zero_page) + (1 << order)) { + set_bit(PG_reserved, &mem_map[pg].flags); + pg++; + } + + size = PAGE_SIZE << order; + zero_page_mask = (size - 1) & PAGE_MASK; + memset((void *)empty_zero_page, 0, size); + + return size; +} + int do_check_pgt_cache(int low, int high) { int freed = 0; + if(pgtable_cache_size > high) { do { if(pgd_quicklist) @@ -141,10 +243,87 @@ return pte_mkdirty(mk_pte(page, PAGE_SHARED)); } +#ifdef __SMP__ +spinlock_t user_page_lock = SPIN_LOCK_UNLOCKED; +#endif +struct upcache user_page_cache[8] __attribute__((aligned(32))); +static unsigned long user_page_order; +unsigned long user_page_colours; + +unsigned long get_user_page_slow(int which) +{ + unsigned long chunk; + struct upcache *up = &user_page_cache[0]; + struct page *p, *res; + int i; + + do { + chunk = __get_free_pages(GFP_KERNEL, user_page_order); + } while(chunk==0); + + p = mem_map + MAP_NR(chunk); + res = p + which; + spin_lock(&user_page_lock); + for (i=user_page_colours; i>=0; i--,p++,up++,chunk+=PAGE_SIZE) { + atomic_set(&p->count, 1); + p->age = PAGE_INITIAL_AGE; + + if (p != res) { + if(up->count < USER_PAGE_WATER) { + p->next = up->list; + up->list = p; + up->count++; + } else + free_pages(chunk, 0); + } + } + spin_unlock(&user_page_lock); + + return page_address(res); +} + +static inline void user_page_setup(void) +{ + unsigned long assoc = 0; + unsigned long dcache_log, icache_log, cache_log; + unsigned long config = read_32bit_cp0_register(CP0_CONFIG); + + switch(mips_cputype) { + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400SC: + case CPU_R4400MC: + cache_log = 3; /* => 32k, sucks */ + break; + + case CPU_R4600: /* two way set associative caches? */ + case CPU_R4700: + case CPU_R5000: + case CPU_NEVADA: + assoc = 1; + /* fall through */ + default: + /* use bigger cache */ + icache_log = (config >> 9) & 7; + dcache_log = (config >> 6) & 7; + if (dcache_log > icache_log) + cache_log = dcache_log; + else + cache_log = icache_log; + } + +#ifdef CONF_GIVE_A_SHIT_ABOUT_COLOURS + cache_log = assoc = 0; +#endif + + user_page_order = cache_log - assoc; + user_page_colours = (1 << (cache_log - assoc)) - 1; +} + void show_mem(void) { int i, free = 0, total = 0, reserved = 0; - int shared = 0; + int shared = 0, cached = 0; printk("Mem-info:\n"); show_free_areas(); @@ -154,15 +333,19 @@ total++; if (PageReserved(mem_map+i)) reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; else if (!atomic_read(&mem_map[i].count)) free++; else shared += atomic_read(&mem_map[i].count) - 1; } printk("%d pages of RAM\n", total); - printk("%d free pages\n", free); printk("%d reserved pages\n", reserved); printk("%d pages shared\n", shared); + printk("%d pages swap cached\n",cached); + printk("%ld pages in page table cache\n",pgtable_cache_size); + printk("%d free pages\n", free); show_buffers(); #ifdef CONFIG_NET show_net_buffers(); @@ -173,7 +356,9 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)) { + /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); + pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2); return free_area_init(start_mem, end_mem); } @@ -193,9 +378,6 @@ max_mapnr = num_physpages = MAP_NR(end_mem); high_memory = (void *)end_mem; - /* clear the zero-page */ - clear_page((unsigned long)empty_zero_page); - /* mark usable pages in the mem_map[] */ start_mem = PAGE_ALIGN(start_mem); @@ -232,13 +414,18 @@ free_page(tmp); } tmp = nr_free_pages << PAGE_SHIFT; + + /* Setup zeroed pages. */ + tmp -= setup_zero_pages(); + printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n", tmp >> 10, max_mapnr << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10), datapages << (PAGE_SHIFT-10)); - return; + /* Initialize allocator for colour matched mapped pages. */ + user_page_setup(); } extern char __init_begin, __init_end; @@ -277,4 +464,36 @@ val->totalram <<= PAGE_SHIFT; val->sharedram <<= PAGE_SHIFT; return; +} + +/* Fixup an immediate instruction */ +__initfunc(static void __i_insn_fixup(unsigned int **start, unsigned int **stop, + unsigned int i_const)) +{ + unsigned int **p, *ip; + + for (p = start;p < stop; p++) { + ip = *p; + *ip = (*ip & 0xffff0000) | i_const; + } +} + +#define i_insn_fixup(section, const) \ +do { \ + extern unsigned int *__start_ ## section; \ + extern unsigned int *__stop_ ## section; \ + __i_insn_fixup(&__start_ ## section, &__stop_ ## section, const); \ +} while(0) + +/* Caller is assumed to flush the caches before the first context switch. */ +__initfunc(void __asid_setup(unsigned int inc, unsigned int mask, + unsigned int version_mask, + unsigned int first_version)) +{ + i_insn_fixup(__asid_inc, inc); + i_insn_fixup(__asid_mask, mask); + i_insn_fixup(__asid_version_mask, version_mask); + i_insn_fixup(__asid_first_version, first_version); + + asid_cache = first_version; } diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/loadmmu.c linux/arch/mips/mm/loadmmu.c --- v2.1.125/linux/arch/mips/mm/loadmmu.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/mm/loadmmu.c Tue Oct 20 13:52:54 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: loadmmu.c,v 1.6 1998/05/01 01:34:54 ralf Exp $ + * $Id: loadmmu.c,v 1.7 1998/03/27 08:53:41 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c --- v2.1.125/linux/arch/mips/mm/r2300.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/mm/r2300.c Tue Oct 20 13:52:54 1998 @@ -1,9 +1,8 @@ -/* +/* $Id: r2300.c,v 1.7 1998/10/16 19:22:43 ralf Exp $ + * * r2300.c: R2000 and R3000 specific mmu/cache code. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: r2300.c,v 1.5 1998/05/01 01:34:55 ralf Exp $ */ #include #include @@ -14,6 +13,7 @@ #include #include #include +#include extern unsigned long mips_tlb_entries; @@ -199,7 +199,7 @@ "=r" (dummy2) :"r" ((unsigned long) invalid_pte_table), "0" (page), - "1" (PAGE_SIZE/(sizeof(pmd_t)*8))); + "1" (USER_PTRS_PER_PGD/8)); } static void r2300_update_mmu_cache(struct vm_area_struct * vma, @@ -274,6 +274,7 @@ flush_tlb_mm = r2300_flush_tlb_mm; flush_tlb_range = r2300_flush_tlb_range; flush_tlb_page = r2300_flush_tlb_page; + r3000_asid_setup(); load_pgd = r2300_load_pgd; pgd_init = r2300_pgd_init; diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/r4xx0.c linux/arch/mips/mm/r4xx0.c --- v2.1.125/linux/arch/mips/mm/r4xx0.c Thu Aug 6 14:06:29 1998 +++ linux/arch/mips/mm/r4xx0.c Tue Oct 20 13:52:55 1998 @@ -1,9 +1,13 @@ -/* +/* $Id: r4xx0.c,v 1.30 1998/10/16 19:22:43 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * * r4xx0.c: R4000 processor variant specific MMU/Cache routines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: r4xx0.c,v 1.13 1998/05/21 07:34:35 davem Exp $ + * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org * * To do: * @@ -37,7 +41,7 @@ static int ic_lsize, dc_lsize; /* LineSize in bytes */ /* Secondary cache (if present) parameters. */ -static scache_size, sc_lsize; /* Again, in bytes */ +static unsigned int scache_size, sc_lsize; /* Again, in bytes */ #include #include @@ -74,10 +78,7 @@ * - a version which handles the buggy R4600 v1.x * - a version which handles the buggy R4600 v2.0 * - Finally a last version without fancy cache games for the SC and MC - * versions of R4000 and R4400. Cache instructions are quite expensive - * and I guess using them for both the primary and the second level cache - * wouldn't be worth the effort. - * This needs to be verified by benchmarking. + * versions of R4000 and R4400. */ static void r4k_clear_page_d16(unsigned long page) @@ -241,14 +242,84 @@ restore_flags(flags); } -static void r4k_clear_page(unsigned long page) +/* + * The next 4 versions are optimized for all possible scache configurations + * of the SC / MC versions of R4000 and R4400 ... + * + * Todo: For even better performance we should have a routine optimized for + * every legal combination of dcache / scache linesize. When I (Ralf) tried + * this the kernel crashed shortly after mounting the root filesystem. CPU + * bug? Weirdo cache instruction semantics? + */ +static void r4k_clear_page_s16(unsigned long page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "cache\t%3,16(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "cache\t%3,-16(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (page) + :"0" (page), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD) + :"$1","memory"); +} + +static void r4k_clear_page_s32(unsigned long page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (page) + :"0" (page), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD) + :"$1","memory"); +} + +static void r4k_clear_page_s64(unsigned long page) { __asm__ __volatile__( ".set\tnoreorder\n\t" ".set\tnoat\n\t" ".set\tmips3\n\t" "daddiu\t$1,%0,%2\n" - "1:\tsd\t$0,(%0)\n\t" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" "sd\t$0,8(%0)\n\t" "sd\t$0,16(%0)\n\t" "sd\t$0,24(%0)\n\t" @@ -263,7 +334,44 @@ ".set\treorder" :"=r" (page) :"0" (page), - "I" (PAGE_SIZE) + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD) + :"$1","memory"); +} + +static void r4k_clear_page_s128(unsigned long page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "sd\t$0,32(%0)\n\t" + "sd\t$0,40(%0)\n\t" + "sd\t$0,48(%0)\n\t" + "sd\t$0,56(%0)\n\t" + "daddiu\t%0,128\n\t" + "sd\t$0,-64(%0)\n\t" + "sd\t$0,-56(%0)\n\t" + "sd\t$0,-48(%0)\n\t" + "sd\t$0,-40(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (page) + :"0" (page), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD) :"$1","memory"); } @@ -525,7 +633,10 @@ restore_flags(flags); } -static void r4k_copy_page(unsigned long to, unsigned long from) +/* + * These are for R4000SC / R4400MC + */ +static void r4k_copy_page_s16(unsigned long to, unsigned long from) { unsigned long dummy1, dummy2; unsigned long reg1, reg2, reg3, reg4; @@ -535,7 +646,8 @@ ".set\tnoat\n\t" ".set\tmips3\n\t" "daddiu\t$1,%0,%8\n" - "1:\tlw\t%2,(%1)\n\t" + "1:\tcache\t%9,(%0)\n\t" + "lw\t%2,(%1)\n\t" "lw\t%3,4(%1)\n\t" "lw\t%4,8(%1)\n\t" "lw\t%5,12(%1)\n\t" @@ -543,6 +655,7 @@ "sw\t%3,4(%0)\n\t" "sw\t%4,8(%0)\n\t" "sw\t%5,12(%0)\n\t" + "cache\t%9,16(%0)\n\t" "lw\t%2,16(%1)\n\t" "lw\t%3,20(%1)\n\t" "lw\t%4,24(%1)\n\t" @@ -551,6 +664,7 @@ "sw\t%3,20(%0)\n\t" "sw\t%4,24(%0)\n\t" "sw\t%5,28(%0)\n\t" + "cache\t%9,32(%0)\n\t" "daddiu\t%0,64\n\t" "daddiu\t%1,64\n\t" "lw\t%2,-32(%1)\n\t" @@ -561,6 +675,208 @@ "sw\t%3,-28(%0)\n\t" "sw\t%4,-24(%0)\n\t" "sw\t%5,-20(%0)\n\t" + "cache\t%9,-16(%0)\n\t" + "lw\t%2,-16(%1)\n\t" + "lw\t%3,-12(%1)\n\t" + "lw\t%4,-8(%1)\n\t" + "lw\t%5,-4(%1)\n\t" + "sw\t%2,-16(%0)\n\t" + "sw\t%3,-12(%0)\n\t" + "sw\t%4,-8(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sw\t%5,-4(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +static void r4k_copy_page_s32(unsigned long to, unsigned long from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tcache\t%9,(%0)\n\t" + "lw\t%2,(%1)\n\t" + "lw\t%3,4(%1)\n\t" + "lw\t%4,8(%1)\n\t" + "lw\t%5,12(%1)\n\t" + "sw\t%2,(%0)\n\t" + "sw\t%3,4(%0)\n\t" + "sw\t%4,8(%0)\n\t" + "sw\t%5,12(%0)\n\t" + "lw\t%2,16(%1)\n\t" + "lw\t%3,20(%1)\n\t" + "lw\t%4,24(%1)\n\t" + "lw\t%5,28(%1)\n\t" + "sw\t%2,16(%0)\n\t" + "sw\t%3,20(%0)\n\t" + "sw\t%4,24(%0)\n\t" + "sw\t%5,28(%0)\n\t" + "cache\t%9,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "lw\t%2,-32(%1)\n\t" + "lw\t%3,-28(%1)\n\t" + "lw\t%4,-24(%1)\n\t" + "lw\t%5,-20(%1)\n\t" + "sw\t%2,-32(%0)\n\t" + "sw\t%3,-28(%0)\n\t" + "sw\t%4,-24(%0)\n\t" + "sw\t%5,-20(%0)\n\t" + "lw\t%2,-16(%1)\n\t" + "lw\t%3,-12(%1)\n\t" + "lw\t%4,-8(%1)\n\t" + "lw\t%5,-4(%1)\n\t" + "sw\t%2,-16(%0)\n\t" + "sw\t%3,-12(%0)\n\t" + "sw\t%4,-8(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sw\t%5,-4(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +static void r4k_copy_page_s64(unsigned long to, unsigned long from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tcache\t%9,(%0)\n\t" + "lw\t%2,(%1)\n\t" + "lw\t%3,4(%1)\n\t" + "lw\t%4,8(%1)\n\t" + "lw\t%5,12(%1)\n\t" + "sw\t%2,(%0)\n\t" + "sw\t%3,4(%0)\n\t" + "sw\t%4,8(%0)\n\t" + "sw\t%5,12(%0)\n\t" + "lw\t%2,16(%1)\n\t" + "lw\t%3,20(%1)\n\t" + "lw\t%4,24(%1)\n\t" + "lw\t%5,28(%1)\n\t" + "sw\t%2,16(%0)\n\t" + "sw\t%3,20(%0)\n\t" + "sw\t%4,24(%0)\n\t" + "sw\t%5,28(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "lw\t%2,-32(%1)\n\t" + "lw\t%3,-28(%1)\n\t" + "lw\t%4,-24(%1)\n\t" + "lw\t%5,-20(%1)\n\t" + "sw\t%2,-32(%0)\n\t" + "sw\t%3,-28(%0)\n\t" + "sw\t%4,-24(%0)\n\t" + "sw\t%5,-20(%0)\n\t" + "lw\t%2,-16(%1)\n\t" + "lw\t%3,-12(%1)\n\t" + "lw\t%4,-8(%1)\n\t" + "lw\t%5,-4(%1)\n\t" + "sw\t%2,-16(%0)\n\t" + "sw\t%3,-12(%0)\n\t" + "sw\t%4,-8(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sw\t%5,-4(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +static void r4k_copy_page_s128(unsigned long to, unsigned long from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tcache\t%9,(%0)\n\t" + "lw\t%2,(%1)\n\t" + "lw\t%3,4(%1)\n\t" + "lw\t%4,8(%1)\n\t" + "lw\t%5,12(%1)\n\t" + "sw\t%2,(%0)\n\t" + "sw\t%3,4(%0)\n\t" + "sw\t%4,8(%0)\n\t" + "sw\t%5,12(%0)\n\t" + "lw\t%2,16(%1)\n\t" + "lw\t%3,20(%1)\n\t" + "lw\t%4,24(%1)\n\t" + "lw\t%5,28(%1)\n\t" + "sw\t%2,16(%0)\n\t" + "sw\t%3,20(%0)\n\t" + "sw\t%4,24(%0)\n\t" + "sw\t%5,28(%0)\n\t" + "lw\t%2,32(%1)\n\t" + "lw\t%3,36(%1)\n\t" + "lw\t%4,40(%1)\n\t" + "lw\t%5,44(%1)\n\t" + "sw\t%2,32(%0)\n\t" + "sw\t%3,36(%0)\n\t" + "sw\t%4,40(%0)\n\t" + "sw\t%5,44(%0)\n\t" + "lw\t%2,48(%1)\n\t" + "lw\t%3,52(%1)\n\t" + "lw\t%4,56(%1)\n\t" + "lw\t%5,60(%1)\n\t" + "sw\t%2,48(%0)\n\t" + "sw\t%3,52(%0)\n\t" + "sw\t%4,56(%0)\n\t" + "sw\t%5,60(%0)\n\t" + "daddiu\t%0,128\n\t" + "daddiu\t%1,128\n\t" + "lw\t%2,-64(%1)\n\t" + "lw\t%3,-60(%1)\n\t" + "lw\t%4,-56(%1)\n\t" + "lw\t%5,-52(%1)\n\t" + "sw\t%2,-64(%0)\n\t" + "sw\t%3,-60(%0)\n\t" + "sw\t%4,-56(%0)\n\t" + "sw\t%5,-52(%0)\n\t" + "lw\t%2,-48(%1)\n\t" + "lw\t%3,-44(%1)\n\t" + "lw\t%4,-40(%1)\n\t" + "lw\t%5,-36(%1)\n\t" + "sw\t%2,-48(%0)\n\t" + "sw\t%3,-44(%0)\n\t" + "sw\t%4,-40(%0)\n\t" + "sw\t%5,-36(%0)\n\t" + "lw\t%2,-32(%1)\n\t" + "lw\t%3,-28(%1)\n\t" + "lw\t%4,-24(%1)\n\t" + "lw\t%5,-20(%1)\n\t" + "sw\t%2,-32(%0)\n\t" + "sw\t%3,-28(%0)\n\t" + "sw\t%4,-24(%0)\n\t" + "sw\t%5,-20(%0)\n\t" "lw\t%2,-16(%1)\n\t" "lw\t%3,-12(%1)\n\t" "lw\t%4,-8(%1)\n\t" @@ -576,9 +892,11 @@ :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) :"0" (to), "1" (from), - "I" (PAGE_SIZE)); + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); } + /* * If you think for one second that this stuff coming up is a lot * of bulky code eating too many kernel cache lines. Think _again_. @@ -628,15 +946,6 @@ restore_flags(flags); } -static inline void r4k_flush_cache_all_s16d32i32(void) -{ - unsigned long flags; - - save_and_cli(flags); - blast_dcache32(); blast_icache32(); blast_scache16(); - restore_flags(flags); -} - static inline void r4k_flush_cache_all_s32d32i32(void) { unsigned long flags; @@ -714,12 +1023,8 @@ pmd = pmd_offset(pgd, start); pte = pte_offset(pmd, start); - if(pte_val(*pte) & _PAGE_VALID) { - blast_dcache16_page(start); - if(text) - blast_icache16_page(start); + if(pte_val(*pte) & _PAGE_VALID) blast_scache16_page(start); - } start += PAGE_SIZE; } restore_flags(flags); @@ -759,12 +1064,8 @@ pmd = pmd_offset(pgd, start); pte = pte_offset(pmd, start); - if(pte_val(*pte) & _PAGE_VALID) { - blast_dcache16_page(start); - if(text) - blast_icache16_page(start); + if(pte_val(*pte) & _PAGE_VALID) blast_scache32_page(start); - } start += PAGE_SIZE; } restore_flags(flags); @@ -803,12 +1104,8 @@ pmd = pmd_offset(pgd, start); pte = pte_offset(pmd, start); - if(pte_val(*pte) & _PAGE_VALID) { - blast_dcache16_page(start); - if(text) - blast_icache16_page(start); + if(pte_val(*pte) & _PAGE_VALID) blast_scache64_page(start); - } start += PAGE_SIZE; } restore_flags(flags); @@ -847,56 +1144,8 @@ pmd = pmd_offset(pgd, start); pte = pte_offset(pmd, start); - if(pte_val(*pte) & _PAGE_VALID) { - blast_dcache16_page(start); - if(text) - blast_icache16_page(start); + if(pte_val(*pte) & _PAGE_VALID) blast_scache128_page(start); - } - start += PAGE_SIZE; - } - restore_flags(flags); - } - } -} - -static void r4k_flush_cache_range_s16d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - unsigned long flags; - - if(mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if(mm->context != current->mm->context) { - r4k_flush_cache_all_s16d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - int text; - - save_and_cli(flags); - text = vma->vm_flags & VM_EXEC; - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) { - blast_dcache32_page(start); - if(text) - blast_icache32_page(start); - blast_scache16_page(start); - } start += PAGE_SIZE; } restore_flags(flags); @@ -935,12 +1184,8 @@ pmd = pmd_offset(pgd, start); pte = pte_offset(pmd, start); - if(pte_val(*pte) & _PAGE_VALID) { - blast_dcache32_page(start); - if(text) - blast_icache32_page(start); + if(pte_val(*pte) & _PAGE_VALID) blast_scache32_page(start); - } start += PAGE_SIZE; } restore_flags(flags); @@ -979,12 +1224,8 @@ pmd = pmd_offset(pgd, start); pte = pte_offset(pmd, start); - if(pte_val(*pte) & _PAGE_VALID) { - blast_dcache32_page(start); - if(text) - blast_icache32_page(start); + if(pte_val(*pte) & _PAGE_VALID) blast_scache64_page(start); - } start += PAGE_SIZE; } restore_flags(flags); @@ -1023,12 +1264,8 @@ pmd = pmd_offset(pgd, start); pte = pte_offset(pmd, start); - if(pte_val(*pte) & _PAGE_VALID) { - blast_dcache32_page(start); - if(text) - blast_icache32_page(start); + if(pte_val(*pte) & _PAGE_VALID) blast_scache128_page(start); - } start += PAGE_SIZE; } restore_flags(flags); @@ -1113,16 +1350,6 @@ } } -static void r4k_flush_cache_mm_s16d32i32(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s16d32i32(); - } -} - static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm) { if(mm->context != 0) { @@ -1221,12 +1448,8 @@ if(text) blast_icache16_page_indexed(page); blast_scache16_page_indexed(page); - } else { - blast_dcache16_page(page); - if(text) - blast_icache16_page(page); + } else blast_scache16_page(page); - } out: restore_flags(flags); } @@ -1278,12 +1501,8 @@ if(text) blast_icache16_page_indexed(page); blast_scache32_page_indexed(page); - } else { - blast_dcache16_page(page); - if(text) - blast_icache16_page(page); + } else blast_scache32_page(page); - } out: restore_flags(flags); } @@ -1336,12 +1555,8 @@ if(text) blast_icache16_page_indexed(page); blast_scache64_page_indexed(page); - } else { - blast_dcache16_page(page); - if(text) - blast_icache16_page(page); + } else blast_scache64_page(page); - } out: restore_flags(flags); } @@ -1395,70 +1610,8 @@ if(text) blast_icache16_page_indexed(page); blast_scache128_page_indexed(page); - } else { - blast_dcache16_page(page); - if(text) - blast_icache16_page(page); + } else blast_scache128_page(page); - } -out: - restore_flags(flags); -} - -static void r4k_flush_cache_page_s16d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int text; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if(mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - text = (vma->vm_flags & VM_EXEC); - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if(mm->context != current->mm->context) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - if(text) - blast_icache32_page_indexed(page); - blast_scache16_page_indexed(page); - } else { - blast_dcache32_page(page); - if(text) - blast_icache32_page(page); - blast_scache16_page(page); - } out: restore_flags(flags); } @@ -1513,12 +1666,8 @@ if(text) blast_icache32_page_indexed(page); blast_scache32_page_indexed(page); - } else { - blast_dcache32_page(page); - if(text) - blast_icache32_page(page); + } else blast_scache32_page(page); - } out: restore_flags(flags); } @@ -1573,12 +1722,8 @@ if(text) blast_icache32_page_indexed(page); blast_scache64_page_indexed(page); - } else { - blast_dcache32_page(page); - if(text) - blast_icache32_page(page); + } else blast_scache64_page(page); - } out: restore_flags(flags); } @@ -1631,12 +1776,8 @@ if(text) blast_icache32_page_indexed(page); blast_scache128_page_indexed(page); - } else { - blast_dcache32_page(page); - if(text) - blast_icache32_page(page); + } else blast_scache128_page(page); - } out: restore_flags(flags); } @@ -1828,15 +1969,10 @@ { page &= PAGE_MASK; if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) { - unsigned long flags; - #ifdef DEBUG_CACHE printk("cram[%08lx]", page); #endif - save_and_cli(flags); - blast_dcache16_page(page); blast_scache16_page(page); - restore_flags(flags); } } @@ -1844,15 +1980,10 @@ { page &= PAGE_MASK; if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) { - unsigned long flags; - #ifdef DEBUG_CACHE printk("cram[%08lx]", page); #endif - save_and_cli(flags); - blast_dcache16_page(page); blast_scache32_page(page); - restore_flags(flags); } } @@ -1860,15 +1991,10 @@ { page &= PAGE_MASK; if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) { - unsigned long flags; - #ifdef DEBUG_CACHE printk("cram[%08lx]", page); #endif - save_and_cli(flags); - blast_dcache16_page(page); blast_scache64_page(page); - restore_flags(flags); } } @@ -1876,31 +2002,10 @@ { page &= PAGE_MASK; if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) { - unsigned long flags; - #ifdef DEBUG_CACHE printk("cram[%08lx]", page); #endif - save_and_cli(flags); - blast_dcache16_page(page); blast_scache128_page(page); - restore_flags(flags); - } -} - -static void r4k_flush_page_to_ram_s16d32i32(unsigned long page) -{ - page &= PAGE_MASK; - if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("cram[%08lx]", page); -#endif - save_and_cli(flags); - blast_dcache32_page(page); - blast_scache16_page(page); - restore_flags(flags); } } @@ -1908,15 +2013,10 @@ { page &= PAGE_MASK; if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) { - unsigned long flags; - #ifdef DEBUG_CACHE printk("cram[%08lx]", page); #endif - save_and_cli(flags); - blast_dcache32_page(page); blast_scache32_page(page); - restore_flags(flags); } } @@ -1924,15 +2024,10 @@ { page &= PAGE_MASK; if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) { - unsigned long flags; - #ifdef DEBUG_CACHE printk("cram[%08lx]", page); #endif - save_and_cli(flags); - blast_dcache32_page(page); blast_scache64_page(page); - restore_flags(flags); } } @@ -1940,15 +2035,10 @@ { page &= PAGE_MASK; if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) { - unsigned long flags; - #ifdef DEBUG_CACHE printk("cram[%08lx]", page); #endif - save_and_cli(flags); - blast_dcache32_page(page); blast_scache128_page(page); - restore_flags(flags); } } @@ -2022,20 +2112,10 @@ r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) { unsigned long end, a; - unsigned int flags; if (size >= scache_size) { flush_cache_all(); - } else { - save_and_cli(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - restore_flags(flags); + return; } a = addr & ~(sc_lsize - 1); @@ -2077,20 +2157,10 @@ r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size) { unsigned long end, a; - unsigned int flags; if (size >= scache_size) { flush_cache_all(); - } else { - save_and_cli(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - restore_flags(flags); + return; } a = addr & ~(sc_lsize - 1); @@ -2287,7 +2357,7 @@ unsigned long *p = (unsigned long *) page; int i; - for(i = 0; i < 1024; i+=8) { + for(i = 0; i < USER_PTRS_PER_PGD; i+=8) { p[i + 0] = (unsigned long) invalid_pte_table; p[i + 1] = (unsigned long) invalid_pte_table; p[i + 2] = (unsigned long) invalid_pte_table; @@ -2344,32 +2414,9 @@ BARRIER; if(idx < 0) { tlb_write_random(); -#if 0 - BARRIER; - printk("[MISS]"); -#endif } else { tlb_write_indexed(); -#if 0 - BARRIER; - printk("[HIT]"); -#endif } -#if 0 - if(!strcmp(current->comm, "args")) { - printk("<"); - for(idx = 0; idx < NTLB_ENTRIES; idx++) { - BARRIER; - set_index(idx); BARRIER; - tlb_read(); BARRIER; - address = get_entryhi(); BARRIER; - if((address & 0xff) != 0) - printk("[%08lx]", address); - } - printk(">"); - } - BARRIER; -#endif BARRIER; set_entryhi(pid); BARRIER; @@ -2465,8 +2512,8 @@ /* Detect and size the various r4k caches. */ __initfunc(static void probe_icache(unsigned long config)) { - icache_size = 1 << (12 + ((config >> 6) & 7)); - ic_lsize = 16 << ((config >> 4) & 1); + icache_size = 1 << (12 + ((config >> 9) & 7)); + ic_lsize = 16 << ((config >> 5) & 1); printk("Primary instruction cache %dkb, linesize %d bytes)\n", icache_size >> 10, ic_lsize); @@ -2565,8 +2612,8 @@ } restore_flags(flags); addr -= begin; - printk("Secondary cache sized at %dK linesize %d\n", (int) (addr >> 10), - sc_lsize); + printk("Secondary cache sized at %dK linesize %d\n", + (int) (addr >> 10), sc_lsize); scache_size = addr; return 1; } @@ -2621,13 +2668,10 @@ flush_page_to_ram = r4k_flush_page_to_ram_s16d16i16; break; case 32: - flush_cache_all = r4k_flush_cache_all_s16d32i32; - flush_cache_mm = r4k_flush_cache_mm_s16d32i32; - flush_cache_range = r4k_flush_cache_range_s16d32i32; - flush_cache_page = r4k_flush_cache_page_s16d32i32; - flush_page_to_ram = r4k_flush_page_to_ram_s16d32i32; - break; + panic("Invalid cache configuration detected"); }; + clear_page = r4k_clear_page_s16; + copy_page = r4k_copy_page_s16; break; case 32: switch(dc_lsize) { @@ -2646,6 +2690,9 @@ flush_page_to_ram = r4k_flush_page_to_ram_s32d32i32; break; }; + clear_page = r4k_clear_page_s32; + copy_page = r4k_copy_page_s32; + break; case 64: switch(dc_lsize) { case 16: @@ -2663,6 +2710,9 @@ flush_page_to_ram = r4k_flush_page_to_ram_s64d32i32; break; }; + clear_page = r4k_clear_page_s64; + copy_page = r4k_copy_page_s64; + break; case 128: switch(dc_lsize) { case 16: @@ -2680,10 +2730,10 @@ flush_page_to_ram = r4k_flush_page_to_ram_s128d32i32; break; }; + clear_page = r4k_clear_page_s128; + copy_page = r4k_copy_page_s128; break; } - clear_page = r4k_clear_page; - copy_page = r4k_copy_page; dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc; dma_cache_inv = r4k_dma_cache_inv_sc; } @@ -2712,14 +2762,13 @@ return (regs->cp0_status & ST0_KSU) == KSU_USER; } - __initfunc(void ld_mmu_r4xx0(void)) { unsigned long config = read_32bit_cp0_register(CP0_CONFIG); printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID)); - set_cp0_config(CONF_REG_CM_CMASK, CONF_REG_CM_CACHABLE_NONCOHERENT); + set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT); probe_icache(config); probe_dcache(config); @@ -2742,6 +2791,7 @@ flush_tlb_mm = r4k_flush_tlb_mm; flush_tlb_range = r4k_flush_tlb_range; flush_tlb_page = r4k_flush_tlb_page; + r4xx0_asid_setup(); load_pgd = r4k_load_pgd; pgd_init = r4k_pgd_init; diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/r6000.c linux/arch/mips/mm/r6000.c --- v2.1.125/linux/arch/mips/mm/r6000.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/mm/r6000.c Tue Oct 20 13:52:55 1998 @@ -1,4 +1,5 @@ -/* $Id: r6000.c,v 1.4 1998/05/01 01:35:06 ralf Exp $ +/* $Id: r6000.c,v 1.6 1998/10/16 19:22:44 ralf Exp $ + * * r6000.c: MMU and cache routines for the R6000 processors. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) @@ -13,6 +14,7 @@ #include #include #include +#include __asm__(".set mips3"); /* because we know... */ @@ -109,7 +111,7 @@ "=r" (dummy2) :"r" ((unsigned long) invalid_pte_table), "0" (page), - "1" (PAGE_SIZE/(sizeof(pmd_t)*8)), + "1" (USER_PTRS_PER_PGD/8), "i" (Create_Dirty_Excl_D)); } @@ -180,6 +182,7 @@ flush_tlb_mm = r6000_flush_tlb_mm; flush_tlb_range = r6000_flush_tlb_range; flush_tlb_page = r6000_flush_tlb_page; + r6000_asid_setup(); load_pgd = r6000_load_pgd; pgd_init = r6000_pgd_init; diff -u --recursive --new-file v2.1.125/linux/arch/mips/mm/tfp.c linux/arch/mips/mm/tfp.c --- v2.1.125/linux/arch/mips/mm/tfp.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/mm/tfp.c Tue Oct 20 13:52:55 1998 @@ -1,4 +1,5 @@ -/* +/* $Id: tfp.c,v 1.6 1998/10/16 19:22:44 ralf Exp $ + * * tfp.c: MMU and cache routines specific to the r8000 (TFP). * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) @@ -13,6 +14,7 @@ #include #include #include +#include extern unsigned long mips_tlb_entries; @@ -104,6 +106,7 @@ flush_tlb_mm = tfp_flush_tlb_mm; flush_tlb_range = tfp_flush_tlb_range; flush_tlb_page = tfp_flush_tlb_page; + tfp_asid_setup(); add_wired_entry = tfp_add_wired_entry; diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/Makefile linux/arch/mips/sgi/kernel/Makefile --- v2.1.125/linux/arch/mips/sgi/kernel/Makefile Fri May 8 23:14:43 1998 +++ linux/arch/mips/sgi/kernel/Makefile Tue Oct 20 13:52:55 1998 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.2 1998/05/01 01:35:13 ralf Exp $ +# $Id: Makefile,v 1.3 1998/06/25 20:19:17 ralf Exp $ # Makefile for the SGI specific kernel interface routines # under Linux. # @@ -13,8 +13,8 @@ .S.o: $(CC) $(CFLAGS) -c $< -o $*.o -OBJS = indy_mc.o indy_sc.o indy_hpc.o indy_int.o system.o indy_timer.o \ - indyIRQ.o reset.o setup.o time.o +OBJS = indy_mc.o indy_sc.o indy_hpc.o indy_int.o indy_rtc.o system.o \ + indy_timer.o indyIRQ.o reset.o setup.o time.o all: sgikern.a diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indyIRQ.S linux/arch/mips/sgi/kernel/indyIRQ.S --- v2.1.125/linux/arch/mips/sgi/kernel/indyIRQ.S Fri May 8 23:14:43 1998 +++ linux/arch/mips/sgi/kernel/indyIRQ.S Tue Oct 20 13:52:55 1998 @@ -1,4 +1,4 @@ -/* $Id: indyIRQ.S,v 1.3 1998/05/01 01:35:14 ralf Exp $ +/* $Id: indyIRQ.S,v 1.3 1998/03/21 22:39:53 ralf Exp $ * indyIRQ.S: Interrupt exception dispatch code for FullHouse and * Guiness. * diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_hpc.c linux/arch/mips/sgi/kernel/indy_hpc.c --- v2.1.125/linux/arch/mips/sgi/kernel/indy_hpc.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/sgi/kernel/indy_hpc.c Tue Oct 20 13:52:55 1998 @@ -1,15 +1,13 @@ -/* +/* $Id: indy_hpc.c,v 1.4 1998/07/14 09:12:27 ralf Exp $ + * * indy_hpc.c: Routines for generic manipulation of the HPC controllers. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: indy_hpc.c,v 1.2 1998/05/01 01:35:14 ralf Exp $ + * Copyright (C) 1998 Ralf Baechle */ #include #include -#include -#include #include #include #include @@ -20,27 +18,13 @@ struct hpc3_miscregs *hpc3mregs; /* We need software copies of these because they are write only. */ -static unsigned long write1, write2; +unsigned long sgi_hpc_write1, sgi_hpc_write2; /* Machine specific identifier knobs. */ int sgi_has_ioc2 = 0; int sgi_guiness = 0; int sgi_boardid; -void sgihpc_write1_modify(int set, int clear) -{ - write1 |= set; - write1 &= ~clear; - hpc3mregs->write1 = write1; -} - -void sgihpc_write2_modify(int set, int clear) -{ - write2 |= set; - write2 &= ~clear; - hpc3mregs->write2 = write2; -} - __initfunc(void sgihpc_init(void)) { unsigned long sid, crev, brev; @@ -96,12 +80,12 @@ prom_printf("\n"); #endif - write1 = (HPC3_WRITE1_PRESET | + sgi_hpc_write1 = (HPC3_WRITE1_PRESET | HPC3_WRITE1_KMRESET | HPC3_WRITE1_ERESET | HPC3_WRITE1_LC0OFF); - write2 = (HPC3_WRITE2_EASEL | + sgi_hpc_write2 = (HPC3_WRITE2_EASEL | HPC3_WRITE2_NTHRESH | HPC3_WRITE2_TPSPEED | HPC3_WRITE2_EPSEL | @@ -109,9 +93,9 @@ HPC3_WRITE2_U1AMODE); if(!sgi_guiness) - write1 |= HPC3_WRITE1_GRESET; - hpc3mregs->write1 = write1; - hpc3mregs->write2 = write2; + sgi_hpc_write1 |= HPC3_WRITE1_GRESET; + hpc3mregs->write1 = sgi_hpc_write1; + hpc3mregs->write2 = sgi_hpc_write2; hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW; } diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_int.c linux/arch/mips/sgi/kernel/indy_int.c --- v2.1.125/linux/arch/mips/sgi/kernel/indy_int.c Thu Aug 6 14:06:29 1998 +++ linux/arch/mips/sgi/kernel/indy_int.c Tue Oct 20 13:52:55 1998 @@ -1,13 +1,14 @@ -/* +/* $Id: indy_int.c,v 1.9 1998/05/28 03:18:00 ralf Exp $ + * * indy_int.c: Routines for generic manipulation of the INT[23] ASIC * found on INDY workstations.. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: indy_int.c,v 1.7 1998/05/07 00:39:51 ralf Exp $ + * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) */ #include #include + #include #include #include @@ -27,7 +28,6 @@ #include #include #include -#include #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_mc.c linux/arch/mips/sgi/kernel/indy_mc.c --- v2.1.125/linux/arch/mips/sgi/kernel/indy_mc.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/sgi/kernel/indy_mc.c Tue Oct 20 13:52:55 1998 @@ -3,14 +3,13 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: indy_mc.c,v 1.3 1998/05/04 09:18:37 ralf Exp $ + * $Id: indy_mc.c,v 1.3 1998/04/25 15:43:32 ralf Exp $ */ #include #include #include #include -#include #include #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_rtc.c linux/arch/mips/sgi/kernel/indy_rtc.c --- v2.1.125/linux/arch/mips/sgi/kernel/indy_rtc.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/sgi/kernel/indy_rtc.c Tue Oct 20 13:52:55 1998 @@ -0,0 +1,37 @@ +/* $Id: indy_rtc.c,v 1.1 1998/06/25 20:19:17 ralf Exp $ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * RTC routines for Indy style attached Dallas chip. + * + * Copyright (C) 1998 by Ralf Baechle + */ +#include +#include + +static unsigned char indy_rtc_read_data(unsigned long addr) +{ + volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; + + return rtcregs[addr]; +} + +static void indy_rtc_write_data(unsigned char data, unsigned long addr) +{ + volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; + + rtcregs[addr] = data; +} + +static int indy_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops indy_rtc_ops = { + &indy_rtc_read_data, + &indy_rtc_write_data, + &indy_rtc_bcd_mode +}; diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_sc.c linux/arch/mips/sgi/kernel/indy_sc.c --- v2.1.125/linux/arch/mips/sgi/kernel/indy_sc.c Wed May 20 19:10:37 1998 +++ linux/arch/mips/sgi/kernel/indy_sc.c Tue Oct 20 13:52:55 1998 @@ -1,15 +1,16 @@ -/* +/* $Id: indy_sc.c,v 1.9 1998/08/17 12:14:55 ralf Exp $ + * * indy_sc.c: Indy cache managment functions. * * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org), * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). - * - * $Id: indy_sc.c,v 1.4 1998/05/04 09:12:57 ralf Exp $ */ +#include #include #include #include #include +#include #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/indy_timer.c linux/arch/mips/sgi/kernel/indy_timer.c --- v2.1.125/linux/arch/mips/sgi/kernel/indy_timer.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/sgi/kernel/indy_timer.c Tue Oct 20 13:52:55 1998 @@ -1,9 +1,9 @@ -/* +/* $Id: indy_timer.c,v 1.9 1998/06/25 20:15:02 ralf Exp $ + * * indy_timer.c: Setting up the clock on the INDY 8254 controller. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: indy_timer.c,v 1.5 1998/05/01 01:35:17 ralf Exp $ + * Copytight (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) */ #include #include @@ -26,26 +26,6 @@ #include #include -/* The layout of registers for the INDY Dallas 1286 clock chipset. */ -struct indy_clock { - volatile unsigned int hsec; - volatile unsigned int sec; - volatile unsigned int min; - volatile unsigned int malarm; - volatile unsigned int hr; - volatile unsigned int halarm; - volatile unsigned int day; - volatile unsigned int dalarm; - volatile unsigned int date; - volatile unsigned int month; - volatile unsigned int year; - volatile unsigned int cmd; - volatile unsigned int whsec; - volatile unsigned int wsec; - volatile unsigned int _unused0[50]; -}; - -#define INDY_CLOCK_REGS ((struct indy_clock *)(KSEG1ADDR(0x1fbe0000))) /* Because of a bug in the i8254 timer we need to use the onchip r4k * counter as our system wide timer interrupt running at 100HZ. @@ -60,7 +40,7 @@ static int set_rtc_mmss(unsigned long nowtime) { - struct indy_clock *clock = INDY_CLOCK_REGS; + struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; int retval = 0; int real_seconds, real_minutes, clock_minutes; @@ -197,7 +177,7 @@ __initfunc(static unsigned long get_indy_time(void)) { - struct indy_clock *clock = INDY_CLOCK_REGS; + struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; unsigned int year, mon, day, hour, min, sec; /* Freeze it. */ diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/reset.c linux/arch/mips/sgi/kernel/reset.c --- v2.1.125/linux/arch/mips/sgi/kernel/reset.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/sgi/kernel/reset.c Tue Oct 20 13:52:55 1998 @@ -1,31 +1,200 @@ -/* - * Reset a SGI. +/* $Id: reset.c,v 1.6 1998/07/09 19:57:47 ralf Exp $ + * + * Reset a SGI. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1997, 1998 by Ralf Baechle - * - * $Id: reset.c,v 1.3 1998/05/01 01:35:18 ralf Exp $ */ +#include +#include +#include +#include #include +#include #include #include #include +#include +#include + +/* + * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds. + * I'm not shure if this feature is a good idea, for now it's here just to + * make the power button make behave just like under IRIX. + */ +#define POWERDOWN_TIMEOUT 120 + +/* + * Blink frequency during reboot grace period and when paniced. + */ +#define POWERDOWN_FREQ (HZ / 4) +#define PANIC_FREQ (HZ / 8) + +static struct timer_list power_timer, blink_timer, debounce_timer; +static int shuting_down, has_paniced; + +static void sgi_machine_restart(char *command) __attribute__((noreturn)); +static void sgi_machine_halt(void) __attribute__((noreturn)); +static void sgi_machine_power_off(void) __attribute__((noreturn)); /* XXX How to pass the reboot command to the firmware??? */ -void sgi_machine_restart(char *command) +static void sgi_machine_restart(char *command) { + if (shuting_down) + sgi_machine_power_off(); prom_reboot(); } -void sgi_machine_halt(void) +static void sgi_machine_halt(void) { + if (shuting_down) + sgi_machine_power_off(); prom_imode(); } -void sgi_machine_power_off(void) +static void sgi_machine_power_off(void) +{ + struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; + + cli(); + + clock->cmd |= 0x08; /* Disable watchdog */ + clock->whsec = 0; + clock->wsec = 0; + + while(1) { + hpc3mregs->panel=0xfe; + /* Good bye cruel world ... */ + + /* If we're still running, we probably got sent an alarm + interrupt. Read the flag to clear it. */ + clock->halarm; + } +} + +static void power_timeout(unsigned long data) +{ + sgi_machine_power_off(); +} + +static void blink_timeout(unsigned long data) { - prom_powerdown(); + /* XXX fix this for fullhouse */ + sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF); + hpc3mregs->write1 = sgi_hpc_write1; + + del_timer(&blink_timer); + blink_timer.expires = jiffies + data; + add_timer(&blink_timer); +} + +static void debounce(unsigned long data) +{ + del_timer(&debounce_timer); + if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent. */ + debounce_timer.expires = jiffies + 5; /* 0.05s */ + add_timer(&debounce_timer); + + hpc3mregs->panel = 0xf3; + + return; + } + + if (has_paniced) + prom_reboot(); + + enable_irq(9); +} + +static inline void power_button(void) +{ + if (has_paniced) + return; + + if (shuting_down || kill_proc(1, SIGINT, 1)) { + /* No init process or button pressed twice. */ + sgi_machine_power_off(); + } + + shuting_down = 1; + blink_timer.data = POWERDOWN_FREQ; + blink_timeout(POWERDOWN_FREQ); + + init_timer(&power_timer); + power_timer.function = power_timeout; + power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ; + add_timer(&power_timer); +} + +static inline void volume_up_button(void) +{ + /* Later when we have sound support ... */ +} + +static inline void volume_down_button(void) +{ + /* Later when we have sound support ... */ +} + +static void panel_int(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int buttons; + + buttons = hpc3mregs->panel; + hpc3mregs->panel = 3; /* power_interrupt | power_supply_on */ + + if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */ + disable_irq(9); + init_timer(&debounce_timer); + debounce_timer.function = debounce; + debounce_timer.expires = jiffies + 5; + add_timer(&debounce_timer); + } + + if (!(buttons & 2)) /* Power button was pressed */ + power_button(); + if (!(buttons & 0x40)) /* Volume up button was pressed */ + volume_up_button(); + if (!(buttons & 0x10)) /* Volume down button was pressed */ + volume_down_button(); +} + +static int panic_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + if (has_paniced) + return NOTIFY_DONE; + has_paniced = 1; + + blink_timer.data = PANIC_FREQ; + blink_timeout(PANIC_FREQ); + + return NOTIFY_DONE; +} + +static struct notifier_block panic_block = { + panic_event, + NULL, + 0 +}; + +void indy_reboot_setup(void) +{ + static int setup_done; + + if (setup_done) + return; + setup_done = 1; + + _machine_restart = sgi_machine_restart; + _machine_halt = sgi_machine_halt; + _machine_power_off = sgi_machine_power_off; + + request_irq(9, panel_int, 0, "Front Panel", NULL); + init_timer(&blink_timer); + blink_timer.function = blink_timeout; + notifier_chain_register(&panic_notifier_list, &panic_block); } diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/setup.c linux/arch/mips/sgi/kernel/setup.c --- v2.1.125/linux/arch/mips/sgi/kernel/setup.c Thu Aug 6 14:06:29 1998 +++ linux/arch/mips/sgi/kernel/setup.c Tue Oct 20 13:52:55 1998 @@ -1,32 +1,34 @@ -/* $Id: setup.c,v 1.6 1998/05/07 00:39:53 ralf Exp $ +/* $Id: setup.c,v 1.13 1998/09/16 22:50:46 ralf Exp $ * * setup.c: SGI specific setup, including init of the feature struct. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) */ #include +#include #include +#include +#include +#include #include +#include #include #include #include +#include #include -#include #include #include #include #include #include -extern int serial_console; /* in console.c, of course */ +extern int serial_console; /* in sgiserial.c */ -extern void sgi_machine_restart(char *command); -extern void sgi_machine_halt(void); -extern void sgi_machine_power_off(void); - -struct feature sgi_feature = { -}; +extern struct rtc_ops indy_rtc_ops; +void indy_reboot_setup(void); static volatile struct hpc_keyb *sgi_kh = (struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64); @@ -68,6 +70,16 @@ kbd_write_output = sgi_write_output; kbd_write_command = sgi_write_command; kbd_read_status = sgi_read_status; + + request_irq(SGI_KEYBOARD_IRQ, keyboard_interrupt, + 0, "keyboard", NULL); + + /* Dirty hack, this get's called as a callback from the keyboard + driver. We piggyback the initialization of the front panel + button handling on it even though they're technically not + related with the keyboard driver in any way. Doing it from + indy_setup wouldn't work since kmalloc isn't initialized yet. */ + indy_reboot_setup(); } __initfunc(static void sgi_irq_setup(void)) @@ -77,16 +89,13 @@ __initfunc(void sgi_setup(void)) { +#ifdef CONFIG_SERIAL_CONSOLE char *ctype; +#endif irq_setup = sgi_irq_setup; - feature = &sgi_feature; keyboard_setup = sgi_keyboard_setup; - _machine_restart = sgi_machine_restart; - _machine_halt = sgi_machine_halt; - _machine_power_off = sgi_machine_power_off; - /* Init the INDY HPC I/O controller. Need to call this before * fucking with the memory controller because it needs to know the * boardID and whether this is a Guiness or a FullHouse machine. @@ -99,6 +108,7 @@ /* Now enable boardcaches, if any. */ indy_sc_init(); +#ifdef CONFIG_SERIAL_CONSOLE /* ARCS console environment variable is set to "g?" for * graphics console, it is set to "d" for the first serial * line and "d2" for the second serial line. @@ -117,4 +127,10 @@ prom_imode(); } } +#endif + +#ifdef CONFIG_VT + conswitchp = &newport_con; +#endif + rtc_ops = &indy_rtc_ops; } diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/system.c linux/arch/mips/sgi/kernel/system.c --- v2.1.125/linux/arch/mips/sgi/kernel/system.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/sgi/kernel/system.c Tue Oct 20 13:52:55 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: system.c,v 1.4 1998/05/01 01:35:19 ralf Exp $ + * $Id: system.c,v 1.4 1998/03/27 08:53:45 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/kernel/time.c linux/arch/mips/sgi/kernel/time.c --- v2.1.125/linux/arch/mips/sgi/kernel/time.c Fri May 8 23:14:43 1998 +++ linux/arch/mips/sgi/kernel/time.c Tue Oct 20 13:52:55 1998 @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.2 1998/05/01 01:35:20 ralf Exp $ +/* $Id: time.c,v 1.2 1998/03/27 08:53:45 ralf Exp $ * time.c: Generic SGI time_init() code, this will dispatch to the * appropriate per-architecture time/counter init code. * diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/Makefile linux/arch/mips/sgi/prom/Makefile --- v2.1.125/linux/arch/mips/sgi/prom/Makefile Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/Makefile Tue Oct 20 13:52:55 1998 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.2 1998/05/01 01:35:22 ralf Exp $ +# $Id: Makefile,v 1.1.1.1 1997/06/01 03:16:40 ralf Exp $ # Makefile for the SGI arcs prom monitor library routines # under Linux. # diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/cmdline.c linux/arch/mips/sgi/prom/cmdline.c --- v2.1.125/linux/arch/mips/sgi/prom/cmdline.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/cmdline.c Tue Oct 20 13:52:55 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: cmdline.c,v 1.3 1998/05/01 01:35:22 ralf Exp $ + * $Id: cmdline.c,v 1.3 1998/03/27 08:53:46 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/console.c linux/arch/mips/sgi/prom/console.c --- v2.1.125/linux/arch/mips/sgi/prom/console.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/console.c Tue Oct 20 13:52:55 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@sgi.com) * - * $Id: console.c,v 1.2 1998/05/01 01:35:23 ralf Exp $ + * $Id: console.c,v 1.2 1998/03/27 08:53:46 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/env.c linux/arch/mips/sgi/prom/env.c --- v2.1.125/linux/arch/mips/sgi/prom/env.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/env.c Tue Oct 20 13:52:55 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: env.c,v 1.2 1998/05/01 01:35:24 ralf Exp $ + * $Id: env.c,v 1.2 1998/03/27 08:53:46 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/file.c linux/arch/mips/sgi/prom/file.c --- v2.1.125/linux/arch/mips/sgi/prom/file.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/file.c Tue Oct 20 13:52:55 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: file.c,v 1.2 1998/05/01 01:35:24 ralf Exp $ + * $Id: file.c,v 1.2 1998/03/27 08:53:47 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/init.c linux/arch/mips/sgi/prom/init.c --- v2.1.125/linux/arch/mips/sgi/prom/init.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/init.c Tue Oct 20 13:52:55 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: init.c,v 1.2 1998/05/01 01:35:25 ralf Exp $ + * $Id: init.c,v 1.2 1998/03/27 08:53:47 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/memory.c linux/arch/mips/sgi/prom/memory.c --- v2.1.125/linux/arch/mips/sgi/prom/memory.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/memory.c Tue Oct 20 13:52:55 1998 @@ -4,7 +4,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: memory.c,v 1.2 1998/05/01 01:35:25 ralf Exp $ + * $Id: memory.c,v 1.2 1998/03/27 08:53:47 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/misc.c linux/arch/mips/sgi/prom/misc.c --- v2.1.125/linux/arch/mips/sgi/prom/misc.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/misc.c Tue Oct 20 13:52:55 1998 @@ -1,9 +1,8 @@ -/* +/* $Id: misc.c,v 1.6 1998/07/08 15:59:13 ralf Exp $ + * * misc.c: Miscellaneous ARCS PROM routines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: misc.c,v 1.2 1998/05/01 01:35:26 ralf Exp $ */ #include #include @@ -15,14 +14,12 @@ #include extern unsigned long mips_cputype; -extern int initialize_kbd(void); extern void *sgiwd93_host; extern void reset_wd33c93(void *instance); void prom_halt(void) { bcops->bc_disable(); - initialize_kbd(); cli(); #if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); @@ -33,7 +30,6 @@ void prom_powerdown(void) { bcops->bc_disable(); - initialize_kbd(); cli(); #if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); @@ -45,7 +41,6 @@ void prom_restart(void) { bcops->bc_disable(); - initialize_kbd(); cli(); #if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); @@ -56,7 +51,6 @@ void prom_reboot(void) { bcops->bc_disable(); - initialize_kbd(); cli(); #if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); @@ -67,7 +61,6 @@ void prom_imode(void) { bcops->bc_disable(); - initialize_kbd(); cli(); #if CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/printf.c linux/arch/mips/sgi/prom/printf.c --- v2.1.125/linux/arch/mips/sgi/prom/printf.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/printf.c Tue Oct 20 13:52:55 1998 @@ -4,7 +4,7 @@ * * Copyright (C) 1996 David S. Miller (dm@sgi.com) * - * $Id: printf.c,v 1.2 1998/05/01 01:35:27 ralf Exp $ + * $Id: printf.c,v 1.2 1998/03/27 08:53:48 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/salone.c linux/arch/mips/sgi/prom/salone.c --- v2.1.125/linux/arch/mips/sgi/prom/salone.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/salone.c Tue Oct 20 13:52:55 1998 @@ -4,7 +4,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: salone.c,v 1.2 1998/05/01 01:35:27 ralf Exp $ + * $Id: salone.c,v 1.2 1998/03/27 08:53:48 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/tags.c linux/arch/mips/sgi/prom/tags.c --- v2.1.125/linux/arch/mips/sgi/prom/tags.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/tags.c Tue Oct 20 13:52:55 1998 @@ -4,7 +4,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: tags.c,v 1.2 1998/05/01 01:35:28 ralf Exp $ + * $Id: tags.c,v 1.2 1998/03/27 08:53:48 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/time.c linux/arch/mips/sgi/prom/time.c --- v2.1.125/linux/arch/mips/sgi/prom/time.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/time.c Tue Oct 20 13:52:55 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: time.c,v 1.2 1998/05/01 01:35:29 ralf Exp $ + * $Id: time.c,v 1.2 1998/03/27 08:53:49 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sgi/prom/tree.c linux/arch/mips/sgi/prom/tree.c --- v2.1.125/linux/arch/mips/sgi/prom/tree.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sgi/prom/tree.c Tue Oct 20 13:52:55 1998 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: tree.c,v 1.2 1998/05/01 01:35:30 ralf Exp $ + * $Id: tree.c,v 1.2 1998/03/27 08:53:49 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/Makefile linux/arch/mips/sni/Makefile --- v2.1.125/linux/arch/mips/sni/Makefile Fri May 8 23:14:44 1998 +++ linux/arch/mips/sni/Makefile Tue Oct 20 13:52:55 1998 @@ -5,7 +5,7 @@ # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (ie not a .c file). # -# $Id: Makefile,v 1.2 1998/05/01 01:35:32 ralf Exp $ +# $Id: Makefile,v 1.2 1997/12/20 13:27:14 ralf Exp $ # .S.s: diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/hw-access.c linux/arch/mips/sni/hw-access.c --- v2.1.125/linux/arch/mips/sni/hw-access.c Thu Aug 6 14:06:29 1998 +++ linux/arch/mips/sni/hw-access.c Tue Oct 20 13:52:55 1998 @@ -1,4 +1,4 @@ -/* $Id: hw-access.c,v 1.5 1998/05/07 00:39:56 ralf Exp $ +/* $Id: hw-access.c,v 1.8 1998/09/16 22:50:46 ralf Exp $ * * Low-level hardware access stuff for SNI RM200 PCI * @@ -10,6 +10,7 @@ */ #include #include +#include #include #include #include @@ -23,144 +24,7 @@ #include #include #include -#include - -extern int FLOPPY_IRQ; -extern int FLOPPY_DMA; - -/* - * How to access the FDC's registers. - */ -static unsigned char -fd_inb(unsigned int port) -{ - return inb_p(port); -} - -static void -fd_outb(unsigned char value, unsigned int port) -{ - outb_p(value, port); -} - -/* - * How to access the floppy DMA functions. - */ -static void -fd_enable_dma(int channel) -{ - enable_dma(channel); -} - -static void -fd_disable_dma(int channel) -{ - disable_dma(channel); -} - -static int -fd_request_dma(int channel) -{ - return request_dma(channel, "floppy"); -} - -static void -fd_free_dma(int channel) -{ - free_dma(channel); -} - -static void -fd_clear_dma_ff(int channel) -{ - clear_dma_ff(channel); -} - -static void -fd_set_dma_mode(int channel, char mode) -{ - set_dma_mode(channel, mode); -} - -static void -fd_set_dma_addr(int channel, unsigned int addr) -{ - set_dma_addr(channel, addr); -} - -static void -fd_set_dma_count(int channel, unsigned int count) -{ - set_dma_count(channel, count); -} - -static int -fd_get_dma_residue(int channel) -{ - return get_dma_residue(channel); -} - -static void -fd_enable_irq(int irq) -{ - enable_irq(irq); -} - -static void -fd_disable_irq(int irq) -{ - disable_irq(irq); -} - -void -sni_fd_cacheflush(const void *addr, size_t size) -{ - flush_cache_all(); -} - -/* - * RTC stuff (This is a guess on how the RM handles this ...) - */ -static unsigned char -rtc_read_data(unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - return inb_p(RTC_PORT(1)); -} - -static void -rtc_write_data(unsigned char data, unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - outb_p(data, RTC_PORT(1)); -} - -struct feature sni_rm200_pci_feature = { - /* - * How to access the floppy controller's ports - */ - fd_inb, - fd_outb, - /* - * How to access the floppy DMA functions. - */ - fd_enable_dma, - fd_disable_dma, - fd_request_dma, - fd_free_dma, - fd_clear_dma_ff, - fd_set_dma_mode, - fd_set_dma_addr, - fd_set_dma_count, - fd_get_dma_residue, - fd_enable_irq, - fd_disable_irq, - /* - * How to access the RTC functions. - */ - rtc_read_data, - rtc_write_data -}; +#include #define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ @@ -200,5 +64,7 @@ kbd_write_output = sni_write_output; kbd_write_command = sni_write_command; kbd_read_status = sni_read_status; + request_irq(PCIMT_KEYBOARD_IRQ, keyboard_interrupt, + 0, "keyboard", NULL); request_region(0x60, 16, "keyboard"); } diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/int-handler.S linux/arch/mips/sni/int-handler.S --- v2.1.125/linux/arch/mips/sni/int-handler.S Thu Aug 6 14:06:29 1998 +++ linux/arch/mips/sni/int-handler.S Tue Oct 20 13:52:55 1998 @@ -1,4 +1,4 @@ -/* $Id: int-handler.S,v 1.4 1998/05/08 01:44:24 ralf Exp $ +/* $Id: int-handler.S,v 1.4 1998/05/07 14:17:47 ralf Exp $ * * SNI RM200 PCI specific interrupt handler code. * diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/io.c linux/arch/mips/sni/io.c --- v2.1.125/linux/arch/mips/sni/io.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sni/io.c Tue Oct 20 13:52:55 1998 @@ -5,7 +5,7 @@ * * Low level I/O functions for SNI. * - * $Id: io.c,v 1.2 1998/05/01 01:35:34 ralf Exp $ + * $Id: io.c,v 1.2 1998/03/27 08:53:50 ralf Exp $ */ #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/pci.c linux/arch/mips/sni/pci.c --- v2.1.125/linux/arch/mips/sni/pci.c Thu Aug 6 14:06:29 1998 +++ linux/arch/mips/sni/pci.c Tue Oct 20 13:52:55 1998 @@ -1,13 +1,14 @@ -/* $Id: pci.c,v 1.5 1998/05/08 01:44:26 ralf Exp $ +/* $Id: pci.c,v 1.6 1998/05/07 14:17:48 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * SNI specific PCI support for RM200/RM300. + * + * Copyright (C) 1997, 1998 Ralf Baechle */ #include -#include #include #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/pcimt_scache.c linux/arch/mips/sni/pcimt_scache.c --- v2.1.125/linux/arch/mips/sni/pcimt_scache.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/sni/pcimt_scache.c Tue Oct 20 13:52:55 1998 @@ -7,9 +7,10 @@ * * Copyright (c) 1997 by Ralf Baechle * - * $Id: pcimt_scache.c,v 1.1 1998/03/04 08:47:29 ralf Exp $ + * $Id: pcimt_scache.c,v 1.2 1998/05/28 03:18:02 ralf Exp $ */ #include +#include #include #include diff -u --recursive --new-file v2.1.125/linux/arch/mips/sni/setup.c linux/arch/mips/sni/setup.c --- v2.1.125/linux/arch/mips/sni/setup.c Thu Aug 6 14:06:29 1998 +++ linux/arch/mips/sni/setup.c Tue Oct 20 13:52:55 1998 @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.7 1998/06/10 07:21:19 davem Exp $ +/* $Id: setup.c,v 1.13 1998/08/17 13:57:45 ralf Exp $ * * Setup pointers to hardware-dependent routines. * @@ -6,7 +6,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1997 by Ralf Baechle + * Copyright (C) 1996, 1997, 1998 by Ralf Baechle */ #include #include @@ -26,7 +26,6 @@ #include #include #include -#include #include /* @@ -40,8 +39,6 @@ static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; extern asmlinkage void sni_rm200_pci_handle_int(void); -extern asmlinkage void sni_fd_cacheflush(const void *addr, size_t size); -extern struct feature sni_rm200_pci_feature; extern void sni_rm200_keyboard_setup(void); extern void sni_machine_restart(char *command); @@ -49,6 +46,7 @@ extern void sni_machine_power_off(void); extern struct ide_ops std_ide_ops; +extern struct rtc_ops std_rtc_ops; __initfunc(static void sni_irq_setup(void)) { @@ -133,8 +131,6 @@ sni_pcimt_sc_init(); irq_setup = sni_irq_setup; - fd_cacheflush = sni_fd_cacheflush; // Will go away - feature = &sni_rm200_pci_feature; mips_io_port_base = SNI_PORT_BASE; keyboard_setup = sni_rm200_keyboard_setup; @@ -165,7 +161,10 @@ */ request_region(0xcfc,0x04,"PCI config data"); pci_ops = &sni_pci_ops; + #ifdef CONFIG_BLK_DEV_IDE ide_ops = &std_ide_ops; #endif + + rtc_ops = &std_rtc_ops; } diff -u --recursive --new-file v2.1.125/linux/arch/mips/tools/Makefile linux/arch/mips/tools/Makefile --- v2.1.125/linux/arch/mips/tools/Makefile Fri May 8 23:14:44 1998 +++ linux/arch/mips/tools/Makefile Tue Oct 20 13:52:55 1998 @@ -3,7 +3,7 @@ # Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) # Copyright (C) 1997 Ralf Baechle (ralf@gnu.ai.mit.edu) # -# $Id: Makefile,v 1.3 1998/05/01 01:35:37 ralf Exp $ +# $Id: Makefile,v 1.2 1997/09/23 06:23:49 ralf Exp $ # TARGET := $(TOPDIR)/include/asm-$(ARCH)/offset.h diff -u --recursive --new-file v2.1.125/linux/arch/mips/tools/offset.c linux/arch/mips/tools/offset.c --- v2.1.125/linux/arch/mips/tools/offset.c Fri May 8 23:14:44 1998 +++ linux/arch/mips/tools/offset.c Tue Oct 20 13:52:55 1998 @@ -1,10 +1,9 @@ -/* +/* $Id: offset.c,v 1.10 1998/08/19 21:53:53 ralf Exp $ + * * offset.c: Calculate pt_regs and task_struct offsets. * * Copyright (C) 1996 David S. Miller * Made portable by Ralf Baechle - * - * $Id: offset.c,v 1.6 1998/05/04 09:18:45 ralf Exp $ */ #include @@ -77,10 +76,11 @@ { text("/* MIPS task_struct offsets. */"); offset("#define TASK_STATE ", struct task_struct, state); - offset("#define TASK_COUNTER ", struct task_struct, counter); - offset("#define TASK_PRIORITY ", struct task_struct, priority); offset("#define TASK_FLAGS ", struct task_struct, flags); offset("#define TASK_SIGPENDING ", struct task_struct, sigpending); + offset("#define TASK_NEED_RESCHED ", struct task_struct, need_resched); + offset("#define TASK_COUNTER ", struct task_struct, counter); + offset("#define TASK_PRIORITY ", struct task_struct, priority); offset("#define TASK_MM ", struct task_struct, mm); linefeed; } diff -u --recursive --new-file v2.1.125/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c --- v2.1.125/linux/arch/ppc/kernel/pmac_setup.c Mon Oct 5 13:13:36 1998 +++ linux/arch/ppc/kernel/pmac_setup.c Wed Oct 14 11:43:13 1998 @@ -145,6 +145,12 @@ #include "../../../drivers/scsi/sd.h" #include "../../../drivers/scsi/hosts.h" +#define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i)) +#define SD_MAJOR_NUMBER(i) SD_MAJOR((i) >> 8) +#define SD_MINOR_NUMBER(i) ((i) & 255) +#define MKDEV_SD_PARTITION(i) MKDEV(SD_MAJOR_NUMBER(i), SD_MINOR_NUMBER(i)) +#define MKDEV_SD(index) MKDEV_SD_PARTITION((index) << 4) + kdev_t sd_find_target(void *host, int tgt) { Scsi_Disk *dp; @@ -153,7 +159,7 @@ for (dp = rscsi_disks, i = 0; i < sd_template.dev_max; ++i, ++dp) if (dp->device != NULL && dp->device->host == host && dp->device->id == tgt) - return MKDEV(SCSI_DISK_MAJOR, i << 4); + return MKDEV_SD(i); return 0; } #endif diff -u --recursive --new-file v2.1.125/linux/drivers/block/Config.in linux/drivers/block/Config.in --- v2.1.125/linux/drivers/block/Config.in Mon Oct 5 13:13:38 1998 +++ linux/drivers/block/Config.in Mon Oct 12 11:40:12 1998 @@ -43,6 +43,7 @@ bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 bool ' VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586 + bool ' CMD646 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CMD646 fi fi fi diff -u --recursive --new-file v2.1.125/linux/drivers/block/README.fd linux/drivers/block/README.fd --- v2.1.125/linux/drivers/block/README.fd Wed Jun 24 22:54:04 1998 +++ linux/drivers/block/README.fd Mon Oct 12 14:13:54 1998 @@ -102,12 +102,12 @@ Tells the floppy driver that a workable DMA channel is available (the default). -floppy=nofifo + floppy=nofifo Disables the FIFO entirely. This is needed if you get "Bus master arbitration error" messages from your Ethernet card (or from other devices) while accessing the floppy. -floppy=fifo + floppy=fifo Enables the FIFO (default) floppy=,fifo_depth @@ -188,6 +188,13 @@ floppy=,dma Sets the floppy DMA channel to instead of 2 + + floppy=slow + Use PS/2 stepping rate: + " PS/2 floppies have much slower step rates than regular floppies. + It's been recommended that take about 1/4 of the default speed + in some more extreme cases." + Supporting utilities and additional documentation: diff -u --recursive --new-file v2.1.125/linux/drivers/block/acsi.c linux/drivers/block/acsi.c --- v2.1.125/linux/drivers/block/acsi.c Wed Aug 26 11:37:34 1998 +++ linux/drivers/block/acsi.c Fri Oct 9 11:56:59 1998 @@ -3,7 +3,7 @@ * * Copyright 1994 Roman Hodek * - * Some parts are based on hd.c by Linus Thorvalds + * Some parts are based on hd.c by Linus Torvalds * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive for diff -u --recursive --new-file v2.1.125/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v2.1.125/linux/drivers/block/floppy.c Mon Oct 5 13:13:38 1998 +++ linux/drivers/block/floppy.c Mon Oct 12 14:13:54 1998 @@ -153,6 +153,11 @@ #include #include +/* + * PS/2 floppies have much slower step rates than regular floppies. + * It's been recommended that take about 1/4 of the default speed + * in some more extreme cases. + */ static int slow_floppy = 0; #include @@ -354,7 +359,7 @@ 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/ {{2, 500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0, - 0, { 2, 5, 6,23,10,20,11, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/ + 0, { 2, 5, 6,23,10,20,12, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/ {{3, 250, 16, 16, 3000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0, 0, { 4,22,21,30, 3, 0, 0, 0}, 3*HZ/2, 4 }, "720k" }, /*3 1/2 DD*/ @@ -1051,6 +1056,7 @@ static void setup_DMA(void) { unsigned long flags; + unsigned long f; #ifdef FLOPPY_SANITY_CHECK if (raw_cmd->length == 0){ @@ -1072,17 +1078,20 @@ } #endif INT_OFF; + f=claim_dma_lock(); fd_disable_dma(); #ifdef fd_dma_setup if(fd_dma_setup(raw_cmd->kernel_data, raw_cmd->length, (raw_cmd->flags & FD_RAW_READ)? DMA_MODE_READ : DMA_MODE_WRITE, FDCS->address) < 0) { + release_dma_lock(f); INT_ON; cont->done(0); FDCS->reset=1; return; } + release_dma_lock(f); #else fd_clear_dma_ff(); fd_cacheflush(raw_cmd->kernel_data, raw_cmd->length); @@ -1092,6 +1101,7 @@ fd_set_dma_count(raw_cmd->length); virtual_dma_port = FDCS->address; fd_enable_dma(); + release_dma_lock(f); #endif INT_ON; floppy_disable_hlt(); @@ -1694,11 +1704,15 @@ { void (*handler)(void) = DEVICE_INTR; int do_print; + unsigned long f; lasthandler = handler; interruptjiffies = jiffies; + f=claim_dma_lock(); fd_disable_dma(); + release_dma_lock(f); + floppy_enable_hlt(); CLEAR_INTR; if (fdc >= N_FDC || FDCS->address == -1){ @@ -1779,13 +1793,18 @@ */ static void reset_fdc(void) { + unsigned long flags; + SET_INTR(reset_interrupt); FDCS->reset = 0; reset_fdc_info(0); /* Pseudo-DMA may intercept 'reset finished' interrupt. */ /* Irrelevant for systems with true DMA (i386). */ + + flags=claim_dma_lock(); fd_disable_dma(); + release_dma_lock(flags); if (FDCS->version >= FDC_82072A) fd_outb(0x80 | (FDCS->dtr &3), FD_STATUS); @@ -1844,12 +1863,18 @@ static void floppy_shutdown(void) { + unsigned long flags; + if (!initialising) show_floppy(); cancel_activity(); floppy_enable_hlt(); + + flags=claim_dma_lock(); fd_disable_dma(); + release_dma_lock(flags); + /* avoid dma going to a random drive after shutdown */ if (!initialising) @@ -1897,6 +1922,8 @@ static void floppy_ready(void) { + unsigned long flags; + CHECK_RESET; if (start_motor(floppy_ready)) return; if (fdc_dtr()) return; @@ -1915,8 +1942,12 @@ #ifdef fd_chose_dma_mode if ((raw_cmd->flags & FD_RAW_READ) || (raw_cmd->flags & FD_RAW_WRITE)) + { + flags=claim_dma_lock(); fd_chose_dma_mode(raw_cmd->kernel_data, raw_cmd->length); + release_dma_lock(flags); + } #endif if (raw_cmd->flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)){ @@ -3020,7 +3051,12 @@ raw_cmd->reply[i] = reply_buffer[i]; if (raw_cmd->flags & (FD_RAW_READ | FD_RAW_WRITE)) + { + unsigned long flags; + flags=claim_dma_lock(); raw_cmd->length = fd_get_dma_residue(); + release_dma_lock(flags); + } if ((raw_cmd->flags & FD_RAW_SOFTFAILURE) && (!raw_cmd->reply_count || (raw_cmd->reply[0] & 0xc0))) @@ -4025,6 +4061,7 @@ { "usefifo", 0, &no_fifo, 0, 0 }, { "cmos", set_cmos, 0, 0, 0 }, + { "slow", 0, &slow_floppy, 1, 0 }, { "unexpected_interrupts", 0, &print_unex, 1, 0 }, { "no_unexpected_interrupts", 0, &print_unex, 0, 0 }, @@ -4036,15 +4073,6 @@ int i; int param; if (str) { - /* - * PS/2 floppies have much slower step rates than regular floppies. - * It's been recommended that take about 1/4 of the default speed - * in some more extreme cases. - */ - if( strcmp(str,"slow") == 0) { - slow_floppy = 1; - return; - } for (i=0; i< ARRAY_SIZE(config_params); i++){ if (strcmp(str,config_params[i].name) == 0){ if (ints[0]) @@ -4125,6 +4153,8 @@ #endif if (floppy_grab_irq_and_dma()){ + del_timer(&fd_timeout); + blk_dev[MAJOR_NR].request_fn = NULL; unregister_blkdev(MAJOR_NR,"fd"); del_timer(&fd_timeout); return -EBUSY; @@ -4176,7 +4206,8 @@ current_drive = 0; floppy_release_irq_and_dma(); initialising=0; - if (have_no_fdc) { + if (have_no_fdc) + { DPRINT("no floppy controllers found\n"); unregister_blkdev(MAJOR_NR,"fd"); } diff -u --recursive --new-file v2.1.125/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.1.125/linux/drivers/block/genhd.c Mon Sep 28 10:51:33 1998 +++ linux/drivers/block/genhd.c Tue Oct 20 13:52:01 1998 @@ -71,7 +71,7 @@ { unsigned int part; const char *maj = hd->major_name; - char unit = (minor >> hd->minor_shift) + 'a'; + int unit = (minor >> hd->minor_shift) + 'a'; /* * IDE devices use multiple major numbers, but the drives @@ -91,8 +91,19 @@ unit += 2; case IDE0_MAJOR: maj = "hd"; + break; } part = minor & ((1 << hd->minor_shift) - 1); + if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) { + unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16; + if (unit > 'z') { + unit -= 'z' + 1; + sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26); + if (part) + sprintf(buf + 4, "%d", part); + return buf; + } + } if (part) sprintf(buf, "%s%c%d", maj, unit, part); else @@ -647,6 +658,74 @@ #endif /* CONFIG_SUN_PARTITION */ +#ifdef CONFIG_SGI_PARTITION + +static int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector) +{ + int i, csum; + unsigned int *ui; + struct buffer_head *bh; + struct sgi_disklabel { + int magic_mushroom; /* Big fat spliff... */ + short root_part_num; /* Root partition number */ + short swap_part_num; /* Swap partition number */ + char boot_file[16]; /* Name of boot file for ARCS */ + unsigned char _unused0[48]; /* Device parameter useless crapola.. */ + struct sgi_volume { + char name[8]; /* Name of volume */ + int block_num; /* Logical block number */ + int num_bytes; /* How big, in bytes */ + } volume[15]; + struct sgi_partition { + int num_blocks; /* Size in logical blocks */ + int first_block; /* First logical block */ + int type; /* Type of this partition */ + } partitions[16]; + int csum; /* Disk label checksum */ + int _unused1; /* Padding */ + } *label; + struct sgi_partition *p; +#define SGI_LABEL_MAGIC 0x0be5a941 + + if(!(bh = bread(dev, 0, 1024))) { + printk("Dev %s: unable to read partition table\n", kdevname(dev)); + return -1; + } + label = (struct sgi_disklabel *) bh->b_data; + p = &label->partitions[0]; + if(label->magic_mushroom != SGI_LABEL_MAGIC) { + printk("Dev %s SGI disklabel: bad magic %08x\n", + kdevname(dev), label->magic_mushroom); + brelse(bh); + return 0; + } + ui = ((unsigned int *) (label + 1)) - 1; + for(csum = 0; ui >= ((unsigned int *) label);) + csum += *ui--; + if(csum) { + printk("Dev %s SGI disklabel: csum bad, label corrupted\n", + kdevname(dev)); + brelse(bh); + return 0; + } + /* All SGI disk labels have 16 partitions, disks under Linux only + * have 15 minor's. Luckily there are always a few zero length + * partitions which we don't care about so we never overflow the + * current_minor. + */ + for(i = 0; i < 16; i++, p++) { + if(!(p->num_blocks)) + continue; + add_partition(hd, current_minor, p->first_block, p->num_blocks); + current_minor++; + } + printk("\n"); + brelse(bh); + return 1; +} + +#endif + #ifdef CONFIG_AMIGA_PARTITION #include #include @@ -1037,6 +1116,10 @@ #endif #ifdef CONFIG_MAC_PARTITION if (mac_partition(hd, dev, first_sector)) + return; +#endif +#ifdef CONFIG_SGI_PARTITION + if(sgi_partition(hd, dev, first_sector)) return; #endif printk(" unknown partition table\n"); diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c --- v2.1.125/linux/drivers/block/ide-cd.c Thu Sep 17 17:53:35 1998 +++ linux/drivers/block/ide-cd.c Wed Oct 21 16:03:04 1998 @@ -2600,6 +2600,8 @@ return 0; } else { + int was_locked; + if ( #if ! STANDARD_ATAPI CDROM_STATE_FLAGS (drive)->sanyo_slot == 0 && @@ -2608,6 +2610,10 @@ return -ENOMEDIUM; } + was_locked = CDROM_STATE_FLAGS (drive)->door_locked; + if (was_locked) + (void) cdrom_lockdoor (drive, 0, NULL); + stat = cdrom_load_unload (drive, slot, NULL); cdrom_saw_media_change (drive); if (stat) @@ -2621,10 +2627,12 @@ stat = cdrom_read_toc (drive, &my_reqbuf); if (stat) return stat; - return slot; } - else - return stat; + + if (was_locked) + (void) cdrom_lockdoor (drive, 1, NULL); + + return stat; } } diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide-dma.c linux/drivers/block/ide-dma.c --- v2.1.125/linux/drivers/block/ide-dma.c Thu Sep 17 17:53:35 1998 +++ linux/drivers/block/ide-dma.c Mon Oct 12 11:42:59 1998 @@ -344,6 +344,21 @@ } } +/* + * Needed for allowing full modular support of ide-driver + */ +int ide_release_dma (ide_hwif_t *hwif) +{ + if (hwif->dmatable) { + clear_page((unsigned long)hwif->dmatable); /* clear PRD 1st */ + free_page((unsigned long)hwif->dmatable); /* free PRD 2nd */ + } + if ((hwif->dma_extra) && (hwif->channel == 0)) + release_region((hwif->dma_base + 16), hwif->dma_extra); + release_region(hwif->dma_base, 8); + return 1; +} + __initfunc(void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports)) { static unsigned long dmatable = 0; @@ -404,6 +419,7 @@ if (extra) /* PDC20246 & HPT343 */ request_region(dma_base+16, extra, name); dma_base += hwif->channel ? 8 : 0; + hwif->dma_extra = extra; if (inb(dma_base+2) & 0x80) { printk("%s: simplex device: DMA disabled\n", name); dma_base = 0; diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c --- v2.1.125/linux/drivers/block/ide-floppy.c Thu Sep 17 17:53:35 1998 +++ linux/drivers/block/ide-floppy.c Wed Oct 14 20:24:55 1998 @@ -868,7 +868,7 @@ if (status.b.check || test_bit (PC_DMA_ERROR, &pc->flags)) { /* Error detected */ #if IDEFLOPPY_DEBUG_LOG - printk (KERN_INFO "ide-floppy: %s: I/O error, ",drive->name); + printk (KERN_INFO "ide-floppy: %s: I/O error\n",drive->name); #endif /* IDEFLOPPY_DEBUG_LOG */ rq->errors++; if (pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) { @@ -1057,6 +1057,7 @@ pc->c[0] = IDEFLOPPY_READ_CAPACITY_CMD; pc->c[7] = 255; pc->c[8] = 255; + pc->request_transfer = 255; } /* diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide-pci.c linux/drivers/block/ide-pci.c --- v2.1.125/linux/drivers/block/ide-pci.c Mon Oct 5 13:13:38 1998 +++ linux/drivers/block/ide-pci.c Mon Oct 12 11:42:59 1998 @@ -117,16 +117,6 @@ unsigned int extra; } ide_pci_device_t; -#ifdef CONFIG_BLK_DEV_OFFBOARD -# define ON_BOARD 0 -# define OFF_BOARD 1 -# define NEVER_BOARD 0 -#else /* CONFIG_BLK_DEV_OFFBOARD */ -# define ON_BOARD 1 -# define OFF_BOARD 0 -# define NEVER_BOARD 0 -#endif /* CONFIG_BLK_DEV_OFFBOARD */ - static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_PIIXa, "PIIX", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIXb, "PIIX", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.1.125/linux/drivers/block/ide.c Fri Oct 9 13:27:07 1998 +++ linux/drivers/block/ide.c Mon Oct 12 11:42:59 1998 @@ -1737,6 +1737,11 @@ else hwgroup->hwif = HWIF(hwgroup->drive); +#ifdef CONFIG_BLK_DEV_IDEDMA + if (hwif->dma_base) + (void) ide_release_dma(hwif); +#endif /* CONFIG_BLK_DEV_IDEDMA */ + /* * Remove us from the kernel's knowledge */ @@ -2998,8 +3003,13 @@ { int index; - for (index = 0; index < MAX_HWIFS; ++index) + for (index = 0; index < MAX_HWIFS; ++index) { ide_unregister(index); +#ifdef CONFIG_BLK_DEV_IDEDMA + if (ide_hwifs[index].dma_base) + (void) ide_release_dma(&ide_hwifs[index]); +#endif /* CONFIG_BLK_DEV_IDEDMA */ + } #ifdef CONFIG_PROC_FS proc_ide_destroy(); #endif diff -u --recursive --new-file v2.1.125/linux/drivers/block/ide.h linux/drivers/block/ide.h --- v2.1.125/linux/drivers/block/ide.h Fri Oct 9 13:27:07 1998 +++ linux/drivers/block/ide.h Fri Oct 23 10:18:55 1998 @@ -328,6 +328,7 @@ unsigned long *dmatable; /* dma physical region descriptor table */ struct hwif_s *mate; /* other hwif from same PCI chip */ unsigned long dma_base; /* base addr for dma ports */ + unsigned dma_extra; /* extra addr for dma ports */ unsigned long config_data; /* for use by chipset-specific code */ unsigned long select_data; /* for use by chipset-specific code */ struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ @@ -725,6 +726,14 @@ int ide_replace_subdriver(ide_drive_t *drive, const char *driver); #ifdef CONFIG_BLK_DEV_IDEPCI +#define ON_BOARD 1 +#define NEVER_BOARD 0 +#ifdef CONFIG_BLK_DEV_OFFBOARD +# define OFF_BOARD ON_BOARD +#else /* CONFIG_BLK_DEV_OFFBOARD */ +# define OFF_BOARD NEVER_BOARD +#endif /* CONFIG_BLK_DEV_OFFBOARD */ + unsigned long ide_find_free_region (unsigned short size) __init; void ide_scan_pcibus (void) __init; #endif @@ -735,6 +744,7 @@ void ide_dma_intr (ide_drive_t *drive); int check_drive_lists (ide_drive_t *drive, int good_bad); int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive); +int ide_release_dma (ide_hwif_t *hwif); void ide_setup_dma (ide_hwif_t *hwif, unsigned long dmabase, unsigned int num_ports) __init; unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const char *name) __init; #endif diff -u --recursive --new-file v2.1.125/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.1.125/linux/drivers/block/ll_rw_blk.c Mon Aug 3 12:45:44 1998 +++ linux/drivers/block/ll_rw_blk.c Wed Oct 14 11:43:13 1998 @@ -93,8 +93,8 @@ * then 512 bytes is assumed. * else * sector_size is hardsect_size[MAJOR][MINOR] - * This is currently set by some scsi device and read by the msdos fs driver - * This might be a some uses later. + * This is currently set by some scsi devices and read by the msdos fs driver. + * Other uses may appear later. */ int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, }; @@ -297,8 +297,8 @@ int queue_new_request = 0; switch (MAJOR(req->rq_dev)) { - case SCSI_DISK_MAJOR: - disk_index = (MINOR(req->rq_dev) & 0x0070) >> 4; + case SCSI_DISK0_MAJOR: + disk_index = (MINOR(req->rq_dev) & 0x00f0) >> 4; if (disk_index < 4) drive_stat_acct(req->cmd, req->nr_sectors, disk_index); break; @@ -479,7 +479,14 @@ break; /* fall through */ - case SCSI_DISK_MAJOR: + case SCSI_DISK0_MAJOR: + case SCSI_DISK1_MAJOR: + case SCSI_DISK2_MAJOR: + case SCSI_DISK3_MAJOR: + case SCSI_DISK4_MAJOR: + case SCSI_DISK5_MAJOR: + case SCSI_DISK6_MAJOR: + case SCSI_DISK7_MAJOR: case SCSI_CDROM_MAJOR: do { diff -u --recursive --new-file v2.1.125/linux/drivers/block/loop.c linux/drivers/block/loop.c --- v2.1.125/linux/drivers/block/loop.c Thu Sep 17 17:53:35 1998 +++ linux/drivers/block/loop.c Wed Oct 21 09:59:41 1998 @@ -21,9 +21,13 @@ * Still To Fix: * - Advisory locking is ignored here. * - Should use an own CAP_* category instead of CAP_SYS_ADMIN + * - Should use the underlying filesystems/devices read function if possible + * to support read ahead (and for write) */ #include + +#include #include #include #include @@ -304,7 +308,7 @@ file->f_version = ++event; } - if ((file->f_mode & FMODE_WRITE) == 0 || file->f_op->write == NULL) { + if (file->f_op->write == NULL) { printk(KERN_WARNING "loop: cannot create block - file not writeable\n"); return FALSE; } @@ -384,9 +388,9 @@ lo->lo_backing_file->f_op = file->f_op; lo->lo_backing_file->private_data = file->private_data; - error = get_write_access(inode); /* cannot fail */ + error = get_write_access(inode); if (error) { - fput(lo->lo_backing_file); + put_filp(lo->lo_backing_file); lo->lo_backing_file = NULL; } } @@ -402,8 +406,7 @@ set_device_ro(dev, 0); } - lo->lo_dentry = file->f_dentry; - lo->lo_dentry->d_count++; + lo->lo_dentry = dget(file->f_dentry); lo->transfer = NULL; lo->ioctl = NULL; figure_loop_size(lo); @@ -420,15 +423,32 @@ { int err = 0; if (lo->lo_encrypt_type) { - if (xfer_funcs[lo->lo_encrypt_type] && - xfer_funcs[lo->lo_encrypt_type]->release) { - err = xfer_funcs[lo->lo_encrypt_type]->release(lo); - } + struct loop_func_table *xfer= xfer_funcs[lo->lo_encrypt_type]; + if (xfer && xfer->release) + err = xfer->release(lo); + if (xfer && xfer->unlock) + xfer->unlock(lo); lo->lo_encrypt_type = 0; } return err; } +static int loop_init_xfer(struct loop_device *lo, int type,struct loop_info *i) +{ + int err = 0; + if (type) { + struct loop_func_table *xfer = xfer_funcs[type]; + if (xfer->init) + err = xfer->init(lo, i); + if (!err) { + lo->lo_encrypt_type = type; + if (xfer->lock) + xfer->lock(lo); + } + } + return err; +} + static int loop_clr_fd(struct loop_device *lo, kdev_t dev) { struct dentry *dentry = lo->lo_dentry; @@ -449,6 +469,7 @@ dput(dentry); } + loop_release_xfer(lo); lo->transfer = NULL; lo->ioctl = NULL; lo->lo_device = 0; @@ -481,17 +502,14 @@ type = info.lo_encrypt_type; if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL) return -EINVAL; - err = loop_release_xfer(lo); - if (err) - return err; - if (xfer_funcs[type]->init) - err = xfer_funcs[type]->init(lo, &info); + err = loop_release_xfer(lo); + if (!err) + err = loop_init_xfer(lo, type, &info); if (err) - return err; + return err; lo->lo_offset = info.lo_offset; strncpy(lo->lo_name, info.lo_name, LO_NAME_SIZE); - lo->lo_encrypt_type = type; lo->transfer = xfer_funcs[type]->transfer; lo->ioctl = xfer_funcs[type]->ioctl; @@ -572,7 +590,8 @@ static int lo_open(struct inode *inode, struct file *file) { struct loop_device *lo; - int dev; + int dev, type; + if (!inode) return -EINVAL; @@ -585,6 +604,10 @@ return -ENODEV; } lo = &loop_dev[dev]; + + type = lo->lo_encrypt_type; + if (type && xfer_funcs[type] && xfer_funcs[type]->lock) + xfer_funcs[type]->lock(lo); lo->lo_refcnt++; MOD_INC_USE_COUNT; return 0; @@ -593,7 +616,7 @@ static int lo_release(struct inode *inode, struct file *file) { struct loop_device *lo; - int dev, err = 0; + int dev, err; if (!inode) return 0; @@ -605,14 +628,14 @@ if (dev >= MAX_LOOP) return 0; err = fsync_dev(inode->i_rdev); - if (err < 0) - return err; lo = &loop_dev[dev]; if (lo->lo_refcnt <= 0) printk(KERN_ERR "lo_release: refcount(%d) <= 0\n", lo->lo_refcnt); else { - if (--lo->lo_refcnt == 0) - err = loop_release_xfer(lo); + int type = lo->lo_encrypt_type; + --lo->lo_refcnt; + if (xfer_funcs[type] && xfer_funcs[type]->unlock) + xfer_funcs[type]->unlock(lo); MOD_DEC_USE_COUNT; } return err; @@ -646,11 +669,20 @@ return 0; } -/* Usage checking must be done by the caller - usually with MOD_INC/DEC_* */ int loop_unregister_transfer(int number) { + struct loop_device *lo; + if ((unsigned)number >= MAX_LO_CRYPT) return -EINVAL; + for (lo = &loop_dev[0]; lo < &loop_dev[MAX_LOOP]; lo++) { + int type = lo->lo_encrypt_type; + if (type == number) { + xfer_funcs[type]->release(lo); + lo->transfer = NULL; + lo->lo_encrypt_type = 0; + } + } xfer_funcs[number] = NULL; return 0; } diff -u --recursive --new-file v2.1.125/linux/drivers/block/xd.c linux/drivers/block/xd.c --- v2.1.125/linux/drivers/block/xd.c Wed Aug 26 11:37:35 1998 +++ linux/drivers/block/xd.c Fri Oct 9 11:56:59 1998 @@ -533,6 +533,8 @@ /* xd_setup_dma: set up the DMA controller for a data transfer */ static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count) { + unsigned long f; + if (nodma) return (PIO_MODE); if (((u_int) buffer & 0xFFFF0000) != (((u_int) buffer + count) & 0xFFFF0000)) { @@ -541,11 +543,15 @@ #endif /* DEBUG_OTHER */ return (PIO_MODE); } + + f=claim_dma_lock(); disable_dma(xd_dma); clear_dma_ff(xd_dma); set_dma_mode(xd_dma,mode); set_dma_addr(xd_dma,(u_int) buffer); set_dma_count(xd_dma,count); + + release_dma_lock(f); return (DMA_MODE); /* use DMA and INT */ } @@ -597,13 +603,22 @@ static inline u_int xd_wait_for_IRQ (void) { + unsigned long flags; xd_watchdog_int.expires = jiffies + 8 * HZ; add_timer(&xd_watchdog_int); + + flags=claim_dma_lock(); enable_dma(xd_dma); + release_dma_lock(flags); + sleep_on(&xd_wait_int); del_timer(&xd_watchdog_int); xdc_busy = 0; + + flags=claim_dma_lock(); disable_dma(xd_dma); + release_dma_lock(flags); + if (xd_error) { printk("xd: missed IRQ - command aborted\n"); xd_error = 0; diff -u --recursive --new-file v2.1.125/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c --- v2.1.125/linux/drivers/cdrom/cdu31a.c Thu Sep 17 17:53:35 1998 +++ linux/drivers/cdrom/cdu31a.c Sat Oct 17 15:52:18 1998 @@ -3020,18 +3020,20 @@ sony_get_toc(); if (!sony_toc_read) { - return -EIO; + return -EIO; } - + + if(copy_from_user(&ra, (char *) arg, sizeof(ra))) + return -EFAULT; + if (ra.nframes == 0) { - return 0; + return 0; } i=verify_area(VERIFY_WRITE, ra.buf, CD_FRAMESIZE_RAW * ra.nframes); if(i<0) return i; - copy_from_user(&ra, (char *) arg, sizeof(ra)); if (ra.addr_format == CDROM_LBA) { diff -u --recursive --new-file v2.1.125/linux/drivers/char/Config.in linux/drivers/char/Config.in --- v2.1.125/linux/drivers/char/Config.in Fri Oct 9 13:27:07 1998 +++ linux/drivers/char/Config.in Fri Oct 9 11:44:19 1998 @@ -56,7 +56,7 @@ tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE tristate 'Logitech busmouse support' CONFIG_BUSMOUSE tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE - tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE + bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE tristate 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE tristate 'PC110 digitizer pad support' CONFIG_PC110_PAD fi diff -u --recursive --new-file v2.1.125/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.1.125/linux/drivers/char/Makefile Fri Oct 9 13:27:07 1998 +++ linux/drivers/char/Makefile Fri Oct 9 11:44:19 1998 @@ -184,14 +184,6 @@ endif endif -ifeq ($(CONFIG_PSMOUSE),y) -L_OBJS += psaux.o -else - ifeq ($(CONFIG_PSMOUSE),m) - M_OBJS += psaux.o - endif -endif - ifeq ($(CONFIG_SOFT_WATCHDOG),y) L_OBJS += softdog.o else diff -u --recursive --new-file v2.1.125/linux/drivers/char/bttv.c linux/drivers/char/bttv.c --- v2.1.125/linux/drivers/char/bttv.c Thu Sep 17 17:53:36 1998 +++ linux/drivers/char/bttv.c Sat Oct 17 15:52:18 1998 @@ -28,11 +28,10 @@ composite source from a satellite tuner can deliver different norms depending on tuned channel * mmap VBI data? - * use new PCI routines * fix RAW Composite grabbing for NTSC - * allow for different VDELAY in RAW grabbing? + * fix VBI reading double frames when grabbing is active + * allow for different VDELAYs * extra modules for tda9850, tda8425, any volunteers??? - * support 15bpp */ #include @@ -80,12 +79,20 @@ static unsigned int vidmem=0; /* manually set video mem address */ static int triton1=0; +#ifndef USE_PLL +/* 0=no pll, 1=28MHz, 2=34MHz */ +#define USE_PLL 0 +#endif +#ifndef CARD_DEFAULT +/* card type (see bttv.h) 0=autodetect */ +#define CARD_DEFAULT 0 +#endif static unsigned int remap[BTTV_MAX]; /* remap Bt848 */ static unsigned int radio[BTTV_MAX]; -static unsigned int card[BTTV_MAX] = { 0, 0, - 0, 0 }; -static unsigned int pll[BTTV_MAX] = { 0, 0, 0, 0 }; +static unsigned int card[BTTV_MAX] = { CARD_DEFAULT, CARD_DEFAULT, + CARD_DEFAULT, CARD_DEFAULT }; +static unsigned int pll[BTTV_MAX] = { USE_PLL, USE_PLL, USE_PLL, USE_PLL }; static int bttv_num; /* number of Bt848s in use */ static struct bttv bttvs[BTTV_MAX]; @@ -96,9 +103,8 @@ { btwrite((CTRL<<1)|(DATA), BT848_I2C); udelay(I2C_DELAY); } #define I2C_GET() (btread(BT848_I2C)&1) -#define AUDIO_MUTE_DELAY 10000 -#define FREQ_CHANGE_DELAY 20000 #define EEPROM_WRITE_DELAY 20000 +#define BURSTOFFSET 76 /*******************************/ /* Memory management functions */ @@ -344,7 +350,6 @@ void attach_inform(struct i2c_bus *bus, int id) { struct bttv *btv = (struct bttv*)bus->data; - int tunertype; switch (id) { @@ -354,12 +359,9 @@ case I2C_DRIVERID_TUNER: btv->have_tuner = 1; if (btv->tuner_type != -1) - { - tunertype=btv->tuner_type; i2c_control_device(&(btv->i2c), I2C_DRIVERID_TUNER, - TUNER_SET_TYPE,&tunertype); - } + TUNER_SET_TYPE,&btv->tuner_type); break; } } @@ -433,9 +435,10 @@ {0, 0xc00, 0x800, 0x400, 0xc00, 0}}, /* TurboTV */ { 3, 0, 2, 3, { 2, 3, 1, 1}, { 1, 1, 2, 3, 0}}, - /* Newer Hauppauge */ - { 2, 0, 2, 1, { 2, 0, 0, 0}, {0, 1, 2, 3, 4}}, - + /* Newer Hauppauge (bt878) */ + { 3, 0, 2, 7, { 2, 0, 1, 1}, { 0, 1, 2, 3, 4}}, + /* MIRO PCTV pro */ + { 3, 0, 2, 65551, { 2, 3, 1, 1}, {1,65537, 0, 0,10}}, }; #define TVCARDS (sizeof(tvcards)/sizeof(tvcard)) @@ -546,32 +549,36 @@ static int set_pll(struct bttv *btv) { int i; - unsigned long tv; + unsigned long tv; if (!btv->pll.pll_crystal) - return 0; - if ((btread(BT848_IFORM)&btv->pll.pll_crystal)) - { - /* printk ("switching PLL off\n");*/ + return 0; + + if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) { + /* no PLL needed */ + if (btv->pll.pll_current == 0) { + /* printk ("bttv%d: PLL: is off\n",btv->nr); */ + return 0; + } + printk ("bttv%d: PLL: switching off\n",btv->nr); btwrite(0x00,BT848_TGCTRL); btwrite(0x00,BT848_PLL_XCI); - btv->pll.pll_crystal&=~2; + btv->pll.pll_current = 0; return 0; } - - /* do not set pll again if already active */ - if (btv->pll.pll_crystal&2) + + if (btv->pll.pll_ofreq == btv->pll.pll_current) { + /* printk("bttv%d: PLL: no change required\n",btv->nr); */ return 1; + } - /* printk ("setting PLL for PAL/SECAM\n");*/ + printk("bttv%d: PLL: %d => %d ... ",btv->nr, + btv->pll.pll_ifreq, btv->pll.pll_ofreq); set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq); - /* - * Let other people run while the PLL stabilizes - */ - - tv=jiffies+HZ/10; /* .1 seconds */ + /* Let other people run while the PLL stabilizes */ + tv=jiffies+HZ/10; /* .1 seconds */ do { schedule(); @@ -585,11 +592,14 @@ else { btwrite(0x08,BT848_TGCTRL); - btv->pll.pll_crystal|=2; - return 1; + btv->pll.pll_current = btv->pll.pll_ofreq; + printk("ok\n"); + return 1; } - udelay(10000); + mdelay(10); } + btv->pll.pll_current = 0; + printk("oops\n"); return -1; } @@ -623,8 +633,9 @@ #define VBIBUF_SIZE 65536 -/* Maximum sample number per VBI line is 2044, can NTSC deliver this? +/* Maximum sample number per VBI line is 2044, NTSC delivers 1600 Note that we write 2048-aligned to keep alignment to memory pages + VBI_RISC is written so that it applies to either 2044 or 1600 */ #define VBI_SPL 2044 @@ -684,7 +695,7 @@ BT848_COLOR_FMT_YCrCb422, BT848_COLOR_FMT_YCrCb411, }; -#define PALETTEFMT_MAX 15 +#define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(int)) static int make_rawrisctab(struct bttv *btv, unsigned int *ro, unsigned int *re, unsigned int *vbuf) @@ -783,199 +794,102 @@ return 0; } -/* does this really make a difference ???? */ -#define BURST_MAX 4096 - -static inline void write_risc_segment(unsigned int **rp, unsigned long line_adr, unsigned int command, - int *x, uint dx, uint bpp, uint width) +static void clip_draw_rectangle(unsigned char *clipmap, int x, int y, int w, int h) { - unsigned int flags, len; - - if (!dx) - return; - len=dx*bpp; - -#ifdef LIMIT_DMA - if (command==BT848_RISC_WRITEC) - { - unsigned int dx2=BURST_MAX/bpp; - while (len>BURST_MAX) - { - write_risc_segment(rp, line_adr, command, - &x,dx2, bpp, width); - dx-=dx2; - len=dx*bpp; - } - } -#endif - - /* mask upper 8 bits for 24+8 bit overlay modes */ - flags = ((bpp==4) ? BT848_RISC_BYTE3 : 0); - - if (*x==0) - { - if (command==BT848_RISC_SKIP) - { - if (dx>3)] |= (1<<(j&7)); } static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr) { - int i,t; - int yy, y, x, dx; - struct video_clip first, *cur, *cur2, *nx, first2, *prev, *nx2; - int bpp, bpl, width, height, inter; - unsigned int **rp,*ro,*re; + int i, line, x, y, bpl, width, height, inter; + unsigned int bpp, dx, sx, **rp, *ro, *re, flags, len; unsigned long adr; - int cx,cx2,cy,cy2; + unsigned char *clipmap, cbit, lastbit, outofmem; inter=(btv->win.interlace&1)^1; bpp=btv->win.bpp; + if (bpp==15) /* handle 15bpp as 16bpp in calculations */ + bpp++; bpl=btv->win.bpl; ro=btv->risc_odd; re=btv->risc_even; - width=btv->win.width; - height=btv->win.height; + if((width=btv->win.width)>1023) + width = 1023; /* sanity check */ + if((height=btv->win.height)>625) + height = 625; /* sanity check */ adr=btv->win.vidadr+btv->win.x*bpp+btv->win.y*bpl; - - /* clip clipping rects against viewing window AND screen + if ((clipmap=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) { + /* can't clip, don't generate any risc code */ + *(ro++)=BT848_RISC_JUMP; + *(ro++)=btv->bus_vbi_even; + *(re++)=BT848_RISC_JUMP; + *(re++)=btv->bus_vbi_odd; + } + if (ncr < 0) { /* bitmap was pased */ + memcpy(clipmap, (unsigned char *)cr, VIDEO_CLIPMAP_SIZE); + } else { /* convert rectangular clips to a bitmap */ + memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */ + for (i=0; iwin.x<0) ? (-btv->win.x) : 0; - cy=(btv->win.y<0) ? (-btv->win.y) : 0; - cx2=(btv->win.x+width>btv->win.swidth) ? - (btv->win.swidth-btv->win.x) : width; - cy2=(btv->win.y+height>btv->win.sheight) ? - (btv->win.sheight-btv->win.y) : height; - first.next=NULL; - for (i=0; i0) - { - if (cr[i].height<=t) - continue; - cr[i].height-=t; - cr[i].y=cy; - } - if ((t=cy2-cr[i].y)0) - { - if (cr[i].width<=t) - continue; - cr[i].width-=t; - cr[i].x=cx; - } - if ((t=cx2-cr[i].x)next) && (cr[i].y > cur->next->y)) - cur=nx; - cur->next=&(cr[i]); - cr[i].next=nx; - } - first2.next=NULL; + clip_draw_rectangle(clipmap,(btv->win.x+width>btv->win.swidth) ? + (btv->win.swidth-btv->win.x) : width, 0, 1024, 768); + clip_draw_rectangle(clipmap,0,(btv->win.y+height>btv->win.sheight) ? + (btv->win.sheight-btv->win.y) : height,1024,768); + if (btv->win.x<0) + clip_draw_rectangle(clipmap, 0, 0, -(btv->win.x), 768); + if (btv->win.y<0) + clip_draw_rectangle(clipmap, 0, 0, 1024, -(btv->win.y)); *(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0; *(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0; - /* loop through all lines */ - for (yy=0; yy<(height<>inter; - rp= (yy&1) ? &re : &ro; - - /* remove rects with y2 > y */ - if ((cur=first2.next)) - { - prev=&first2; - do - { - if (cur->y+cur->height <= y) - prev->next=cur->next; - else - prev=cur; - } - while ((cur=cur->next)); - } - - /* add rect to second (x-sorted) list if rect.y == y */ - if ((cur=first.next)) - { - while ((cur) && (cur->y == y)) - { - first.next=cur->next; - cur2=&first2; - while ((nx2=cur2->next) && (cur->x > cur2->next->x)) - cur2=nx2; - cur2->next=cur; - cur->next=nx2; - cur=first.next; - } - } - x=0; - if ((btv->win.y+y<=0)||(btv->win.y+y>=btv->win.sheight)) - write_risc_segment(rp, adr, BT848_RISC_SKIP, &x, - width, bpp, width); - else - { - dx=cx; - for (cur2=first2.next; cur2; cur2=cur2->next) - { - if (x+dx < cur2->x) - { - write_risc_segment(rp, adr, BT848_RISC_SKIP, - &x, dx, bpp, width); - dx=cur2->x-x; - write_risc_segment(rp, adr, BT848_RISC_WRITEC, - &x, dx, bpp, width); - dx=cur2->width; - } - else if (x+dx < cur2->x+cur2->width) - dx=cur2->x+cur2->width-x; - } - if (cx2>inter; + rp= (line&1) ? &re : &ro; + lastbit=(clipmap[y<<7]&1); + for(x=dx=1,sx=0; x<=width && !outofmem; x++) { + cbit = (clipmap[(y<<7)+(x>>3)] & (1<<(x&7))); + if (x < width && !lastbit == !cbit) + dx++; + else { /* generate the dma controller code */ + len = dx * bpp; + flags = ((bpp==4) ? BT848_RISC_BYTE3 : 0); + flags |= ((!sx) ? BT848_RISC_SOL : 0); + flags |= ((sx + dx == width) ? BT848_RISC_EOL : 0); + if (!lastbit) { + *((*rp)++)=BT848_RISC_WRITE|flags|len; + *((*rp)++)=adr + bpp * sx; + } else + *((*rp)++)=BT848_RISC_SKIP|flags|len; + lastbit=cbit; + sx += dx; + dx = 1; + if (ro - btv->risc_odd > RISCMEM_LEN/2 - 16) + outofmem++; + if (re - btv->risc_even > RISCMEM_LEN/2 - 16) + outofmem++; + } + } + if ((!inter)||(line&1)) adr+=bpl; } - - *(ro++)=BT848_RISC_JUMP; + vfree(clipmap); + /* outofmem flag relies on the following code to discard extra data */ + *(ro++)=BT848_RISC_JUMP; *(ro++)=btv->bus_vbi_even; *(re++)=BT848_RISC_JUMP; *(re++)=btv->bus_vbi_odd; @@ -999,44 +913,51 @@ u8 adelay, bdelay, iform; u32 scaledtwidth; u16 hdelayx1, hactivex1; - u16 vdelay, fporch; + u16 vdelay; + u8 vbipack; }; static struct tvnorm tvnorms[] = { /* PAL-BDGHI */ - /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ + /* max pal/secam is actually 922, but 924 is divisible by 4 and 3! */ + /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ { 35468950, 924, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1), - 1135, 186, 924, 0x20}, + 1135, 178, 924, 0x20, 255}, /* { 35468950, 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1), - 944, 186, 922, 0x20}, + 944, 178, 922, 0x20, 255}, */ /* NTSC */ { 28636363, + 768, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0), + 910, 128, 754, 0x1a, 144}, +/* + { 28636363, 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0), - 780, 135, 754, 0x1a}, - /* SECAM */ - { 28636363, - 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0), - 780, 135, 754, 0x16}, + 780, 122, 754, 0x1a, 144}, +*/ + /* SECAM - phase means nothing in SECAM, bdelay is useless */ + { 35468950, + 924, 576,1135, 0x7f, 0xb0, (BT848_IFORM_SECAM|BT848_IFORM_XT1), + 1135, 178, 924, 0x20, 255}, /* PAL-M */ { 28636363, 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0), - 780, 135, 754, 0x16}, + 780, 122, 754, 0x1a, 144}, /* PAL-N */ { 35468950, 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_N|BT848_IFORM_XT1), - 944, 186, 922, 0x20}, + 944, 178, 922, 0x20, 255}, /* PAL-NC */ { 35468950, 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_NC|BT848_IFORM_XT0), - 944, 186, 922, 0x20}, + 944, 178, 922, 0x20, 255}, /* NTSC-Japan */ { 28636363, 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC_J|BT848_IFORM_XT0), - 780, 135, 754, 0x16}, + 780, 122, 754, 0x1a, 144}, }; #define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm)) @@ -1101,6 +1022,8 @@ btwrite(tvn->adelay, BT848_ADELAY); btwrite(tvn->bdelay, BT848_BDELAY); btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM); + btwrite(1, BT848_VBI_PACK_DEL); + btwrite(tvn->vbipack, BT848_VBI_PACK_SIZE); set_pll(btv); @@ -1172,11 +1095,7 @@ static void set_freq(struct bttv *btv, unsigned short freq) { int fixme = freq; /* XXX */ - int oldAudio = btv->audio; - audio(btv, AUDIO_MUTE); - udelay(AUDIO_MUTE_DELAY); - if (btv->radio) { if (btv->have_tuner) @@ -1204,10 +1123,6 @@ } } - if (!(oldAudio & AUDIO_MUTE)) { - udelay(FREQ_CHANGE_DELAY); - audio(btv, AUDIO_UNMUTE); - } } @@ -1243,10 +1158,15 @@ So, better check the total image size ... */ /* - if(mp->height>576 || mp->width>768) + if(mp->height>576 || mp->width>768+BURSTOFFSET) return -EINVAL; */ - if (mp->height*mp->width*fmtbppx2[mp->format&0x0f]/2>BTTV_MAX_FBUF) + if (mp->format >= PALETTEFMT_MAX) + return -EINVAL; + if (mp->height*mp->width*fmtbppx2[palette2fmt[mp->format]&0x0f]/2 + > BTTV_MAX_FBUF) + return -EINVAL; + if (!palette2fmt[mp->format]) return -EINVAL; /* @@ -1264,31 +1184,28 @@ return -EAGAIN;*/ ro=btv->grisc+(((btv->grabcount++)&1) ? 4096 :0); re=ro+2048; - btv->gwidth=mp->width; - btv->gheight=mp->height; - - if (mp->format > PALETTEFMT_MAX) - return -EINVAL; - btv->gfmt=palette2fmt[mp->format]; - if(btv->gfmt==0) - return -EINVAL; - - make_vrisctab(btv, ro, re, vbuf, btv->gwidth, btv->gheight, btv->gfmt); + make_vrisctab(btv, ro, re, vbuf, mp->width, mp->height, palette2fmt[mp->format]); /* bt848_set_risc_jmps(btv); */ - btor(3, BT848_CAP_CTL); - btor(3, BT848_GPIO_DMA_CTL); btv->frame_stat[mp->frame] = GBUFFER_GRABBING; if (btv->grabbing) { + btv->gfmt_next=palette2fmt[mp->format]; + btv->gwidth_next=mp->width; + btv->gheight_next=mp->height; btv->gro_next=virt_to_bus(ro); btv->gre_next=virt_to_bus(re); btv->grf_next=mp->frame; } else { + btv->gfmt=palette2fmt[mp->format]; + btv->gwidth=mp->width; + btv->gheight=mp->height; btv->gro=virt_to_bus(ro); btv->gre=virt_to_bus(re); btv->grf=mp->frame; } if (!(btv->grabbing++)) btv->risc_jmp[12]=BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ; + btor(3, BT848_CAP_CTL); + btor(3, BT848_GPIO_DMA_CTL); /* interruptible_sleep_on(&btv->capq); */ return 0; } @@ -1519,6 +1436,7 @@ &&v.norm!=VIDEO_MODE_SECAM) return -EOPNOTSUPP; btv->win.norm = v.norm; + make_vbitab(btv); bt848_set_winsize(btv); btv->channel=v.channel; return 0; @@ -1604,15 +1522,20 @@ case VIDIOCSWIN: { struct video_window vw; - struct video_clip *vcp; + struct video_clip *vcp = NULL; int on; if(copy_from_user(&vw,arg,sizeof(vw))) return -EFAULT; - if(vw.flags) + if(vw.flags || vw.width < 16 || vw.height < 16) { + bt848_cap(btv,0); return -EINVAL; - + } + if (btv->win.bpp < 4) { /* adjust and align writes */ + vw.x = (vw.x + 3) & ~3; + vw.width = (vw.width - 3) & ~3; + } btv->win.x=vw.x; btv->win.y=vw.y; btv->win.width=vw.width; @@ -1623,26 +1546,37 @@ else btv->win.interlace=0; - on=(btv->cap&3)?1:0; + on=(btv->cap&3); bt848_cap(btv,0); bt848_set_winsize(btv); - if(vw.clipcount>256) - return -EDOM; /* Too many! */ - /* * Do any clips. */ - - vcp=vmalloc(sizeof(struct video_clip)*(vw.clipcount+4)); - if(vcp==NULL) - return -ENOMEM; - if(vw.clipcount && copy_from_user(vcp,vw.clips,sizeof(struct video_clip)*vw.clipcount)) - return -EFAULT; - make_clip_tab(btv,vcp, vw.clipcount); - vfree(vcp); - if(on && btv->win.vidadr!=0) + if(vw.clipcount<0) { + if((vcp=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) + return -ENOMEM; + if(copy_from_user(vcp, vw.clips, + VIDEO_CLIPMAP_SIZE)) { + vfree(vcp); + return -EFAULT; + } + } else if (vw.clipcount) { + if((vcp=vmalloc(sizeof(struct video_clip)* + (vw.clipcount))) == NULL) + return -ENOMEM; + if(copy_from_user(vcp,vw.clips, + sizeof(struct video_clip)* + vw.clipcount)) { + vfree(vcp); + return -EFAULT; + } + } + make_clip_tab(btv, vcp, vw.clipcount); + if (vw.clipcount != 0) + vfree(vcp); + if(on && btv->win.vidadr != 0) bt848_cap(btv,1); return 0; } @@ -1700,7 +1634,9 @@ return -EPERM; if(copy_from_user(&v, arg,sizeof(v))) return -EFAULT; - if(v.depth!=8 && v.depth!=15 && v.depth!=16 && v.depth!=24 && v.depth!=32) + if(v.depth!=8 && v.depth!=15 && v.depth!=16 && + v.depth!=24 && v.depth!=32 && v.width > 16 && + v.height > 16 && v.bytesperline > 16) return -EINVAL; btv->win.vidadr=(unsigned long)v.base; btv->win.sheight=v.height; @@ -1801,9 +1737,8 @@ case VIDIOCSYNC: if(copy_from_user((void *)&i,arg,sizeof(int))) return -EFAULT; - if(i>1 || i<0) - return -EINVAL; - + if (i>1 || i<0) + return -EINVAL; switch (btv->frame_stat[i]) { case GBUFFER_UNUSED: return -EINVAL; @@ -1832,24 +1767,25 @@ return -EFAULT; break; - case BTTV_FIELDNR: + case BTTV_FIELDNR: if(copy_to_user((void *) arg, (void *) &btv->last_field, sizeof(btv->last_field))) return -EFAULT; break; - - case BTTV_PLLSET: { - struct bttv_pll_info p; - if(!capable(CAP_SYS_ADMIN)) - return -EPERM; - if(copy_from_user(&p , (void *) arg, sizeof(btv->pll))) - return -EFAULT; - btv->pll.pll_ifreq = p.pll_ifreq; - btv->pll.pll_ofreq = p.pll_ofreq; - btv->pll.pll_crystal = p.pll_crystal; + case BTTV_PLLSET: + { + struct bttv_pll_info p; + if(!capable(CAP_SYS_ADMIN)) + return -EPERM; + if(copy_from_user(&p , (void *) arg, sizeof(btv->pll))) + return -EFAULT; + btv->pll.pll_ifreq = p.pll_ifreq; + btv->pll.pll_ofreq = p.pll_ofreq; + btv->pll.pll_crystal = p.pll_crystal; break; - } + } + case VIDIOCMCAPTURE: { struct video_mmap vm; @@ -1893,7 +1829,27 @@ return -EFAULT; return 0; } - + + case BTTV_BURST_ON: + { + tvnorms[0].scaledtwidth=1135-BURSTOFFSET-2; + tvnorms[0].hdelayx1=186-BURSTOFFSET; + return 0; + } + + case BTTV_BURST_OFF: + { + tvnorms[0].scaledtwidth=1135; + tvnorms[0].hdelayx1=186; + return 0; + } + + case BTTV_PICNR: + { + /* return picture */ + return 0; + } + default: return -ENOIOCTLCMD; } @@ -2182,6 +2138,8 @@ }; static struct vidbases vbs[] = { + { PCI_VENDOR_ID_ALLIANCE, PCI_DEVICE_ID_ALLIANCE_AT3D, + "Alliance AT3D", PCI_BASE_ADDRESS_0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_215CT222, "ATI MACH64 CT", PCI_BASE_ADDRESS_0}, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_210888GX, @@ -2418,12 +2376,11 @@ { btv->type=BTTV_MIRO; - if (I2CRead(&(btv->i2c), I2C_HAUPEE)>=0) - { + if (I2CRead(&(btv->i2c), I2C_HAUPEE)>=0) { if(btv->id>849) btv->type=BTTV_HAUPPAUGE878; else - btv->type=BTTV_HAUPPAUGE; + btv->type=BTTV_HAUPPAUGE; } else if (I2CRead(&(btv->i2c), I2C_STBEE)>=0) @@ -2443,8 +2400,8 @@ if (I2CRead(&(btv->i2c), I2C_TDA8425) >=0) { - btv->audio_chip = TDA8425; - printk("bttv%d: audio chip: TDA8425\n", i); + btv->audio_chip = TDA8425; + printk("bttv%d: audio chip: TDA8425\n", i); } switch(btv->audio_chip) @@ -2459,11 +2416,11 @@ /* How do I detect the tuner type for other cards but Miro ??? */ printk(KERN_INFO "bttv%d: model: ", btv->nr); - sprintf(btv->video_dev.name,"BT%d",btv->id); switch (btv->type) { case BTTV_MIRO: + case BTTV_MIROPRO: printk("MIRO\n"); if (btv->have_tuner) { @@ -2472,7 +2429,7 @@ I2C_DRIVERID_TUNER, TUNER_SET_TYPE,&tunertype); } - strcat(btv->video_dev.name, "(Miro)"); + strcat(btv->video_dev.name,"(Miro)"); break; case BTTV_HAUPPAUGE: case BTTV_HAUPPAUGE878: @@ -2650,11 +2607,6 @@ /* select direct input */ btwrite(0x00, BT848_GPIO_REG_INP); - - btwrite(0xff, BT848_VBI_PACK_SIZE); - btwrite(1, BT848_VBI_PACK_DEL); - - btwrite(BT848_IFORM_MUX1 | BT848_IFORM_XTAUTO | BT848_IFORM_PAL_BDGHI, BT848_IFORM); @@ -2759,6 +2711,7 @@ if (astat&BT848_INT_VSYNC) { IDEBUG(printk ("bttv%d: IRQ_VSYNC\n", btv->nr)); + btv->field++; } if (astat&BT848_INT_SCERR) { IDEBUG(printk ("bttv%d: IRQ_SCERR\n", btv->nr)); @@ -2776,18 +2729,22 @@ if (stat&(1<<28)) { btv->vbip=0; + /* inc vbi frame count for detecting drops */ + (*(u32 *)&(btv->vbibuf[VBIBUF_SIZE - 4]))++; wake_up_interruptible(&btv->vbiq); } /* captured full frame */ if (stat&(2<<28)) { - wake_up_interruptible(&btv->capq); btv->last_field=btv->field; btv->grab++; btv->frame_stat[btv->grf] = GBUFFER_DONE; if ((--btv->grabbing)) { + btv->gfmt = btv->gfmt_next; + btv->gwidth = btv->gwidth_next; + btv->gheight = btv->gheight_next; btv->gro = btv->gro_next; btv->gre = btv->gre_next; btv->grf = btv->grf_next; @@ -2844,10 +2801,12 @@ } if (astat&BT848_INT_HLOCK) { +#if 0 if ((dstat&BT848_DSTATUS_HLOC) || (btv->radio)) audio(btv, AUDIO_ON); else audio(btv, AUDIO_OFF); +#endif } if (astat&BT848_INT_I2CDONE) @@ -2923,18 +2882,28 @@ printk("irq: %d, ",btv->irq); printk("memory: 0x%08x.\n", btv->bt848_adr); - btv->pll.pll_ifreq=0; - btv->pll.pll_ofreq=0; - btv->pll.pll_crystal=0; - if(pll[btv->nr]) - if (!(btv->id==848 && btv->revision==0x11)) - { - printk(KERN_INFO "bttv%d: internal PLL, single crystal operation enabled\n",bttv_num); - btv->pll.pll_ofreq=28636363; + btv->pll.pll_ifreq=0; + btv->pll.pll_ofreq=0; + btv->pll.pll_crystal=0; + btv->pll.pll_current=0; + if (!(btv->id==848 && btv->revision==0x11)) { + switch (pll[btv->nr]) { + case 0: + /* off */ + break; + case 1: + /* 28 MHz crystal installed */ + btv->pll.pll_ifreq=28636363; + btv->pll.pll_crystal=BT848_IFORM_XT0; + break; + case 2: + /* 35 MHz crystal installed */ btv->pll.pll_ifreq=35468950; btv->pll.pll_crystal=BT848_IFORM_XT1; + break; } - + } + btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000); /* clear interrupt mask */ @@ -2997,7 +2966,7 @@ dev = dev->next; } if(bttv_num) - printk(KERN_INFO "bttv: %d BT8xx card(s) found.\n", bttv_num); + printk(KERN_INFO "bttv: %d Bt8xx card(s) found.\n", bttv_num); return bttv_num; } @@ -3113,4 +3082,3 @@ * tab-width: 8 * End: */ - diff -u --recursive --new-file v2.1.125/linux/drivers/char/bttv.h linux/drivers/char/bttv.h --- v2.1.125/linux/drivers/char/bttv.h Sat Sep 5 16:46:40 1998 +++ linux/drivers/char/bttv.h Sat Oct 17 15:52:18 1998 @@ -31,12 +31,11 @@ #include "bt848.h" #include -#define MAX_CLIPRECS 100 #define MAX_GBUFFERS 2 #define RISCMEM_LEN (32744*2) /* maximum needed buffer size for extended VBI frame mode capturing */ -#define BTTV_MAX_FBUF 0x151000 +#define BTTV_MAX_FBUF 0x190000 #ifdef __KERNEL__ @@ -56,11 +55,11 @@ ushort depth; }; - struct bttv_pll_info { - unsigned int pll_ifreq; /* PLL input frequency */ - unsigned int pll_ofreq; /* PLL output frequency */ + unsigned int pll_ifreq; /* PLL input frequency */ + unsigned int pll_ofreq; /* PLL output frequency */ unsigned int pll_crystal; /* Crystal used for input */ + unsigned int pll_current; /* Current programmed ofrq*/ }; struct bttv @@ -116,6 +115,7 @@ struct gbuffer *ogbuffers; struct gbuffer *egbuffers; u16 gwidth, gheight, gfmt; + u16 gwidth_next, gheight_next, gfmt_next; u32 *grisc; unsigned long gro; @@ -143,6 +143,7 @@ int i2c_command; int triton1; }; + #endif /*The following should be done in more portable way. It depends on define @@ -167,6 +168,10 @@ #define BTTV_GRAB _IOR('v' , BASE_VIDIOCPRIVATE+2, struct gbuf) #define BTTV_FIELDNR _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int) #define BTTV_PLLSET _IOW('v' , BASE_VIDIOCPRIVATE+3, struct bttv_pll_info) +#define BTTV_BURST_ON _IOR('v' , BASE_VIDIOCPRIVATE+4, int) +#define BTTV_BURST_OFF _IOR('v' , BASE_VIDIOCPRIVATE+5, int) +#define BTTV_NAGRAVERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int) +#define BTTV_PICNR _IOR('v' , BASE_VIDIOCPRIVATE+7, int) #define BTTV_UNKNOWN 0x00 @@ -178,7 +183,9 @@ #define BTTV_AVERMEDIA 0x06 #define BTTV_MATRIX_VISION 0x07 #define BTTV_FLYVIDEO 0x08 -#define BTTV_HAUPPAUGE878 0x09 +#define BTTV_TURBOTV 0x09 +#define BTTV_HAUPPAUGE878 0x0a +#define BTTV_MIROPRO 0x0b #define AUDIO_TUNER 0x00 #define AUDIO_RADIO 0x01 diff -u --recursive --new-file v2.1.125/linux/drivers/char/bw-qcam.c linux/drivers/char/bw-qcam.c --- v2.1.125/linux/drivers/char/bw-qcam.c Tue Aug 18 22:02:03 1998 +++ linux/drivers/char/bw-qcam.c Fri Oct 9 11:56:59 1998 @@ -296,7 +296,7 @@ if (reg != lastreg) count++; lastreg = reg; - mdelay(1); + mdelay(2); } /* Be liberal in what you accept... */ diff -u --recursive --new-file v2.1.125/linux/drivers/char/esp.c linux/drivers/char/esp.c --- v2.1.125/linux/drivers/char/esp.c Mon Sep 28 10:51:33 1998 +++ linux/drivers/char/esp.c Fri Oct 9 11:56:59 1998 @@ -395,15 +395,20 @@ static _INLINE_ void receive_chars_dma(struct esp_struct *info, int num_bytes) { + unsigned long flags; info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; dma_bytes = num_bytes; info->stat_flags |= ESP_STAT_DMA_RX; + + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma, DMA_MODE_READ); set_dma_addr(dma, virt_to_bus(dma_buffer)); set_dma_count(dma, dma_bytes); enable_dma(dma); + release_dma_lock(flags); + serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX); } @@ -412,12 +417,17 @@ { struct tty_struct *tty = info->tty; int num_bytes; - + unsigned long flags; + + + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); info->stat_flags &= ~ESP_STAT_DMA_RX; num_bytes = dma_bytes - get_dma_residue(dma); + release_dma_lock(flags); + info->icount.rx += num_bytes; memcpy(tty->flip.char_buf_ptr, dma_buffer, num_bytes); @@ -534,6 +544,8 @@ static _INLINE_ void transmit_chars_dma(struct esp_struct *info, int num_bytes) { + unsigned long flags; + dma_bytes = num_bytes; if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) { @@ -564,34 +576,46 @@ } info->stat_flags |= ESP_STAT_DMA_TX; + + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma, DMA_MODE_WRITE); set_dma_addr(dma, virt_to_bus(dma_buffer)); set_dma_count(dma, dma_bytes); enable_dma(dma); + release_dma_lock(flags); + serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); } static _INLINE_ void transmit_chars_dma_done(struct esp_struct *info) { int num_bytes; + unsigned long flags; + + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); num_bytes = dma_bytes - get_dma_residue(dma); info->icount.tx += dma_bytes; + release_dma_lock(flags); if (dma_bytes != num_bytes) { dma_bytes -= num_bytes; memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes); + + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma, DMA_MODE_WRITE); set_dma_addr(dma, virt_to_bus(dma_buffer)); set_dma_count(dma, dma_bytes); enable_dma(dma); + release_dma_lock(flags); + serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); } else { dma_bytes = 0; @@ -1003,7 +1027,7 @@ */ static void shutdown(struct esp_struct * info) { - unsigned long flags; + unsigned long flags, f; if (!(info->flags & ASYNC_INITIALIZED)) return; @@ -1025,8 +1049,11 @@ /* stop a DMA transfer on the port being closed */ if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) { + f=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); + release_dma_lock(f); + dma_bytes = 0; } diff -u --recursive --new-file v2.1.125/linux/drivers/char/hfmodem/main.c linux/drivers/char/hfmodem/main.c --- v2.1.125/linux/drivers/char/hfmodem/main.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/hfmodem/main.c Fri Oct 9 12:20:27 1998 @@ -148,14 +148,6 @@ #define SP_PAR 2 #define SP_MIDI 4 -/* ---------------------------------------------------------------------- */ - -static int parptt_preempt(void *handle) -{ - /* we cannot relinquish the port in the middle of an operation */ - return 1; -} - /* --------------------------------------------------------------------- */ static void parptt_wakeup(void *handle) @@ -176,8 +168,8 @@ pp = pp->next; if (!pp) return 0; - if (!(dev->ptt_out.pardev = parport_register_device(pp, hfmodem_drvname, parptt_preempt, parptt_wakeup, - NULL, PARPORT_DEV_LURK, dev))) + if (!(dev->ptt_out.pardev = parport_register_device(pp, hfmodem_drvname, NULL, parptt_wakeup, + NULL, PARPORT_DEV_EXCL, dev))) return 0; return 1; } diff -u --recursive --new-file v2.1.125/linux/drivers/char/istallion.c linux/drivers/char/istallion.c --- v2.1.125/linux/drivers/char/istallion.c Wed Jun 24 22:54:05 1998 +++ linux/drivers/char/istallion.c Fri Oct 23 08:26:04 1998 @@ -170,7 +170,7 @@ */ static char *stli_drvtitle = "Stallion Intelligent Multiport Serial Driver"; static char *stli_drvname = "istallion"; -static char *stli_drvversion = "5.4.6"; +static char *stli_drvversion = "5.4.7"; static char *stli_serialname = "ttyE"; static char *stli_calloutname = "cue"; @@ -635,16 +635,21 @@ * board. This is also a very useful debugging tool. */ static struct file_operations stli_fsiomem = { - NULL, - stli_memread, - stli_memwrite, - NULL, - NULL, - stli_memioctl, - NULL, - stli_memopen, - stli_memclose, - NULL + NULL, /* llseek */ + stli_memread, /* read */ + stli_memwrite, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + stli_memioctl, /* ioctl */ + NULL, /* mmap */ + stli_memopen, /* open */ + NULL, /* flush */ + stli_memclose, /* release */ + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL /* lock */ }; /*****************************************************************************/ diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-analog.c linux/drivers/char/joystick/joy-analog.c --- v2.1.125/linux/drivers/char/joystick/joy-analog.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-analog.c Wed Oct 21 08:43:33 1998 @@ -73,7 +73,7 @@ u = a = ((info->mask[0] | info->mask[1]) & JS_AN_AXES_STD) | (info->extensions & JS_AN_HAT_FCS) | ((info->extensions & JS_AN_BUTTONS_PXY_XY) >> 2) | ((info->extensions & JS_AN_BUTTONS_PXY_UV) >> 4); - outb(inb(io),io); + outb(0xff,io); t = js_get_time_a(); do { v = inb(io) & a; @@ -130,7 +130,7 @@ if (check_region(io, 1)) return port; if (((u = inb(io)) & 3) == 3) return port; - outb(u,io); + outb(0xff,io); u = inb(io); udelay(JS_AN_MAX_TIME); u = (inb(io) ^ u) & u; diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-assasin.c linux/drivers/char/joystick/joy-assasin.c --- v2.1.125/linux/drivers/char/joystick/joy-assasin.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-assasin.c Wed Oct 21 08:43:33 1998 @@ -84,7 +84,7 @@ __save_flags(flags); __cli(); - outb(inb(io),io); + outb(0xff,io); u = inb(io); t = js_get_time(); @@ -306,7 +306,7 @@ if (check_region(io, 1)) return port; if (((u = inb(io)) & 3) == 3) return port; - outb(u,io); + outb(0xff,io); if (!((inb(io) ^ u) & ~u & 0xf)) return port; if (js_as_read_packet(io, 1, data) != 1) return port; diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-console.c linux/drivers/char/joystick/joy-console.c --- v2.1.125/linux/drivers/char/joystick/joy-console.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-console.c Wed Oct 21 08:43:33 1998 @@ -1,5 +1,5 @@ /* - * joy-console.c Version 0.10 + * joy-console.c Version 0.11V * * Copyright (c) 1998 Andree Borrmann */ @@ -57,8 +57,6 @@ struct js_console_info { #ifdef USE_PARPORT struct pardevice *port; /* parport device */ - int use; /* use count */ - int wanted; /* parport wanted */ #else int port; /* hw port */ #endif @@ -345,19 +343,11 @@ int js_console_open(struct js_dev *dev) { - MOD_INC_USE_COUNT; - #ifdef USE_PARPORT - { - struct js_console_info *info = dev->port->info; - if (!info->use && parport_claim(info->port)) { - printk(KERN_WARNING "joy-console: parport busy!\n"); /* port currently not available ... */ - info->wanted++; /* we'll claim it on wakeup */ - return 0; - } - info->use++; - } + struct js_console_info *info = dev->port->info; + if (!MOD_IN_USE && parport_claim(info->port)) return -EBUSY; #endif + MOD_INC_USE_COUNT; return 0; } @@ -369,32 +359,13 @@ { #ifdef USE_PARPORT struct js_console_info *info = dev->port->info; - - if (!--info->use) - parport_release(info->port); #endif MOD_DEC_USE_COUNT; - - return 0; -} - -/* - * parport wakeup callback: claim the port! - */ - #ifdef USE_PARPORT -static void js_console_wakeup(void *v) -{ - struct js_console_info *info = js_console_port->info; /* FIXME! We can have more than 1 port! */ - - if (!info->use && info->wanted) - { - parport_claim(info->port); - info->use++; - info->wanted--; - } -} + if (!MOD_IN_USE) parport_release(info->port); #endif + return 0; +} #ifdef MODULE void cleanup_module(void) @@ -466,9 +437,9 @@ return port; } - info.port = parport_register_device(pp, "joystick (console)", NULL, js_console_wakeup, NULL, 0, NULL); - info.wanted = 0; - info.use = 0; + info.port = parport_register_device(pp, "joystick (console)", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); + if (!info.port) + return port; } if (parport_claim(info.port)) diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-db9.c linux/drivers/char/joystick/joy-db9.c --- v2.1.125/linux/drivers/char/joystick/joy-db9.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-db9.c Wed Oct 21 08:43:33 1998 @@ -1,5 +1,5 @@ /* - * joy-db9.c Version 0.3V + * joy-db9.c Version 0.5V * * Copyright (c) 1998 Andree Borrmann */ @@ -47,8 +47,8 @@ #define JS_GENESIS5_PAD 0x05 #define JS_GENESIS6_PAD 0x06 #define JS_SATURN_PAD 0x07 - -#define JS_MAX_PAD (JS_SATURN_PAD + 1) +#define JS_MULTI_0802 0x08 +#define JS_MAX_PAD 0x09 #define JS_DB9_UP 0x01 #define JS_DB9_DOWN 0x02 @@ -78,11 +78,9 @@ struct js_db9_info { #ifdef USE_PARPORT struct pardevice *port; /* parport device */ - int wanted; /* parport wanted */ #else int port; /* hw port */ #endif - int use; /* use count */ int mode; /* pad mode */ }; @@ -97,6 +95,17 @@ switch(info->mode) { + case JS_MULTI_0802: + + data = JS_PAR_STATUS(info->port) >> 3; + + axes[0][1] = (data&JS_DB9_DOWN ?0:1) - (data&JS_DB9_UP ?0:1); + axes[0][0] = (data&JS_DB9_RIGHT?0:1) - (data&JS_DB9_LEFT?0:1); + + buttons[0][0] = (data&JS_DB9_FIRE1?1:0); + + break; + case JS_MULTI_STICK: data = JS_PAR_DATA_IN(info->port); @@ -262,19 +271,14 @@ { struct js_db9_info *info = dev->port->info; - MOD_INC_USE_COUNT; - if (!info->use) { - + if (!MOD_IN_USE) { #ifdef USE_PARPORT - if (parport_claim(info->port)) { - printk(KERN_WARNING "joy-db9: parport busy\n"); /* port currently not available ... */ - info->wanted++; /* we'll claim it on wakeup */ - return 0; - } + if (parport_claim(info->port)) return -EBUSY; #endif js_db9_enable_ps2(info); } - info->use++; + + MOD_INC_USE_COUNT; return 0; } @@ -287,9 +291,8 @@ struct js_db9_info *info = dev->port->info; MOD_DEC_USE_COUNT; - info->use--; - if (!info->use) { + if (!MOD_IN_USE) { js_db9_disable_ps2(info); #ifdef USE_PARPORT parport_release(info->port); @@ -298,25 +301,6 @@ return 0; } -/* - * parport wakeup callback: claim the port! - */ - -#ifdef USE_PARPORT -static void js_db9_wakeup(void *v) -{ - struct js_db9_info *info = js_db9_port->info; /* FIXME! We can have more than 1 port! */ - - if (!info->use && info->wanted) - { - parport_claim(info->port); - js_db9_enable_ps2(info); - info->use++; - info->wanted--; - } -} -#endif - #ifdef MODULE void cleanup_module(void) { @@ -363,9 +347,9 @@ static struct js_port __init *js_db9_probe(int *config, struct js_port *port) { struct js_db9_info info; - char buttons[JS_MAX_PAD] = {0,1,2,4,0,6,7,8}; + char buttons[JS_MAX_PAD] = {0,1,2,4,0,6,7,8,1}; char *name[JS_MAX_PAD] = {NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad", - NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad"}; + NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick"}; if (config[0] < 0) return port; if (config[1] < 0 || config[1] >= JS_MAX_PAD || !name[config[1]]) return port; @@ -389,8 +373,9 @@ return port; } - info.port = parport_register_device(pp, "joystick (db9)", NULL, js_db9_wakeup, NULL, 0, NULL); - info.wanted = 0; + info.port = parport_register_device(pp, "joystick (db9)", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); + if (!info.port) + return port; } #else info.port = config[0]; @@ -400,7 +385,6 @@ #endif info.mode = config[1]; - info.use = 0; port = js_register_port(port, &info, 1, sizeof(struct js_db9_info), js_db9_read); diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-joydump.c linux/drivers/char/joystick/joy-joydump.c --- v2.1.125/linux/drivers/char/joystick/joy-joydump.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-joydump.c Wed Dec 31 16:00:00 1969 @@ -1,172 +0,0 @@ -/* - * joydump.c Version 1.2 - * - * Copyright (c) 1996-1998 Vojtech Pavlik - */ - -/* - * This is just a very simple driver that can dump the data - * out of the joystick port into the syslog ... - */ - -/* - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to , or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic - */ - -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Vojtech Pavlik "); - -#define JS_PORT 0x201 - -#ifdef __i386__ -static unsigned int get_time(void) -{ - unsigned int x; - __asm__ __volatile__ ( "rdtsc" : "=A" (x) ); - return x; -} -#else - -#ifdef __alpha__ -static unsigned int get_time(void) -{ - unsigned int x; - __asm__ __volatile__ ( "rpcc %0" : "=r" (x) ); - return x; -} -#else - -#error "Sorry, you need a precise timer for this - define some in joydump.c" - -#endif -#endif - -#define BUF_SIZE 128 - -struct datatype { - unsigned int time; - unsigned char data; -}; - -static struct datatype buf[BUF_SIZE]; - -int init_module(void) -{ - int i, j; - unsigned int t, t1; - int timeout, div; - unsigned long flags; - unsigned char u; - - printk(KERN_INFO "joydump: ,------------------- START ------------------.\n"); - -/* - * Calibrate. - */ - - __save_flags(flags); - __cli(); - t = get_time(); - udelay(1000); - t1 = get_time(); - __restore_flags(flags); - - timeout = t1 - t; - div = timeout / 1000; - - printk(KERN_INFO "joydump: | Timer ticks at %d.%02d MHz. |\n", - timeout / 1000, timeout / 10 % 100); - - __save_flags(flags); - __cli(); - t = get_time(); - inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); - inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); inb(JS_PORT); - t1 = get_time(); - __restore_flags(flags); - - printk(KERN_INFO "joydump: | I/O at %#x takes %d.%02d us. |\n", - JS_PORT, (t1 - t) / div / 10, (t1 - t) * 10 / div % 100); - - timeout *= 20; - -/* - * Gather data. - */ - - __save_flags(flags); - __cli(); - - u = inb(JS_PORT); - t = t1 = get_time(); - buf[0].data = u; - buf[0].time = t1; - i = 1; - - outb(u,JS_PORT); - - while (i < BUF_SIZE && t1 - t < timeout) { - - t1 = get_time(); - buf[i].data = inb(JS_PORT); - - if (buf[i].data != u) { - u = buf[i].data; - buf[i].time = t1; - i++; - } - } - - __restore_flags(flags); - -/* - * Dump data. - */ - - - t = i; - - printk(KERN_INFO "joydump: >------------------- DATA -------------------<\n"); - printk(KERN_INFO "joydump: | index: %3d delta: %3d.%02d us data: ", 0, 0, 0); - for (j = 7; j >= 0; j--) - printk("%d",(buf[0].data >> j) & 1); - printk(" |\n"); - for (i = 1; i < t; i++) { - printk(KERN_INFO "joydump: | index: %3d delta: %3d.%02d us data: ", i, - (buf[i].time - buf[i-1].time) / div, (buf[i].time - buf[i-1].time) * 100 / div % 100); - for (j = 7; j >= 0; j--) - printk("%d",(buf[i].data >> j) & 1); - printk(" |\n"); - } - - printk(KERN_INFO "joydump: `-------------------- END -------------------'\n"); - - return -1; -} - -void cleanup_module(void) -{ -} diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-lightning.c linux/drivers/char/joystick/joy-lightning.c --- v2.1.125/linux/drivers/char/joystick/joy-lightning.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-lightning.c Wed Oct 21 08:43:34 1998 @@ -109,18 +109,42 @@ js_an_decode(&info->an, axes, buttons); + return 0; +} + +/* + * js_l4_getcal() reads the L4 with calibration values. + */ + +static int js_l4_getcal(int port, int *cal) +{ + int i; + outb(JS_L4_SELECT_ANALOG, JS_L4_PORT); + outb(JS_L4_SELECT_DIGITAL + (port >> 2), JS_L4_PORT); + + if (inb(JS_L4_PORT) & JS_L4_BUSY) return -1; + outb(JS_L4_CMD_GETCAL, JS_L4_PORT); + + if (js_l4_wait_ready()) return -1; + if (inb(JS_L4_PORT) != JS_L4_SELECT_DIGITAL + (port >> 2)) return -1; + + if (js_l4_wait_ready()) return -1; + outb(port & 3, JS_L4_PORT); + + for (i = 0; i < 4; i++) { + if (js_l4_wait_ready()) return -1; + cal[i] = inb(JS_L4_PORT); + } return 0; } -#if 0 - /* * js_l4_setcal() programs the L4 with calibration values. */ -static int js_l4_setcal(int port, int *calib) +static int js_l4_setcal(int port, int *cal) { int i; @@ -128,54 +152,61 @@ outb(JS_L4_SELECT_DIGITAL + (port >> 2), JS_L4_PORT); if (inb(JS_L4_PORT) & JS_L4_BUSY) return -1; - outb(JS_L4_CMD_SETCAL, JS_L4_PORT); + if (js_l4_wait_ready()) return -1; + if (inb(JS_L4_PORT) != JS_L4_SELECT_DIGITAL + (port >> 2)) return -1; - outb(port & 3, JS_L4_PORT); if (js_l4_wait_ready()) return -1; + outb(port & 3, JS_L4_PORT); for (i = 0; i < 4; i++) { - outb(calib[0], JS_L4_PORT); if (js_l4_wait_ready()) return -1; + outb(cal[i], JS_L4_PORT); } - outb(JS_L4_SELECT_ANALOG, JS_L4_PORT); - return 0; } +/* + * js_l4_calibrate() calibrates the L4 for the attached device, so + * that the device's resistance fits into the L4's 8-bit range. + */ static void js_l4_calibrate(struct js_l4_info *info) { - int calib[4]; int i; + int cal[4]; + int axes[4]; + int t; + + js_l4_getcal(info->port, cal); + for (i = 0; i < 4; i++) + axes[i] = info->an.axes[i]; + if ((info->an.extensions & JS_AN_BUTTON_PXY_X) && !(info->an.extensions & JS_AN_BUTTON_PXY_U)) - info->an.axes[2] >>= 2; /* Pad button X */ + axes[2] >>= 1; /* Pad button X */ if ((info->an.extensions & JS_AN_BUTTON_PXY_Y) && !(info->an.extensions & JS_AN_BUTTON_PXY_V)) - info->an.axes[3] >>= 2; /* Pad button Y */ + axes[3] >>= 1; /* Pad button Y */ if (info->an.extensions & JS_AN_HAT_FCS) - info->an.axes[3] >>= 2; /* FCS hat */ - - if (((info->an.mask[0] & 0xb) == 0xb) || - ((info->an.mask[1] & 0xb) == 0xb)) - info->an.axes[3] = (info->an.axes[0] + info->an.axes[1]) >> 1; /* Throttle */ + axes[3] >>= 1; /* FCS hat */ - for (i = 0; i < 4; i++) - calib[i] = (info->an.axes[i] * 255) / 100; - - for (i = 0; i < 4; i++) - if (calib[i] > 255) calib[i] = 255; + if (((info->an.mask[0] & 0xb) == 0xb) || ((info->an.mask[1] & 0xb) == 0xb)) + axes[3] = (axes[0] + axes[1]) >> 1; /* Throttle */ - js_l4_setcal(info->port, calib); + for (i = 0; i < 4; i++) { + t = (axes[i] * cal[i]) / 100; + if (t > 255) t = 255; + info->an.axes[i] = (info->an.axes[i] * cal[i]) / t; + cal[i] = t; + } + js_l4_setcal(info->port, cal); } -#endif - /* * js_l4_open() is a callback from the file open routine. */ @@ -200,25 +231,21 @@ * js_l4_probe() probes for joysticks on the L4 cards. */ -static struct js_port __init *js_l4_probe(int cards, int l4port, int mask0, int mask1, struct js_port *port) +static struct js_port __init *js_l4_probe(unsigned char *cards, int l4port, int mask0, int mask1, struct js_port *port) { struct js_l4_info iniinfo; struct js_l4_info *info = &iniinfo; -#if 0 - int calib[4] = {255, 255, 255, 255}; -#endif + int cal[4] = {255,255,255,255}; int i, numdev; unsigned char u; if (l4port < 0) return port; - if (~cards & (1 << (l4port >> 2))) return port; + if (!cards[(l4port >> 2)]) return port; memset(info, 0, sizeof(struct js_l4_info)); info->port = l4port; -#if 0 - js_l4_setcal(info->port, calib); -#endif + if (cards[l4port >> 2] > 0x28) js_l4_setcal(info->port, cal); if (js_l4_read(info, NULL, NULL)) return port; for (i = u = 0; i < 4; i++) if (info->an.axes[i] < 253) u |= 1 << i; @@ -236,9 +263,7 @@ info = port->info; -#if 0 js_l4_calibrate(info); -#endif js_l4_read(info, port->axes, port->buttons); js_an_init_corr(&info->an, port->axes, port->corr, 0); @@ -249,12 +274,12 @@ * js_l4_card_probe() probes for presence of the L4 card(s). */ -static int __init js_l4_card_probe(void) +static void __init js_l4_card_probe(unsigned char *cards) { - int i, cards = 0; + int i; unsigned char rev = 0; - if (check_region(JS_L4_PORT, 1)) return 0; + if (check_region(JS_L4_PORT, 1)) return; for (i = 0; i < 2; i++) { @@ -273,15 +298,12 @@ if (js_l4_wait_ready()) continue; rev = inb(JS_L4_PORT); - cards |= (1 << i); + cards[i] = rev; printk(KERN_INFO "js: PDPI Lightning 4 %s card (ports %d-%d) firmware v%d.%d found at %#x\n", i ? "secondary" : "primary", (i << 2), (i << 2) + 3, rev >> 4, rev & 0xf, JS_L4_PORT); } - outb(JS_L4_SELECT_ANALOG, JS_L4_PORT); - - return cards; } #ifndef MODULE @@ -295,18 +317,19 @@ #ifdef MODULE int init_module(void) #else -int __init js_l4_an_init(void) +int __init js_l4_init(void) #endif { - int i, cards; + int i; + unsigned char cards[2] = {0, 0}; - cards = js_l4_card_probe(); + js_l4_card_probe(cards); if (js_l4[0] >= 0) { for (i = 0; (js_l4[i*3] >= 0) && i < 8; i++) js_l4_port = js_l4_probe(cards, js_l4[i*3], js_l4[i*3+1], js_l4[i*3+2], js_l4_port); } else { - for (i = 0; i < (cards << 2); i++) + for (i = 0; i < 8; i++) js_l4_port = js_l4_probe(cards, i, 0, 0, js_l4_port); } @@ -326,15 +349,18 @@ void cleanup_module(void) { int i; + int cal[4] = {59, 59, 59, 59}; + struct js_l4_info *info; while (js_l4_port) { for (i = 0; i < js_l4_port->ndevs; i++) if (js_l4_port->devs[i]) js_unregister_device(js_l4_port->devs[i]); + info = js_l4_port->info; + js_l4_setcal(info->port, cal); js_l4_port = js_unregister_port(js_l4_port); } outb(JS_L4_SELECT_ANALOG, JS_L4_PORT); release_region(JS_L4_PORT, 1); - } #endif diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-logitech.c linux/drivers/char/joystick/joy-logitech.c --- v2.1.125/linux/drivers/char/joystick/joy-logitech.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-logitech.c Wed Oct 21 08:43:34 1998 @@ -92,7 +92,7 @@ __save_flags(flags); __cli(); - outb(u,io); + outb(0xff,io); u = inb(io); t = js_get_time(); @@ -232,7 +232,7 @@ static void __init js_lt_trigger_sequence(int io, int *seq) { while (*seq) { - outb(inb(io),io); + outb(0xff,io); udelay(*seq++); } } @@ -288,7 +288,7 @@ if (check_region(io, 1)) return port; if (((u = inb(io)) & 3) == 3) return port; - outb(u,io); + outb(0xff,io); if (!((inb(io) ^ u) & ~u & 0xf)) return port; if (!(i = js_lt_read_packet(io, &data))) { diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-sidewinder.c linux/drivers/char/joystick/joy-sidewinder.c --- v2.1.125/linux/drivers/char/joystick/joy-sidewinder.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-sidewinder.c Wed Oct 21 08:43:34 1998 @@ -68,21 +68,20 @@ /* * js_sw_init_digital() switches a SideWinder into digital mode. - * It currently switches to 2-bit mode only (FIXME). */ static void __init js_sw_init_digital(int io) { unsigned int t; unsigned int timeout = (js_time_speed * JS_SW_MAX_TIME) >> 10; - int delays[] = {100, 850, 400, 0}; + int delays[] = {140, 140+726, 140+300, 0}; int i = 0; unsigned long flags; __save_flags(flags); __cli(); do { - outb(inb(io),io); + outb(0xff,io); t = js_get_time(); while ((inb(io) & 1) && (js_delta(js_get_time(),t) < timeout)); udelay(delays[i]); @@ -112,7 +111,7 @@ __save_flags(flags); __cli(); - outb(inb(io),io); + outb(0xff,io); v = inb(io); t = js_get_time(); @@ -214,7 +213,6 @@ info->optimize = 0; return -1; } - axes[0][0] = ((data << 4) & 0x380) | ((data >> 16) & 0x07f); axes[0][1] = ((data << 7) & 0x380) | ((data >> 24) & 0x07f); axes[0][2] = ((data >> 28) & 0x180) | ((data >> 40) & 0x07f); @@ -367,7 +365,7 @@ if (check_region(io, 1)) return port; if (((u = inb(io)) & 3) == 3) return port; - outb(u,io); + outb(0xff,io); if (!((inb(io) ^ u) & ~u & 0xf)) return port; i = js_sw_read_packet(io, JS_SW_MAX_LENGTH, -1, JS_SW_EXT_STROBE, &data); @@ -390,7 +388,7 @@ case 45: case 60: info.mode = JS_SW_MODE_GP; - outb(inb(io),io); /* Kick into 3-bit mode */ + outb(0xff,io); /* Kick into 3-bit mode */ udelay(JS_SW_MAX_TIME); i = js_sw_read_packet(io, 60, -1, JS_SW_EXT_STROBE, &data); /* Get total length */ udelay(JS_SW_MIN_TIME); diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-thrustmaster.c linux/drivers/char/joystick/joy-thrustmaster.c --- v2.1.125/linux/drivers/char/joystick/joy-thrustmaster.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-thrustmaster.c Wed Oct 21 08:43:34 1998 @@ -94,7 +94,7 @@ __save_flags(flags); __cli(); - outb(inb(io),io); + outb(0xff,io); t = js_get_time(); @@ -262,7 +262,7 @@ if (check_region(io, 1)) return port; if (((u = inb(io)) & 3) == 3) return port; - outb(u,io); + outb(0xff,io); if (!((inb(io) ^ u) & ~u & 0xf)) return port; if(js_tm_read_packet(io, data)) { diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joy-turbografx.c linux/drivers/char/joystick/joy-turbografx.c --- v2.1.125/linux/drivers/char/joystick/joy-turbografx.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joy-turbografx.c Wed Oct 21 08:43:34 1998 @@ -61,8 +61,6 @@ struct js_tg_info { #ifdef USE_PARPORT struct pardevice *port; /* parport device */ - int use; /* use count */ - int wanted; /* parport wanted */ #else int port; /* hw port */ #endif @@ -99,19 +97,11 @@ int js_tg_open(struct js_dev *dev) { - MOD_INC_USE_COUNT; - #ifdef USE_PARPORT - { - struct js_tg_info *info = dev->port->info; - if (!info->use && parport_claim(info->port)) { - printk(KERN_WARNING "joy-tg: parport busy\n"); /* port currently not available ... */ - info->wanted++; /* we'll claim it on wakeup */ - return 0; - } - info->use++; - } + struct js_tg_info *info = dev->port->info; + if (!MOD_IN_USE && parport_claim(info->port)) return -EBUSY; #endif + MOD_INC_USE_COUNT; return 0; } @@ -122,33 +112,14 @@ int js_tg_close(struct js_dev *dev) { #ifdef USE_PARPORT - struct js_tg_info *info = dev->port->info; - - if (!--info->use) - parport_release(info->port); + struct js_tg_info *info = dev->port->info; #endif - MOD_DEC_USE_COUNT; - - return 0; -} - -/* - * parport wakeup callback: claim the port! - */ - + MOD_DEC_USE_COUNT; #ifdef USE_PARPORT -static void js_tg_wakeup(void *v) -{ - struct js_tg_info *info = js_tg_port->info; /* FIXME! We can have more than 1 port! */ - - if (!info->use && info->wanted) - { - parport_claim(info->port); - info->use++; - info->wanted--; - } -} + if (!MOD_IN_USE) parport_release(info->port); #endif + return 0; +} #ifdef MODULE void cleanup_module(void) @@ -217,9 +188,9 @@ return port; } - info.port = parport_register_device(pp, "joystick (turbografx)", NULL, js_tg_wakeup, NULL, 0, NULL); - info.wanted = 0; - info.use = 0; + info.port = parport_register_device(pp, "joystick (turbografx)", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); + if (!info.port) + return port; } #else info.port = config[0]; diff -u --recursive --new-file v2.1.125/linux/drivers/char/joystick/joystick.c linux/drivers/char/joystick/joystick.c --- v2.1.125/linux/drivers/char/joystick/joystick.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/joystick/joystick.c Wed Oct 21 08:43:34 1998 @@ -859,6 +859,7 @@ struct js_dev *jd = js_dev; int i = MINOR(inode->i_rdev); unsigned long flags; + int result; if (MAJOR(inode->i_rdev) != JOYSTICK_MAJOR) return -EINVAL; @@ -870,7 +871,7 @@ if (!jd) return -ENODEV; - jd->open(jd); + if ((result = jd->open(jd))) return result; MOD_INC_USE_COUNT; if (!js_use_count++) js_do_timer(0); diff -u --recursive --new-file v2.1.125/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.1.125/linux/drivers/char/lp.c Wed Sep 9 14:51:07 1998 +++ linux/drivers/char/lp.c Sat Oct 17 15:52:18 1998 @@ -543,7 +543,7 @@ if (( i & 1) != 0) { Byte= (Byte | z<<4); - if (put_user(Byte, (char *)temp)) + if (__put_user(Byte, (char *)temp)) return -EFAULT; temp++; } else Byte=z; @@ -768,7 +768,7 @@ lp_table[nr].dev = parport_register_device(port, "lp", lp_preempt, NULL, lp_interrupt, - PARPORT_DEV_TRAN, + 0, (void *) &lp_table[nr]); if (lp_table[nr].dev == NULL) return 1; diff -u --recursive --new-file v2.1.125/linux/drivers/char/misc.c linux/drivers/char/misc.c --- v2.1.125/linux/drivers/char/misc.c Mon Sep 28 10:51:33 1998 +++ linux/drivers/char/misc.c Fri Oct 9 12:30:15 1998 @@ -66,7 +66,6 @@ extern int adbdev_init(void); extern int bus_mouse_init(void); -extern int psaux_init(void); extern int qpmouse_init(void); extern int ms_bus_mouse_init(void); extern int atixl_busmouse_init(void); @@ -156,8 +155,13 @@ } if (misc->minor < DYNAMIC_MINORS) misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); - misc->next = &misc_list; - misc->prev = misc_list.prev; + + /* + * Add it to the front, so that later devices can "override" + * earlier defaults + */ + misc->prev = &misc_list; + misc->next = misc_list.next; misc->prev->next = misc; misc->next->prev = misc; return 0; @@ -199,10 +203,7 @@ bus_mouse_init(); #endif #if defined CONFIG_82C710_MOUSE - qpmouse_init(); /* This must be before psaux_init */ -#endif -#if defined CONFIG_PSMOUSE - psaux_init(); + qpmouse_init(); #endif #ifdef CONFIG_MS_BUSMOUSE ms_bus_mouse_init(); diff -u --recursive --new-file v2.1.125/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c --- v2.1.125/linux/drivers/char/pc_keyb.c Mon Sep 28 10:51:33 1998 +++ linux/drivers/char/pc_keyb.c Fri Oct 9 13:19:46 1998 @@ -5,10 +5,16 @@ * See keyboard.c for the whole history. * * Major cleanup by Martin Mares, May 1997 + * + * Combined the keyboard and PS/2 mouse handling into one file, + * because they share the same hardware. + * Johan Myreen 1998-10-08. + * */ #include +#include #include #include #include @@ -18,10 +24,15 @@ #include #include #include +#include +#include +#include +#include #include #include #include +#include #include #include #include @@ -43,32 +54,69 @@ "\r\000/"; /* 0x60 - 0x6f */ #endif -unsigned char pckbd_read_mask = KBD_STAT_OBF; /* Modified by psaux.c */ +static void kbd_write(int address, int data); + +static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; /* used only by send_data - set by keyboard_interrupt */ static volatile unsigned char reply_expected = 0; static volatile unsigned char acknowledge = 0; static volatile unsigned char resend = 0; + +#if defined CONFIG_PSMOUSE +/* + * PS/2 Auxiliary Device + */ + +static int __init psaux_init(void); + +static struct aux_queue *queue; /* Mouse data buffer. */ +static int aux_count = 0; + +#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT) +#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT) + +#define MAX_RETRIES 60 /* some aux operations take long time*/ +#if defined(__alpha__) && !defined(CONFIG_PCI) +# define AUX_IRQ 9 /* Jensen is odd indeed */ +#else +# define AUX_IRQ 12 +#endif +#endif /* CONFIG_PSMOUSE */ + /* - * Wait for keyboard controller input buffer is empty. + * Wait for keyboard controller input buffer is empty. + * + * Don't use 'jiffies' so that we don't depend on + * interrupts.. * - * Don't use 'jiffies' so that we don't depend on - * interrupts.. + * Quote from PS/2 System Reference Manual: + * + * "Address hex 0060 and address hex 0064 should be written only when + * the input-buffer-full bit and output-buffer-full bit in the + * Controller Status register are set 0." */ static inline void kb_wait(void) { unsigned long timeout = KBC_TIMEOUT; + unsigned char status; do { + status = inb_p(KBD_STATUS_REG); + if (status & KBD_STAT_OBF) { + if (status & KBD_STAT_MOUSE_OBF) + inb_p(KBD_DATA_REG); /* Flush. */ + } + if (! (inb_p(KBD_STATUS_REG) & KBD_STAT_IBF)) return; mdelay(1); timeout--; } while (timeout); #ifdef KBD_REPORT_TIMEOUTS - printk(KERN_WARNING "Keyboard timed out\n"); + printk(KERN_WARNING "Keyboard timed out[1]\n"); #endif } @@ -211,11 +259,16 @@ #if DISABLE_KBD_DURING_INTERRUPTS static inline void send_cmd(unsigned char c) { + unsigned long flags; + + spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); outb(c, KBD_CNTL_REG); + spin_unlock_irqrestore(&kbd_controller_lock, flags); } -#define disable_keyboard() do { send_cmd(KBD_CCMD_KBD_DISABLE); kb_wait(); } while (0) +/* #define disable_keyboard() do { send_cmd(KBD_CCMD_KBD_DISABLE); kb_wait(); } while (0) */ +#define disable_keyboard() send_cmd(KBD_CCMD_KBD_DISABLE) #define enable_keyboard() send_cmd(KBD_CCMD_KBD_ENABLE) #else #define disable_keyboard() /* nothing */ @@ -368,27 +421,45 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + unsigned long flags; unsigned char status; - kbd_pt_regs = regs; disable_keyboard(); + spin_lock_irqsave(&kbd_controller_lock, flags); + kbd_pt_regs = regs; - status = inb_p(KBD_STATUS_REG); - do { + status = inb(KBD_STATUS_REG); + while (status & KBD_STAT_OBF) { unsigned char scancode; - /* mouse data? */ - if (status & pckbd_read_mask & KBD_STAT_MOUSE_OBF) - break; - scancode = inb(KBD_DATA_REG); - if ((status & KBD_STAT_OBF) && do_acknowledge(scancode)) - handle_scancode(scancode); + + if (status & KBD_STAT_MOUSE_OBF) { +#ifdef CONFIG_PSMOUSE + /* Mouse data. */ + if (aux_count) { + int head = queue->head; + queue->buf[head] = scancode; + add_mouse_randomness(scancode); + head = (head + 1) & (AUX_BUF_SIZE-1); + if (head != queue->tail) { + queue->head = head; + if (queue->fasync) + kill_fasync(queue->fasync, SIGIO); + wake_up_interruptible(&queue->proc_list); + } + } +#endif + } else { + if (do_acknowledge(scancode)) + handle_scancode(scancode); + mark_bh(KEYBOARD_BH); + } status = inb(KBD_STATUS_REG); - } while (status & KBD_STAT_OBF); + } - mark_bh(KEYBOARD_BH); + spin_unlock_irqrestore(&kbd_controller_lock, flags); enable_keyboard(); } @@ -406,11 +477,10 @@ do { unsigned long timeout = KBD_TIMEOUT; - kb_wait(); - acknowledge = 0; + acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */ resend = 0; reply_expected = 1; - outb_p(data, KBD_DATA_REG); + kbd_write(KBD_DATA_REG, data); for (;;) { if (acknowledge) return 1; @@ -419,7 +489,7 @@ mdelay(1); if (!--timeout) { #ifdef KBD_REPORT_TIMEOUTS - printk(KERN_WARNING "Keyboard timeout\n"); + printk(KERN_WARNING "Keyboard timeout[2]\n"); #endif return 0; } @@ -500,15 +570,29 @@ return -1; } -static void __init kbd_write(int address, int data) +static void kbd_write(int address, int data) { - int status; + unsigned long flags; - do { - status = inb(KBD_STATUS_REG); - } while (status & KBD_STAT_IBF); + spin_lock_irqsave(&kbd_controller_lock, flags); + kb_wait(); outb(data, address); + spin_unlock_irqrestore(&kbd_controller_lock, flags); +} + +#if defined CONFIG_PSMOUSE +static void kbd_write_cmd(int cmd) +{ + unsigned long flags; + + spin_lock_irqsave(&kbd_controller_lock, flags); + kb_wait(); + outb(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG); + kb_wait(); + outb(cmd, KBD_DATA_REG); + spin_unlock_irqrestore(&kbd_controller_lock, flags); } +#endif /* CONFIG_PSMOUSE */ static char * __init initialize_kbd(void) { @@ -623,6 +707,225 @@ printk(KERN_WARNING "initialize_kbd: %s\n", msg); } +#if defined CONFIG_PSMOUSE + psaux_init(); +#endif + /* Ok, finally allocate the IRQ, and off we go.. */ request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL); } + +#if defined CONFIG_PSMOUSE +/* + * Send a byte to the mouse. + */ +static void aux_write_dev(int val) +{ + unsigned long flags; + + spin_lock_irqsave(&kbd_controller_lock, flags); + kb_wait(); + outb(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG); + kb_wait(); + outb(val, KBD_DATA_REG); + spin_unlock_irqrestore(&kbd_controller_lock, flags); +} + +static unsigned int get_from_queue(void) +{ + unsigned int result; + unsigned long flags; + + save_flags(flags); + cli(); + result = queue->buf[queue->tail]; + queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1); + restore_flags(flags); + return result; +} + + +static inline int queue_empty(void) +{ + return queue->head == queue->tail; +} + +static int fasync_aux(int fd, struct file *filp, int on) +{ + int retval; + + retval = fasync_helper(fd, filp, on, &queue->fasync); + if (retval < 0) + return retval; + return 0; +} + + +static int release_aux(struct inode * inode, struct file * file) +{ + fasync_aux(-1, file, 0); + if (--aux_count) + return 0; + kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */ + kbd_write(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); +#ifdef CONFIG_MCA + free_irq(AUX_IRQ, inode); +#else + free_irq(AUX_IRQ, NULL); +#endif + return 0; +} + +/* + * Install interrupt handler. + * Enable auxiliary device. + */ + +static int open_aux(struct inode * inode, struct file * file) +{ + if (aux_count++) { + return 0; + } + queue->head = queue->tail = 0; /* Flush input queue */ +#ifdef CONFIG_MCA + if (request_irq(AUX_IRQ, keyboard_interrupt, MCA_bus ? SA_SHIRQ : 0, "PS/2 Mouse", inode)) { +#else + if (request_irq(AUX_IRQ, keyboard_interrupt, 0, "PS/2 Mouse", NULL)) { +#endif + aux_count--; + return -EBUSY; + } + kbd_write(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable the + auxiliary port on + controller. */ + aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */ + kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */ + + return 0; +} + +/* + * Put bytes from input queue to buffer. + */ + +static ssize_t read_aux(struct file * file, char * buffer, + size_t count, loff_t *ppos) +{ + struct wait_queue wait = { current, NULL }; + ssize_t i = count; + unsigned char c; + + if (queue_empty()) { + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + add_wait_queue(&queue->proc_list, &wait); +repeat: + current->state = TASK_INTERRUPTIBLE; + if (queue_empty() && !signal_pending(current)) { + schedule(); + goto repeat; + } + current->state = TASK_RUNNING; + remove_wait_queue(&queue->proc_list, &wait); + } + while (i > 0 && !queue_empty()) { + c = get_from_queue(); + put_user(c, buffer++); + i--; + } + if (count-i) { + file->f_dentry->d_inode->i_atime = CURRENT_TIME; + return count-i; + } + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +/* + * Write to the aux device. + */ + +static ssize_t write_aux(struct file * file, const char * buffer, + size_t count, loff_t *ppos) +{ + ssize_t retval = 0; + + if (count) { + ssize_t written = 0; + + if (count > 32) + count = 32; /* Limit to 32 bytes. */ + do { + char c; + get_user(c, buffer++); + aux_write_dev(c); + written++; + } while (--count); + retval = -EIO; + if (written) { + retval = written; + file->f_dentry->d_inode->i_mtime = CURRENT_TIME; + } + } + + return retval; +} + +static unsigned int aux_poll(struct file *file, poll_table * wait) +{ + poll_wait(file, &queue->proc_list, wait); + if (!queue_empty()) + return POLLIN | POLLRDNORM; + return 0; +} + +struct file_operations psaux_fops = { + NULL, /* seek */ + read_aux, + write_aux, + NULL, /* readdir */ + aux_poll, + NULL, /* ioctl */ + NULL, /* mmap */ + open_aux, + NULL, /* flush */ + release_aux, + NULL, + fasync_aux, +}; + +/* + * Initialize driver. + */ +static struct miscdevice psaux_mouse = { + PSMOUSE_MINOR, "psaux", &psaux_fops +}; + +static int __init psaux_init(void) +{ + if (aux_device_present != 0xaa) + return -EIO; + + printk(KERN_INFO "PS/2 auxiliary pointing device detected -- driver installed.\n"); + misc_register(&psaux_mouse); + queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL); + memset(queue, 0, sizeof(*queue)); + queue->head = queue->tail = 0; + queue->proc_list = NULL; + +#ifdef INITIALIZE_MOUSE + kbd_write(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable Aux. */ + aux_write_dev(AUX_SET_SAMPLE); + aux_write_dev(100); /* 100 samples/sec */ + aux_write_dev(AUX_SET_RES); + aux_write_dev(3); /* 8 counts per mm */ + aux_write_dev(AUX_SET_SCALE21); /* 2:1 scaling */ +#endif /* INITIALIZE_MOUSE */ + kbd_write(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); /* Disable aux device. */ + kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */ + + return 0; +} + +#endif /* CONFIG_PSMOUSE */ diff -u --recursive --new-file v2.1.125/linux/drivers/char/pc_keyb.h linux/drivers/char/pc_keyb.h --- v2.1.125/linux/drivers/char/pc_keyb.h Sat Sep 5 16:46:40 1998 +++ linux/drivers/char/pc_keyb.h Fri Oct 9 11:44:19 1998 @@ -14,6 +14,9 @@ #define KBD_REPORT_UNKN /* Report unknown scan codes */ #define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */ #undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */ +#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */ + + #define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */ #define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ @@ -109,3 +112,13 @@ #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ #define AUX_RESET 0xFF /* Reset aux device */ + +#define AUX_BUF_SIZE 2048 + +struct aux_queue { + unsigned long head; + unsigned long tail; + struct wait_queue *proc_list; + struct fasync_struct *fasync; + unsigned char buf[AUX_BUF_SIZE]; +}; diff -u --recursive --new-file v2.1.125/linux/drivers/char/psaux.c linux/drivers/char/psaux.c --- v2.1.125/linux/drivers/char/psaux.c Mon Sep 28 10:51:33 1998 +++ linux/drivers/char/psaux.c Wed Dec 31 16:00:00 1969 @@ -1,452 +0,0 @@ -/* - * linux/drivers/char/psaux.c - * - * Driver for PS/2 type mouse by Johan Myreen. - * - * Supports pointing devices attached to a PS/2 type - * Keyboard and Auxiliary Device Controller. - * - * Corrections in device setup for some laptop mice & trackballs. - * 02Feb93 (troyer@saifr00.cfsat.Honeywell.COM,mch@wimsey.bc.ca) - * - * Changed to prevent keyboard lockups on AST Power Exec. - * 28Jul93 Brad Bosch - brad@lachman.com - * - * Added support for SIGIO. 28Jul95 jem@pandora.pp.fi - * - * Rearranged SIGIO support to use code from tty_io. 9Sept95 ctm@ardi.com - * - * Modularised 8-Sep-95 Philip Blundell - * - * Fixed keyboard lockups at open time - * 3-Jul-96, 22-Aug-96 Roman Hodek - * - * Cleanup by Martin Mares, 01-Jun-97 (now uses the new PC kbd include) - * - * Renamed misc. name to "psaux",more in keeping with Documentation/devices.txt - * 13-Jan-1998, Richard Gooch - */ - -/* - * This really should be part of the pc_kbd driver - they share the same - * controller, and right now we have ridiculous synchronization problems. - * Some of the SMP bootup problems may be due to not getting synchronization - * right. - * - * I moved the C&T mouse driver to a file of its own, hopefully that will - * make it easier to eventually fix this all. - * - * Linus - */ - -/* Uncomment the following line if your mouse needs initialization. */ - -/* #define INITIALIZE_DEVICE */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "pc_keyb.h" - -/* - * Generic declarations for both PS2 and 82C710 - */ - -#define PSMOUSE_MINOR 1 /* Minor device # for this mouse */ -#define AUX_BUF_SIZE 2048 - -struct aux_queue { - unsigned long head; - unsigned long tail; - struct wait_queue *proc_list; - struct fasync_struct *fasync; - unsigned char buf[AUX_BUF_SIZE]; -}; - -static struct aux_queue *queue; -static int aux_count = 0; - -static unsigned int get_from_queue(void) -{ - unsigned int result; - unsigned long flags; - - save_flags(flags); - cli(); - result = queue->buf[queue->tail]; - queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1); - restore_flags(flags); - return result; -} - - -static inline int queue_empty(void) -{ - return queue->head == queue->tail; -} - -static int fasync_aux(int fd, struct file *filp, int on) -{ - int retval; - - retval = fasync_helper(fd, filp, on, &queue->fasync); - if (retval < 0) - return retval; - return 0; -} - -/* - * PS/2 Aux Device - */ - -#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT) -#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT) - -#define MAX_RETRIES 60 /* some aux operations take long time*/ -#if defined(__alpha__) && !defined(CONFIG_PCI) -# define AUX_IRQ 9 /* Jensen is odd indeed */ -#else -# define AUX_IRQ 12 -#endif - -/* - * Status polling - */ - -static int poll_aux_status(void) -{ - int retries=0; - - while ((inb(KBD_STATUS_REG) & (KBD_STAT_IBF | KBD_STAT_OBF)) && retries < MAX_RETRIES) { - if ((inb_p(KBD_STATUS_REG) & AUX_STAT_OBF) == AUX_STAT_OBF) - inb_p(KBD_DATA_REG); - current->state = TASK_INTERRUPTIBLE; - current->timeout = jiffies + (5*HZ + 99) / 100; - schedule(); - retries++; - } - return (retries < MAX_RETRIES); -} - -/* - * Write to aux device - */ - -static void aux_write_dev(int val) -{ - poll_aux_status(); - outb_p(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG); /* Write magic cookie */ - poll_aux_status(); - outb_p(val, KBD_DATA_REG); /* Write data */ -} - -/* - * Write to device & handle returned ack - */ - -#ifdef INITIALIZE_DEVICE -__initfunc(static int aux_write_ack(int val)) -{ - aux_write_dev(val); - poll_aux_status(); - - if ((inb(KBD_STATUS_REG) & AUX_STAT_OBF) == AUX_STAT_OBF) - { - return (inb(KBD_DATA_REG)); - } - return 0; -} -#endif /* INITIALIZE_DEVICE */ - -/* - * Write aux device command - */ - -static void aux_write_cmd(int val) -{ - poll_aux_status(); - outb_p(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG); - poll_aux_status(); - outb_p(val, KBD_DATA_REG); -} - -/* - * AUX handler critical section start and end. - * - * Only one process can be in the critical section and all keyboard sends are - * deferred as long as we're inside. This is necessary as we may sleep when - * waiting for the keyboard controller and other processes / BH's can - * preempt us. Please note that the input buffer must be flushed when - * aux_end_atomic() is called and the interrupt is no longer enabled as not - * doing so might cause the keyboard driver to ignore all incoming keystrokes. - */ - -static struct semaphore aux_sema4 = MUTEX; - -static inline void aux_start_atomic(void) -{ - down(&aux_sema4); - disable_bh(KEYBOARD_BH); -} - -static inline void aux_end_atomic(void) -{ - enable_bh(KEYBOARD_BH); - up(&aux_sema4); -} - -/* - * Interrupt from the auxiliary device: a character - * is waiting in the keyboard/aux controller. - */ - -static void aux_interrupt(int cpl, void *dev_id, struct pt_regs * regs) -{ - int head = queue->head; - int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1); - - if ((inb(KBD_STATUS_REG) & AUX_STAT_OBF) != AUX_STAT_OBF) - return; - - add_mouse_randomness(queue->buf[head] = inb(KBD_DATA_REG)); - if (head != maxhead) { - head++; - head &= AUX_BUF_SIZE-1; - } - queue->head = head; - if (queue->fasync) - kill_fasync(queue->fasync, SIGIO); - wake_up_interruptible(&queue->proc_list); -} - -static int release_aux(struct inode * inode, struct file * file) -{ - fasync_aux(-1, file, 0); - if (--aux_count) - return 0; -#ifdef CONFIG_VT - pckbd_read_mask = KBD_STAT_OBF; -#endif - aux_start_atomic(); - aux_write_cmd(AUX_INTS_OFF); /* Disable controller ints */ - poll_aux_status(); - outb_p(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); /* Disable Aux device */ - poll_aux_status(); - aux_end_atomic(); -#ifdef CONFIG_MCA - free_irq(AUX_IRQ, inode); -#else - free_irq(AUX_IRQ, NULL); -#endif - MOD_DEC_USE_COUNT; - return 0; -} - -/* - * Install interrupt handler. - * Enable auxiliary device. - */ - -static int open_aux(struct inode * inode, struct file * file) -{ - aux_start_atomic(); - if (aux_count++) { - aux_end_atomic(); - return 0; - } - if (!poll_aux_status()) { /* FIXME: Race condition */ - aux_count--; - aux_end_atomic(); - return -EBUSY; - } - queue->head = queue->tail = 0; /* Flush input queue */ -#ifdef CONFIG_MCA - if (request_irq(AUX_IRQ, aux_interrupt, MCA_bus ? SA_SHIRQ : 0, "PS/2 Mouse", inode)) { -#else - if (request_irq(AUX_IRQ, aux_interrupt, 0, "PS/2 Mouse", NULL)) { -#endif - aux_count--; - aux_end_atomic(); - return -EBUSY; - } - MOD_INC_USE_COUNT; - poll_aux_status(); - outb_p(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable Aux */ - aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */ - aux_write_cmd(AUX_INTS_ON); /* Enable controller ints */ - poll_aux_status(); - aux_end_atomic(); - -#ifdef CONFIG_VT - pckbd_read_mask = AUX_STAT_OBF; -#endif - - return 0; -} - -/* - * Write to the aux device. - */ - -static ssize_t write_aux(struct file * file, const char * buffer, - size_t count, loff_t *ppos) -{ - ssize_t retval = 0; - - if (count) { - ssize_t written = 0; - - aux_start_atomic(); - do { - char c; - if (!poll_aux_status()) - break; - outb_p(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG); - if (!poll_aux_status()) - break; - get_user(c, buffer++); - outb_p(c, KBD_DATA_REG); - written++; - } while (--count); - aux_end_atomic(); - retval = -EIO; - if (written) { - retval = written; - file->f_dentry->d_inode->i_mtime = CURRENT_TIME; - } - } - - return retval; -} - -/* - * Put bytes from input queue to buffer. - */ - -static ssize_t read_aux(struct file * file, char * buffer, - size_t count, loff_t *ppos) -{ - struct wait_queue wait = { current, NULL }; - ssize_t i = count; - unsigned char c; - - if (queue_empty()) { - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - add_wait_queue(&queue->proc_list, &wait); -repeat: - current->state = TASK_INTERRUPTIBLE; - if (queue_empty() && !signal_pending(current)) { - schedule(); - goto repeat; - } - current->state = TASK_RUNNING; - remove_wait_queue(&queue->proc_list, &wait); - } - while (i > 0 && !queue_empty()) { - c = get_from_queue(); - put_user(c, buffer++); - i--; - } - if (count-i) { - file->f_dentry->d_inode->i_atime = CURRENT_TIME; - return count-i; - } - if (signal_pending(current)) - return -ERESTARTSYS; - return 0; -} - -static unsigned int aux_poll(struct file *file, poll_table * wait) -{ - poll_wait(file, &queue->proc_list, wait); - if (!queue_empty()) - return POLLIN | POLLRDNORM; - return 0; -} - -struct file_operations psaux_fops = { - NULL, /* seek */ - read_aux, - write_aux, - NULL, /* readdir */ - aux_poll, - NULL, /* ioctl */ - NULL, /* mmap */ - open_aux, - NULL, /* flush */ - release_aux, - NULL, - fasync_aux, -}; - -/* - * Initialize driver. - */ -static struct miscdevice psaux_mouse = { - PSMOUSE_MINOR, "psaux", &psaux_fops -}; - -__initfunc(int psaux_init(void)) -{ - if (aux_device_present != 0xaa) - return -EIO; - - printk(KERN_INFO "PS/2 auxiliary pointing device detected -- driver installed.\n"); - misc_register(&psaux_mouse); - queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL); - memset(queue, 0, sizeof(*queue)); - queue->head = queue->tail = 0; - queue->proc_list = NULL; - - aux_start_atomic(); -#ifdef INITIALIZE_DEVICE - outb_p(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable Aux */ - aux_write_ack(AUX_SET_SAMPLE); - aux_write_ack(100); /* 100 samples/sec */ - aux_write_ack(AUX_SET_RES); - aux_write_ack(3); /* 8 counts per mm */ - aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */ - poll_aux_status(); -#endif /* INITIALIZE_DEVICE */ - outb_p(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); /* Disable Aux device */ - poll_aux_status(); - outb_p(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG); /* Disable controller interrupts */ - poll_aux_status(); - outb_p(AUX_INTS_OFF, KBD_DATA_REG); - poll_aux_status(); - aux_end_atomic(); - - return 0; -} - -#ifdef MODULE -int init_module(void) -{ - return psaux_init(); -} - -void cleanup_module(void) -{ - misc_deregister(&psaux_mouse); - kfree(queue); -} -#endif diff -u --recursive --new-file v2.1.125/linux/drivers/char/qpmouse.c linux/drivers/char/qpmouse.c --- v2.1.125/linux/drivers/char/qpmouse.c Mon Sep 28 10:51:33 1998 +++ linux/drivers/char/qpmouse.c Fri Oct 9 11:44:19 1998 @@ -8,15 +8,15 @@ * Corrections in device setup for some laptop mice & trackballs. * 02Feb93 (troyer@saifr00.cfsat.Honeywell.COM,mch@wimsey.bc.ca) * - * Modified by Johan Myreen (jem@pandora.pp.fi) 04Aug93 + * Modified by Johan Myreen (jem@iki.fi) 04Aug93 * to include support for QuickPort mouse. * * Changed references to "QuickPort" with "82C710" since "QuickPort" * is not what this driver is all about -- QuickPort is just a * connector type, and this driver is for the mouse port on the Chips - * & Technologies 82C710 interface chip. 15Nov93 jem@pandora.pp.fi + * & Technologies 82C710 interface chip. 15Nov93 jem@iki.fi * - * Added support for SIGIO. 28Jul95 jem@pandora.pp.fi + * Added support for SIGIO. 28Jul95 jem@iki.fi * * Rearranged SIGIO support to use code from tty_io. 9Sept95 ctm@ardi.com * diff -u --recursive --new-file v2.1.125/linux/drivers/char/stallion.c linux/drivers/char/stallion.c --- v2.1.125/linux/drivers/char/stallion.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/stallion.c Fri Oct 23 08:26:04 1998 @@ -144,7 +144,7 @@ */ static char *stl_drvtitle = "Stallion Multiport Serial Driver"; static char *stl_drvname = "stallion"; -static char *stl_drvversion = "5.4.6"; +static char *stl_drvversion = "5.4.7"; static char *stl_serialname = "ttyE"; static char *stl_calloutname = "cue"; @@ -664,17 +664,21 @@ * to get at port stats - only not using the port device itself. */ static struct file_operations stl_fsiomem = { - NULL, - NULL, - NULL, - NULL, - NULL, - stl_memioctl, - NULL, - stl_memopen, + NULL, /* llseek */ + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + stl_memioctl, /* ioctl */ + NULL, /* mmap */ + stl_memopen, /* open */ NULL, /* flush */ - stl_memclose, - NULL + stl_memclose, /* release */ + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL /* lock */ }; /*****************************************************************************/ diff -u --recursive --new-file v2.1.125/linux/drivers/char/sysrq.c linux/drivers/char/sysrq.c --- v2.1.125/linux/drivers/char/sysrq.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/sysrq.c Wed Oct 14 11:43:13 1998 @@ -168,7 +168,14 @@ case IDE1_MAJOR: case IDE2_MAJOR: case IDE3_MAJOR: - case SCSI_DISK_MAJOR: + case SCSI_DISK0_MAJOR: + case SCSI_DISK1_MAJOR: + case SCSI_DISK2_MAJOR: + case SCSI_DISK3_MAJOR: + case SCSI_DISK4_MAJOR: + case SCSI_DISK5_MAJOR: + case SCSI_DISK6_MAJOR: + case SCSI_DISK7_MAJOR: return 1; default: return 0; diff -u --recursive --new-file v2.1.125/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v2.1.125/linux/drivers/char/tpqic02.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/tpqic02.c Fri Oct 9 11:56:59 1998 @@ -1360,6 +1360,7 @@ */ static inline void dma_transfer(void) { + unsigned long flags; if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */ outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT); /* back to normal */ @@ -1369,6 +1370,7 @@ outb_p(ctlbits, QIC02_CTL_PORT); + flags=claim_dma_lock(); clear_dma_ff(QIC02_TAPE_DMA); set_dma_mode(QIC02_TAPE_DMA, dma_mode); set_dma_addr(QIC02_TAPE_DMA, buffaddr+dma_bytes_done); /* full address */ @@ -1393,6 +1395,9 @@ /* start computer DMA controller */ enable_dma(QIC02_TAPE_DMA); + + release_dma_lock(flags); + /* block transfer should start now, jumping to the * interrupt routine when done or an exception was detected. */ @@ -1410,6 +1415,7 @@ /* assume 'bytes_todo'>0 */ { int stat; + unsigned long flags; tpqputs(TPQD_DEBUG, "start_dma() enter"); TPQDEB({printk(TPQIC02_NAME ": doing_read==%d, doing_write==%d\n", doing_read, doing_write);}) @@ -1506,9 +1512,10 @@ /* initiate first data block read from/write to the tape controller */ + save_flags(flags); cli(); dma_transfer(); - sti(); + restore_flags(flags); TPQPUTS("start_dma() end"); return TE_OK; @@ -1524,13 +1531,18 @@ static void end_dma(unsigned long * bytes_done) { int stat = TE_OK; + unsigned long flags; TIMEROFF; TPQPUTS("end_dma() enter"); + flags=claim_dma_lock(); + disable_dma(QIC02_TAPE_DMA); clear_dma_ff(QIC02_TAPE_DMA); + + release_dma_lock(flags); if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */ outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT); /* back to normal */ @@ -1633,6 +1645,7 @@ static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int stat, r, i; + unsigned long flags; TIMEROFF; @@ -1682,10 +1695,14 @@ r = 1; } + flags=claim_dma_lock(); + if ( (i = get_dma_residue(QIC02_TAPE_DMA)) != 0 ) { printk(TPQIC02_NAME ": dma_residue == %x !!!\n", i); r = 1; /* big trouble, but can't do much about it... */ } + + release_dma_lock(flags); if (r) return; diff -u --recursive --new-file v2.1.125/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.1.125/linux/drivers/char/tty_io.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/tty_io.c Tue Oct 13 11:42:18 1998 @@ -1132,7 +1132,6 @@ * both sides, and we've completed the last operation that could * block, so it's safe to proceed with closing. */ - if (pty_master) { if (--o_tty->count < 0) { printk("release_dev: bad pty slave count (%d) for %s\n", @@ -1147,6 +1146,16 @@ } /* + * We've decremented tty->count, so we should zero out + * filp->private_data, to break the link between the tty and + * the file descriptor. Otherwise if close_fp() blocks before + * the the file descriptor is removed from the inuse_filp + * list, check_tty_count() could observe a discrepancy and + * printk a warning message to the user. + */ + filp->private_data = 0; + + /* * Perform some housekeeping before deciding whether to return. * * Set the TTY_CLOSING flag if this was the last open. In the @@ -1180,7 +1189,6 @@ /* check whether both sides are closing ... */ if (!tty_closing || (o_tty && !o_tty_closing)) return; - filp->private_data = 0; #ifdef TTY_DEBUG_HANGUP printk("freeing tty structure..."); @@ -1293,7 +1301,6 @@ return retval; #ifdef CONFIG_UNIX98_PTYS - /* N.B. this error exit may leave filp->f_flags with O_NONBLOCK set */ init_dev_done: #endif filp->private_data = tty; @@ -2084,6 +2091,7 @@ if (tty_register_driver(&dev_syscons_driver)) panic("Couldn't register /dev/console driver\n"); +#ifdef CONFIG_UNIX98_PTYS dev_ptmx_driver = dev_tty_driver; dev_ptmx_driver.driver_name = "/dev/ptmx"; dev_ptmx_driver.name = dev_ptmx_driver.driver_name + 5; @@ -2094,7 +2102,8 @@ if (tty_register_driver(&dev_ptmx_driver)) panic("Couldn't register /dev/ptmx driver\n"); - +#endif + #ifdef CONFIG_VT dev_console_driver = dev_tty_driver; dev_console_driver.driver_name = "/dev/tty0"; diff -u --recursive --new-file v2.1.125/linux/drivers/char/videodev.c linux/drivers/char/videodev.c --- v2.1.125/linux/drivers/char/videodev.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/char/videodev.c Sat Oct 17 15:52:18 1998 @@ -53,6 +53,9 @@ #ifdef CONFIG_VIDEO_BWQCAM extern int init_bw_qcams(struct video_init *); #endif +#ifdef CONFIG_VIDEO_PLANB +extern int init_planbs(struct video_init *); +#endif #ifdef CONFIG_RADIO_AZTECH extern int aztech_init(struct video_init *); #endif @@ -83,6 +86,9 @@ #ifdef CONFIG_VIDEO_PMS {"PMS", init_pms_cards}, #endif +#ifdef CONFIG_VIDEO_PLANB + {"planb", init_planbs}, +#endif #ifdef CONFIG_RADIO_AZTECH {"Aztech", aztech_init}, #endif diff -u --recursive --new-file v2.1.125/linux/drivers/char/wdt.c linux/drivers/char/wdt.c --- v2.1.125/linux/drivers/char/wdt.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/wdt.c Sat Oct 17 15:52:18 1998 @@ -23,6 +23,7 @@ * Alan Cox : Fixed the reboot problem (as noted by * Matt Crocker). * Alan Cox : Added wdt= boot option + * Alan Cox : Cleaned up copy/user stuff */ #include @@ -191,7 +192,6 @@ { unsigned short c=inb_p(WDT_RT); unsigned char cp; - int err; /* Can't seek (pread) on this device */ if (ptr != &file->f_pos) @@ -200,13 +200,11 @@ switch(MINOR(file->f_dentry->d_inode->i_rdev)) { case TEMP_MINOR: - err=verify_area(VERIFY_WRITE, buf, 1); - if(err) - return err; c*=11; c/=15; cp=c+7; - copy_to_user(buf,&cp,1); + if(copy_to_user(buf,&cp,1)) + return -EFAULT; return 1; default: return -EINVAL; @@ -216,7 +214,6 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int i; static struct watchdog_info ident= { WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER @@ -231,20 +228,10 @@ default: return -ENOIOCTLCMD; case WDIOC_GETSUPPORT: - i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info)); - if (i) - return i; - else - return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)); + return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; case WDIOC_GETSTATUS: - i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(int)); - if (i) - return i; - else - { - return put_user(wdt_status(),(int *)arg); - } + return put_user(wdt_status(),(int *)arg); case WDIOC_GETBOOTSTATUS: return put_user(0, (int *)arg); case WDIOC_KEEPALIVE: diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_arc.c linux/drivers/misc/parport_arc.c --- v2.1.125/linux/drivers/misc/parport_arc.c Tue Jul 21 00:15:31 1998 +++ linux/drivers/misc/parport_arc.c Fri Oct 9 12:20:27 1998 @@ -33,6 +33,11 @@ /* ARC can't read from the data latch, so we must use a soft copy. */ static unsigned char data_copy; +static void arc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + parport_generic_irq(irq, (struct parport *) dev_id, regs); +} + static void arc_write_data(struct parport *p, unsigned char data) { data_copy = data; @@ -110,7 +115,7 @@ arc_enable_irq, arc_disable_irq, - arc_examine_irq, + arc_interrupt, arc_inc_use_count, arc_dec_use_count, diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_ax.c linux/drivers/misc/parport_ax.c --- v2.1.125/linux/drivers/misc/parport_ax.c Thu Aug 6 14:06:32 1998 +++ linux/drivers/misc/parport_ax.c Fri Oct 9 12:20:27 1998 @@ -50,10 +50,9 @@ #define CONFIGB 0x401 #define ECONTROL 0x402 -static void -parport_ax_null_intr_func(int irq, void *dev_id, struct pt_regs *regs) +static void parport_ax_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - /* NULL function - Does nothing */ + parport_generic_irq(irq, (struct parport *) dev_id, regs); } void @@ -206,7 +205,7 @@ { if (p->irq != PARPORT_IRQ_NONE) { parport_ax_disable_irq(p); - free_irq(p->irq, NULL); + free_irq(p->irq, p); } release_region(p->base, p->size); if (p->modes & PARPORT_MODE_PCECR) @@ -219,11 +218,15 @@ parport_ax_claim_resources(struct parport *p) { /* FIXME check that resources are free */ - if (p->irq != PARPORT_IRQ_NONE) { - request_irq(p->irq, parport_ax_null_intr_func, - 0, p->name, NULL); - parport_ax_enable_irq(p); - } + int err; + + if (p->irq != PARPORT_IRQ_NONE) + if ((err = request_irq(p->irq, parport_ax_interrupt, + 0, p->name, p)) != 0) + return err; + else + parport_ax_enable_irq(p); + request_region(p->base, p->size, p->name); if (p->modes & PARPORT_MODE_PCECR) request_region(p->base+0x400, 3, p->name); @@ -281,12 +284,6 @@ return 0; /* FIXME */ } -int -parport_ax_examine_irq(struct parport *p) -{ - return 0; /* FIXME */ -} - void parport_ax_inc_use_count(void) { @@ -355,7 +352,7 @@ parport_ax_enable_irq, parport_ax_disable_irq, - parport_ax_examine_irq, + parport_ax_interrupt, parport_ax_inc_use_count, parport_ax_dec_use_count, diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c --- v2.1.125/linux/drivers/misc/parport_pc.c Wed Sep 9 14:51:07 1998 +++ linux/drivers/misc/parport_pc.c Fri Oct 9 12:20:27 1998 @@ -1,4 +1,4 @@ -/* Low-level parallel-port routines for PC-style hardware. +/* Low-level parallel-port routines for 8255-based PC-style hardware. * * Authors: Phil Blundell * Tim Waugh @@ -32,13 +32,8 @@ * accomodate this. */ -#include -#include - -#include -#include - #include +#include #include #include #include @@ -46,6 +41,8 @@ #include #include +#include + #include #include @@ -53,9 +50,9 @@ than PARPORT_MAX (in ). */ #define PARPORT_PC_MAX_PORTS 8 -static void parport_pc_null_intr_func(int irq, void *dev_id, struct pt_regs *regs) +static void parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - /* Null function - does nothing */ + parport_generic_irq(irq, (struct parport *) dev_id, regs); } void parport_pc_write_epp(struct parport *p, unsigned char d) @@ -173,7 +170,7 @@ void parport_pc_release_resources(struct parport *p) { if (p->irq != PARPORT_IRQ_NONE) - free_irq(p->irq, NULL); + free_irq(p->irq, p); release_region(p->base, p->size); if (p->modes & PARPORT_MODE_PCECR) release_region(p->base+0x400, 3); @@ -183,7 +180,9 @@ { int err; if (p->irq != PARPORT_IRQ_NONE) - if ((err = request_irq(p->irq, parport_pc_null_intr_func, 0, p->name, NULL)) != 0) return err; + if ((err = request_irq(p->irq, parport_pc_interrupt, + 0, p->name, p)) != 0) + return err; request_region(p->base, p->size, p->name); if (p->modes & PARPORT_MODE_PCECR) request_region(p->base+0x400, 3, p->name); @@ -242,11 +241,6 @@ return -ENOSYS; /* FIXME */ } -int parport_pc_examine_irq(struct parport *p) -{ - return 0; /* FIXME */ -} - void parport_pc_inc_use_count(void) { #ifdef MODULE @@ -313,7 +307,7 @@ parport_pc_enable_irq, parport_pc_disable_irq, - parport_pc_examine_irq, + parport_pc_interrupt, parport_pc_inc_use_count, parport_pc_dec_use_count, diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_procfs.c linux/drivers/misc/parport_procfs.c --- v2.1.125/linux/drivers/misc/parport_procfs.c Wed Sep 9 14:51:07 1998 +++ linux/drivers/misc/parport_procfs.c Fri Oct 9 12:20:27 1998 @@ -29,16 +29,13 @@ struct proc_dir_entry *base = NULL; -extern void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs); - static int irq_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) + unsigned long count, void *data) { int retval = -EINVAL; int newirq = PARPORT_IRQ_NONE; struct parport *pp = (struct parport *)data; int oldirq = pp->irq; - unsigned long flags; /* * We can have these valid cases: @@ -70,30 +67,44 @@ if (oldirq == newirq) goto out; - spin_lock_irqsave(&pp->lock, flags); if (pp->flags & PARPORT_FLAG_COMA) goto out_ok; retval = -EBUSY; + + /* + * Here we don' t need the irq version of spinlocks because + * the parport_lowlevel irq handler must not change the cad, + * and so has no one reason to write_lock() the cad_lock spinlock. + * -arca + */ + read_lock(&pp->cad_lock); + if (pp->cad) - goto out_unlock; + { + read_unlock(&pp->cad_lock); + return retval; + } if (newirq != PARPORT_IRQ_NONE) { - retval = request_irq(newirq, parport_null_intr_func, - SA_INTERRUPT, pp->name, NULL); + retval = request_irq(newirq, pp->ops->interrupt, + 0, pp->name, pp); if (retval) - goto out_unlock; - else retval = count; + { + read_unlock(&pp->cad_lock); + return retval; + } } if (oldirq != PARPORT_IRQ_NONE) - free_irq(oldirq, NULL); + free_irq(oldirq, pp); + + retval = count; + + read_unlock(&pp->cad_lock); out_ok: pp->irq = newirq; - -out_unlock: - spin_unlock_irqrestore (&pp->lock, flags); out: return retval; diff -u --recursive --new-file v2.1.125/linux/drivers/misc/parport_share.c linux/drivers/misc/parport_share.c --- v2.1.125/linux/drivers/misc/parport_share.c Wed Sep 9 14:51:07 1998 +++ linux/drivers/misc/parport_share.c Fri Oct 9 12:20:27 1998 @@ -27,6 +27,7 @@ #include #include +#include #ifdef CONFIG_KMOD #include @@ -55,19 +56,12 @@ return portlist; } -void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs) -{ - /* Null function - does nothing. IRQs are pointed here whenever - there is no real handler for them. */ -} - struct parport *parport_register_port(unsigned long base, int irq, int dma, struct parport_operations *ops) { struct parport *tmp; int portnum; char *name; - unsigned long flags; /* Check for a previously registered port. NOTE: we will ignore irq and dma if we find a previously @@ -111,7 +105,9 @@ tmp->ops = ops; tmp->number = portnum; memset (&tmp->probe_info, 0, sizeof (struct parport_device_info)); - spin_lock_init (&tmp->lock); + spin_lock_init(&tmp->cad_lock); + spin_lock_init(&tmp->waitlist_lock); + spin_lock_init(&tmp->pardevice_lock); name = kmalloc(15, GFP_KERNEL); if (!name) { @@ -122,14 +118,19 @@ sprintf(name, "parport%d", portnum); tmp->name = name; - /* Chain the entry to our list. */ - spin_lock_irqsave (&parportlist_lock, flags); + /* + * Chain the entry to our list. + * + * This function must not run from an irq handler so we don' t need + * to clear irq on the local CPU. -arca + */ + spin_lock(&parportlist_lock); if (portlist_tail) portlist_tail->next = tmp; portlist_tail = tmp; if (!portlist) portlist = tmp; - spin_unlock_irqrestore (&parportlist_lock, flags); + spin_unlock(&parportlist_lock); tmp->probe_info.class = PARPORT_CLASS_LEGACY; /* assume the worst */ tmp->waithead = tmp->waittail = NULL; @@ -140,8 +141,8 @@ void parport_unregister_port(struct parport *port) { struct parport *p; - unsigned long flags; - spin_lock_irqsave (&parportlist_lock, flags); + + spin_lock(&parportlist_lock); if (portlist == port) { if ((portlist = port->next) == NULL) portlist_tail = NULL; @@ -155,7 +156,7 @@ else printk (KERN_WARNING "%s not found in port list!\n", port->name); } - spin_unlock_irqrestore (&parportlist_lock, flags); + spin_unlock(&parportlist_lock); if (port->probe_info.class_name) kfree (port->probe_info.class_name); if (port->probe_info.mfr) @@ -195,7 +196,13 @@ int flags, void *handle) { struct pardevice *tmp; - unsigned long flgs; + + if (port->flags & PARPORT_FLAG_EXCL) { + /* An exclusive device is registered. */ + printk (KERN_DEBUG "%s: no more devices allowed\n", + port->name); + return NULL; + } if (flags & PARPORT_DEV_LURK) { if (!pf || !kf) { @@ -242,12 +249,30 @@ /* Chain this onto the list */ tmp->prev = NULL; - spin_lock_irqsave (&port->lock, flgs); + /* + * This function must not run from an irq handler so we don' t need + * to clear irq on the local CPU. -arca + */ + spin_lock(&port->pardevice_lock); + + if (flags & PARPORT_DEV_EXCL) { + if (port->devices) { + spin_unlock (&port->pardevice_lock); + kfree (tmp->state); + kfree (tmp); + printk (KERN_DEBUG + "%s: cannot grant exclusive access for " + "device %s\n", port->name, name); + return NULL; + } + port->flags |= PARPORT_FLAG_EXCL; + } + tmp->next = port->devices; if (port->devices) port->devices->prev = tmp; port->devices = tmp; - spin_unlock_irqrestore (&port->lock, flgs); + spin_unlock(&port->pardevice_lock); inc_parport_count(); port->ops->inc_use_count(); @@ -262,7 +287,6 @@ void parport_unregister_device(struct pardevice *dev) { struct parport *port; - unsigned long flags; #ifdef PARPORT_PARANOID if (dev == NULL) { @@ -279,14 +303,18 @@ return; } - spin_lock_irqsave (&port->lock, flags); + spin_lock(&port->pardevice_lock); if (dev->next) dev->next->prev = dev->prev; if (dev->prev) dev->prev->next = dev->next; else port->devices = dev->next; - spin_unlock_irqrestore (&port->lock, flags); + + if (dev->flags & PARPORT_DEV_EXCL) + port->flags &= ~PARPORT_FLAG_EXCL; + + spin_unlock(&port->pardevice_lock); kfree(dev->state); kfree(dev); @@ -337,7 +365,7 @@ dev->waiting = 0; /* Take ourselves out of the wait list again. */ - spin_lock_irqsave (&port->lock, flags); + spin_lock_irqsave (&port->waitlist_lock, flags); if (dev->waitprev) dev->waitprev->waitnext = dev->waitnext; else @@ -346,28 +374,27 @@ dev->waitnext->waitprev = dev->waitprev; else port->waittail = dev->waitprev; - spin_unlock_irqrestore (&port->lock, flags); + spin_unlock_irqrestore (&port->waitlist_lock, flags); dev->waitprev = dev->waitnext = NULL; } + if (oldcad && port->irq != PARPORT_IRQ_NONE && !oldcad->irq_func) + /* + * If there was an irq pending it should hopefully happen + * before return from enable_irq(). -arca + */ + enable_irq(port->irq); + + /* + * Avoid running irq handlers if the pardevice doesn' t use it. -arca + */ + if (port->irq != PARPORT_IRQ_NONE && !dev->irq_func) + disable_irq(port->irq); + /* Now we do the change of devices */ - spin_lock_irqsave(&port->lock, flags); + write_lock_irqsave(&port->cad_lock, flags); port->cad = dev; - spin_unlock_irqrestore(&port->lock, flags); - - /* Swap the IRQ handlers. */ - if (port->irq != PARPORT_IRQ_NONE) { - if (oldcad && oldcad->irq_func) { - free_irq(port->irq, oldcad->private); - request_irq(port->irq, parport_null_intr_func, - SA_INTERRUPT, port->name, NULL); - } - if (dev->irq_func) { - free_irq(port->irq, NULL); - request_irq(port->irq, dev->irq_func, - SA_INTERRUPT, dev->name, dev->private); - } - } + write_unlock_irqrestore(&port->cad_lock, flags); /* Restore control registers */ port->ops->restore_state(port, dev->state); @@ -379,10 +406,10 @@ interest. This is only allowed for devices sleeping in parport_claim_or_block(), or those with a wakeup function. */ if (dev->waiting & 2 || dev->wakeup) { - spin_lock_irqsave (&port->lock, flags); + spin_lock_irqsave (&port->waitlist_lock, flags); if (port->cad == NULL) { /* The port got released in the meantime. */ - spin_unlock_irqrestore (&port->lock, flags); + spin_unlock_irqrestore (&port->waitlist_lock, flags); goto try_again; } if (test_and_set_bit(0, &dev->waiting) == 0) { @@ -395,7 +422,7 @@ } else port->waithead = port->waittail = dev; } - spin_unlock_irqrestore (&port->lock, flags); + spin_unlock_irqrestore (&port->waitlist_lock, flags); } return -EAGAIN; } @@ -451,19 +478,19 @@ "when not owner\n", port->name, dev->name); return; } - spin_lock_irqsave(&port->lock, flags); + write_lock_irqsave(&port->cad_lock, flags); port->cad = NULL; - spin_unlock_irqrestore(&port->lock, flags); + write_unlock_irqrestore(&port->cad_lock, flags); + + /* + * Reenable irq and so discard the eventually pending irq while + * cad is NULL. -arca + */ + if (port->irq != PARPORT_IRQ_NONE && !dev->irq_func) + enable_irq(port->irq); /* Save control registers */ port->ops->save_state(port, dev->state); - - /* Point IRQs somewhere harmless. */ - if (port->irq != PARPORT_IRQ_NONE && dev->irq_func) { - free_irq(port->irq, dev->private); - request_irq(port->irq, parport_null_intr_func, - SA_INTERRUPT, port->name, NULL); - } /* If anybody is waiting, find out who's been there longest and then wake them up. (Note: no locking required) */ diff -u --recursive --new-file v2.1.125/linux/drivers/net/3c505.c linux/drivers/net/3c505.c --- v2.1.125/linux/drivers/net/3c505.c Wed Jun 24 22:54:06 1998 +++ linux/drivers/net/3c505.c Fri Oct 9 11:56:59 1998 @@ -327,13 +327,17 @@ { elp_device *adapter = dev->priv; if (adapter->dmaing && (jiffies > (adapter->current_dma.start_time + 10))) { - unsigned long flags; + unsigned long flags, f; printk("%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma)); save_flags(flags); cli(); adapter->dmaing = 0; adapter->busy = 0; + + f=claim_dma_lock(); disable_dma(dev->dma); + release_dma_lock(f); + if (adapter->rx_active) adapter->rx_active--; outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev); @@ -601,6 +605,7 @@ elp_device *adapter = dev->priv; void *target; struct sk_buff *skb; + unsigned long flags; rlen = (len + 1) & ~1; skb = dev_alloc_skb(rlen + 2); @@ -632,12 +637,14 @@ outb_control(adapter->hcr_val | DIR | TCEN | DMAE, dev); + flags=claim_dma_lock(); disable_dma(dev->dma); clear_dma_ff(dev->dma); set_dma_mode(dev->dma, 0x04); /* dma read */ set_dma_addr(dev->dma, virt_to_bus(target)); set_dma_count(dev->dma, rlen); enable_dma(dev->dma); + release_dma_lock(flags); if (elp_debug >= 3) { printk("%s: rx DMA transfer started\n", dev->name); @@ -1019,6 +1026,7 @@ { elp_device *adapter = dev->priv; unsigned long target; + unsigned long flags; /* * make sure the length is even and no shorter than 60 bytes @@ -1060,7 +1068,8 @@ target = virt_to_bus(adapter->dma_buffer); } adapter->current_dma.skb = skb; - cli(); + + flags=claim_dma_lock(); disable_dma(dev->dma); clear_dma_ff(dev->dma); set_dma_mode(dev->dma, 0x48); /* dma memory -> io */ @@ -1068,6 +1077,8 @@ set_dma_count(dev->dma, nlen); outb_control(adapter->hcr_val | DMAE | TCEN, dev); enable_dma(dev->dma); + release_dma_lock(flags); + if (elp_debug >= 3) printk("%s: DMA transfer started\n", dev->name); diff -u --recursive --new-file v2.1.125/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v2.1.125/linux/drivers/net/3c509.c Tue Aug 18 22:02:04 1998 +++ linux/drivers/net/3c509.c Sat Oct 17 15:33:45 1998 @@ -178,28 +178,64 @@ } #ifdef CONFIG_MCA -#warning "The MCA code in drivers/net/3c509.c does not compile" -#warning "See http://glycerine.itsmm.uni.edu/mca/ for patches." -#if 0 - if (MCA_bus) { - mca_adaptor_select_mode(1); - for (i = 0; i < 8; i++) - if ((mca_adaptor_id(i) | 1) == 0x627c) { - ioaddr = mca_pos_base_addr(i); - irq = inw(ioaddr + WN0_IRQ) >> 12; - if_port = inw(ioaddr + 6)>>14; - for (i = 0; i < 3; i++) - phys_addr[i] = htons(read_eeprom(ioaddr, i)); +#define MCA_NUMBER_OF_SLOTS 8 +#define MCA_PORT_POS_SEL 0x096 +#define MCA_PORT_ID_REG_0 0x100 +#define MCA_PORT_ID_REG_1 0x101 +#define MCA_SELECT_BIT 0x08 + if (MCA_bus) + { + u_int mca_id; + u_char posreg[4]; + int mca_slot; - mca_adaptor_select_mode(0); - goto found; + if (el3_debug > 2) + printk("3c529: probing...\n"); + /* This should probably be done once early on and read into + * a structure somewhere... */ + for (mca_slot = 0; mca_slot < MCA_NUMBER_OF_SLOTS; mca_slot++) + { + /* Select MCA slot i */ + outb_p(mca_slot | MCA_SELECT_BIT, MCA_PORT_POS_SEL); + mca_id = ((inb_p(MCA_PORT_ID_REG_1)<<8) + + inb_p(MCA_PORT_ID_REG_0)); + if (mca_id == 0x627C /* 10base2 */ + || mca_id == 0x627D /* 10baseT */ + || mca_id == 0x62DB /* Test mode */ + || mca_id == 0x62F6 /* TP or coax */ + || mca_id == 0x62F7) /* TP only */ + { + if (el3_debug > 1) + printk("3c529: Found with id 0x%x at slot %d\n", + mca_id, mca_slot); + posreg[0] = inb_p(0x102); posreg[1] = inb_p(0x103); + posreg[2] = inb_p(0x104); posreg[3] = inb_p(0x105); + break; } - mca_adaptor_select_mode(0); - + mca_id = 0xFFFF; + } + /* Read values from POS registers so now disable */ + outb(0,MCA_PORT_POS_SEL); + if (mca_id != 0xFFFF && !(posreg[0]&0x01)) + printk("3c529: Adapter found but disabled in slot %d\n", mca_slot); + else if (mca_id != 0xFFFF && posreg[0]&0x01) + { + /* Found and adapter is enabled */ + if (el3_debug > 2) + printk("3c529: pos registers 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", + posreg[0], posreg[1], posreg[2], posreg[3]); + ioaddr = ((short)((posreg[2]&0xfc)|0x02)) << 8; + irq = posreg[3] & 0x0f; + if_port = posreg[2] & 0x03; + if (el3_debug > 2) + printk("3c529: irq %d ioaddr 0x%x ifport %d\n", + irq, ioaddr, if_port); + for (i = 0; i < 3; i++) + phys_addr[i] = htons(read_eeprom(ioaddr, i)); + goto found; + } } #endif -#endif - /* Reset the ISA PnP mechanism on 3c509b. */ outb(0x02, 0x279); /* Select PnP config control register. */ outb(0x02, 0xA79); /* Return to WaitForKey state. */ diff -u --recursive --new-file v2.1.125/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.125/linux/drivers/net/Config.in Fri Oct 9 13:27:08 1998 +++ linux/drivers/net/Config.in Sat Oct 17 15:33:45 1998 @@ -106,6 +106,9 @@ fi bool 'SK_G16 support' CONFIG_SK_G16 fi + if [ "$CONFIG_MCA" = "y" ]; then + tristate 'NE/2 (ne2000 MCA version) support' CONFIG_NE2_MCA + fi bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA if [ "$CONFIG_NET_EISA" = "y" ]; then tristate 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32 diff -u --recursive --new-file v2.1.125/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.1.125/linux/drivers/net/Makefile Fri Oct 9 13:27:08 1998 +++ linux/drivers/net/Makefile Sat Oct 17 15:33:45 1998 @@ -199,6 +199,16 @@ endif endif +ifeq ($(CONFIG_NE2_MCA),y) +L_OBJS += ne2.o +CONFIG_8390_BUILTIN = y +else + ifeq ($(CONFIG_NE2_MCA),m) + CONFIG_8390_MODULE = y + M_OBJS += ne2.o + endif +endif + ifeq ($(CONFIG_HPLAN),y) L_OBJS += hp.o CONFIG_8390_BUILTIN = y diff -u --recursive --new-file v2.1.125/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.1.125/linux/drivers/net/Space.c Fri Oct 9 13:27:08 1998 +++ linux/drivers/net/Space.c Sat Oct 17 15:33:45 1998 @@ -39,6 +39,7 @@ ethernet adaptor have the name "eth[0123...]". */ +extern int ne2_probe(struct device *dev); extern int tulip_probe(struct device *dev); extern int hp100_probe(struct device *dev); extern int ultra_probe(struct device *dev); @@ -108,6 +109,7 @@ extern int epic100_probe(struct device *dev); extern int rtl8139_probe(struct device *dev); extern int hplance_probe(struct device *dev); +extern int via_rhine_probe(struct device *dev); /* Gigabit Ethernet adapters */ extern int yellowfin_probe(struct device *dev); @@ -195,6 +197,9 @@ #ifdef CONFIG_YELLOWFIN {yellowfin_probe, 0}, #endif +#ifdef CONFIG_VIA_RHINE + {via_rhine_probe, 0}, +#endif {NULL, 0}, }; @@ -242,6 +247,9 @@ struct devprobe mca_probes[] __initdata = { #ifdef CONFIG_ULTRAMCA {ultramca_probe, 0}, +#endif +#ifdef CONFIG_NE2_MCA + {ne2_probe, 0}, #endif #ifdef CONFIG_ELMC /* 3c523 */ {elmc_probe, 0}, diff -u --recursive --new-file v2.1.125/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c --- v2.1.125/linux/drivers/net/eepro100.c Mon Aug 3 12:45:45 1998 +++ linux/drivers/net/eepro100.c Tue Oct 20 17:04:29 1998 @@ -1,13 +1,13 @@ /* drivers/net/eepro100.c: An Intel i82557 Ethernet driver for Linux. */ /* NOTICE: this version tested with kernels 1.3.72 and later only! - Written 1996-1997 by Donald Becker. + Written 1996-1998 by Donald Becker. This software may be used and distributed according to the terms of the GNU Public License, incorporated herein by reference. This driver is for the Intel EtherExpress Pro 100B boards. - It should work with other i82557 boards (if any others exist). + It should work with other i82557 and i82558 boards. To use a built-in driver, install as drivers/net/eepro100.c. To use as a module, use the compile-command at the end of the file. @@ -15,11 +15,13 @@ Center of Excellence in Space Data and Information Sciences Code 930.5, NASA Goddard Space Flight Center, Greenbelt MD 20771 For updates see - + http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html + There is also a mailing list based at + linux-eepro100@cesdis.gsfc.nasa.gov */ static const char *version = -"eepro100.c:v0.36 10/20/97 Donald Becker linux-eepro100@cesdis.gsfc.nasa.gov\n"; +"eepro100.c:v1.06 10/16/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n"; /* A few user-configurable values that apply to all boards. First set are undocumented and spelled per Intel recommendations. */ @@ -33,125 +35,60 @@ /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method. Lower values use more memory, but are faster. */ -/* - * NOTE! The value of 2000 means that this optimization never gets - * used. Rationale: it seems to be broken when in low-memory situations, - * apparently when alloc_skb() can return NULL the clever list of - * copy-buffers can get buggered. - * - * My personal suspicion is that the allocation failure will cause - * us to not remove the skb from the list of available buffers, but - * we'd already have done a "skb_push()" with the data we got, so - * the buffer stays on the list but the available memory in it - * shrinks until we panic. - * - * Donald, when you fix this you can shrink this value again. - * - * Linus - */ -static int rx_copybreak = 2000; +static int rx_copybreak = 200; /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ static int max_interrupt_work = 200; -#ifdef MODULE -#ifdef MODVERSIONS -#include -#endif +/* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */ +static int multicast_filter_limit = 64; + #include -#else -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif #include #include -#include #include #include -#include #include #include #include #include #include -#include -#include /* Processor type for cache alignment. */ -#include -#include -#include - #include #include #include - -/* A nominally proper method to handle version dependencies is to use - LINUX_VERSION_CODE in version.h, but that triggers recompiles w/'make'. */ -#define VERSION(v,p,s) (((v)<<16)+(p<<8)+s) -#ifdef MODULE -#if (LINUX_VERSION_CODE < VERSION(1,3,0)) -#define KERNEL_1_2 -#else /* 1.3.0 */ -#if (LINUX_VERSION_CODE >= VERSION(1,3,44)) -#define NEW_MULTICAST -#define LINUX_1_4 -#else -#warning "This driver is tested for 1.3.44 and later development kernels only." -#endif /* 1.3.44 */ -#endif -#else - -#if (LINUX_VERSION_CODE >= 0x10344) -#define NEW_MULTICAST #include -#endif -#ifdef HAVE_HEADER_CACHE -#define LINUX_1_4 -#define NEW_MULTICAST -#else -#ifdef ETH_P_DDCMP /* Warning: Bogus! This means IS_LINUX_1_3. */ -#define KERNEL_1_3 -#else -#define KERNEL_1_2 -#endif -#endif +#include +#include +#include + +/* + * Module documentation + */ +MODULE_AUTHOR("Donald Becker "); +MODULE_DESCRIPTION("Intel i82557/i82558 PCI EtherExpressPro driver"); +MODULE_PARM(debug, "i"); +MODULE_PARM(options, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(congenb, "i"); +MODULE_PARM(txfifo, "i"); +MODULE_PARM(rxfifo, "i"); +MODULE_PARM(txdmacount, "i"); +MODULE_PARM(rxdmacount, "i"); +MODULE_PARM(rx_copybreak, "i"); +MODULE_PARM(max_interrupt_work, "i"); +MODULE_PARM(multicast_filter_limit, "i"); -#endif -/* This should be in a header file. */ -#if (LINUX_VERSION_CODE < VERSION(1,3,44)) -struct device *init_etherdev(struct device *dev, int sizeof_priv, - unsigned long *mem_startp); -#endif -#if LINUX_VERSION_CODE < 0x10300 -#define RUN_AT(x) (x) /* What to put in timer->expires. */ -#define DEV_ALLOC_SKB(len) alloc_skb(len, GFP_ATOMIC) -#define virt_to_bus(addr) ((unsigned long)addr) -#define bus_to_virt(addr) ((void*)addr) -#else /* 1.3.0 and later */ #define RUN_AT(x) (jiffies + (x)) -#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2) -#endif -#if (LINUX_VERSION_CODE < 0x20123) -#define test_and_set_bit(val, addr) set_bit(val, addr) -#include -#endif +#define dev_free_skb(skb) dev_kfree_skb(skb); -/* The total I/O port extent of the board. Nominally 0x18, but rounded up - for PCI allocation. */ +/* The total I/O port extent of the board. + The registers beyond 0x18 only exist on the i82558. */ #define SPEEDO3_TOTAL_SIZE 0x20 -#ifdef HAVE_DEVLIST -struct netdev_entry eepro100_drv = -{"EEPro-100", eepro100_init, SPEEDO3_TOTAL_SIZE, NULL}; -#endif - -#ifdef SPEEDO3_DEBUG -int speedo_debug = SPEEDO3_DEBUG; -#else -int speedo_debug = 3; -#endif +int speedo_debug = 0; /* Theory of Operation @@ -183,7 +120,7 @@ Despite the extra space overhead in each receive skbuff, the driver must use the simplified Rx buffer mode to assure that only a single data buffer is associated with each RxFD. The driver implements this by reserving space -for the Rx descriptor at the head of each Rx skbuff +for the Rx descriptor at the head of each Rx skbuff. The Speedo-3 has receive and command unit base addresses that are added to almost all descriptor pointers. The driver sets these to zero, so that all @@ -198,10 +135,13 @@ The driver must use the complex Tx command+descriptor mode in order to have a indirect pointer to the skbuff data section. Each Tx command block -(TxCB) is associated with a single, immediately appended Tx buffer descriptor +(TxCB) is associated with two immediately appended Tx Buffer Descriptor (TxBD). A fixed ring of these TxCB+TxBD pairs are kept as part of the speedo_private data structure for each adapter instance. +The newer i82558 explicitly supports this structure, and can read the two +TxBDs in the same PCI burst as the TxCB. + This ring structure is used for all normal transmit packets, but the transmit packet descriptors aren't long enough for most non-Tx commands such as CmdConfigure. This is complicated by the possibility that the chip has @@ -290,26 +230,19 @@ #define PKT_BUF_SZ 1536 /* Time in jiffies before concluding the transmitter is hung. */ -#define TX_TIMEOUT ((400*HZ)/1000) +#define TX_TIMEOUT ((800*HZ)/1000) /* How to wait for the command unit to accept a command. Typically this takes 0 ticks. */ -static inline void wait_for_cmd_done(int cmd_ioaddr) +static inline void wait_for_cmd_done(long cmd_ioaddr) { - short wait = 100; - do ; - while(inb(cmd_ioaddr) && --wait >= 0); + int wait = 100; + do ; + while(inb(cmd_ioaddr) && --wait >= 0); } /* Operational parameter that usually are not changed. */ -#ifndef PCI_VENDOR_ID_INTEL /* Now defined in linux/pci.h */ -#define PCI_VENDOR_ID_INTEL 0x8086 /* Hmmmm, how did they pick that? */ -#endif -#ifndef PCI_DEVICE_ID_INTEL_82557 -#define PCI_DEVICE_ID_INTEL_82557 0x1229 -#endif - /* The rest of these values should never change. */ /* Offsets to the various registers. @@ -364,17 +297,24 @@ u16 size; }; -/* Elements of the RxFD.status word. */ -#define RX_COMPLETE 0x8000 +/* Selected elements of the Tx/RxFD.status word. */ +enum RxFD_bits { + RxComplete=0x8000, RxOK=0x2000, + RxErrCRC=0x0800, RxErrAlign=0x0400, RxErrTooBig=0x0200, RxErrSymbol=0x0010, + RxEth2Type=0x0020, RxNoMatch=0x0004, RxNoIAMatch=0x0002, + StatusComplete=0x8000, +}; struct TxFD { /* Transmit frame descriptor set. */ s32 status; u32 link; /* void * */ u32 tx_desc_addr; /* Always points to the tx_buf_addr element. */ s32 count; /* # of TBD (=1), Tx start thresh., etc. */ - /* This constitutes a single "TBD" entry -- we only use one. */ - u32 tx_buf_addr; /* void *, frame to be transmitted. */ - s32 tx_buf_size; /* Length of Tx frame. */ + /* This constitutes two "TBD" entries -- we only use one. */ + u32 tx_buf_addr0; /* void *, frame to be transmitted. */ + s32 tx_buf_size0; /* Length of Tx frame. */ + u32 tx_buf_addr1; /* void *, frame to be transmitted. */ + s32 tx_buf_size1; /* Length of Tx frame. */ }; /* Elements of the dump_statistics block. This block must be lword aligned. */ @@ -402,6 +342,7 @@ char devname[8]; /* Used only for kernel debugging. */ const char *product_name; struct device *next_module; + spinlock_t lock; struct TxFD tx_ring[TX_RING_SIZE]; /* Commands (usually CmdTxPacket). */ /* The saved address of a sent-in-place packet/buffer, for skfree(). */ struct sk_buff* tx_skbuff[TX_RING_SIZE]; @@ -409,9 +350,6 @@ /* Rx descriptor ring & addresses of receive-in-place skbuffs. */ struct RxFD *rx_ringp[RX_RING_SIZE]; struct sk_buff* rx_skbuff[RX_RING_SIZE]; -#if (LINUX_VERSION_CODE < 0x10300) /* Kernel v1.2.*. */ - struct RxFD saved_skhead[RX_RING_SIZE]; /* Saved skbuff header chunk. */ -#endif struct RxFD *last_rxf; /* Last command sent. */ struct enet_statistics stats; struct speedo_stats lstats; @@ -419,10 +357,9 @@ long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */ unsigned int cur_rx, cur_tx; /* The next free ring entry */ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ - struct descriptor config_cmd; /* A configure command, with header... */ - u8 config_cmd_data[22]; /* .. and setup parameters. */ int mc_setup_frm_len; /* The length of an allocated.. */ struct descriptor *mc_setup_frm; /* ..multicast setup frame. */ + int mc_setup_busy; /* Avoid double-use of setup frame. */ char rx_mode; /* Current PROMISC/ALLMULTI setting. */ unsigned int tx_full:1; /* The Tx queue is full. */ unsigned int full_duplex:1; /* Full-duplex operation requested. */ @@ -436,11 +373,16 @@ /* The parameters for a CmdConfigure operation. There are so many options that it would be difficult to document each bit. We mostly use the default or recommended settings. */ -const char basic_config_cmd[22] = { +const char i82557_config_cmd[22] = { 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */ 0, 0x2E, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */ 0x3f, 0x05, }; +const char i82558_config_cmd[22] = { + 22, 0x08, 0, 1, 0, 0x80, 0x22, 0x03, 1, /* 1=Use MII 0=Use AUI */ + 0, 0x2E, 0, 0x60, 0x08, 0x88, + 0x68, 0, 0x40, 0xf2, 0xBD, /* 0xBD->0xFD=Force full-duplex */ + 0x31, 0x05, }; /* PHY media interface chips. */ static const char *phys[] = { @@ -452,12 +394,12 @@ S80C24, I82555, DP83840A=10, }; static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 }; -static void speedo_found1(struct device *dev, int ioaddr, int irq, - int options, int card_idx); +static void speedo_found1(struct device *dev, long ioaddr, int irq, + int card_idx); -static int read_eeprom(int ioaddr, int location); -static int mdio_read(int ioaddr, int phy_id, int location); -static int mdio_write(int ioaddr, int phy_id, int location, int value); +static int read_eeprom(long ioaddr, int location, int addr_len); +static int mdio_read(long ioaddr, int phy_id, int location); +static int mdio_write(long ioaddr, int phy_id, int location, int value); static int speedo_open(struct device *dev); static void speedo_timer(unsigned long data); static void speedo_init_rx_ring(struct device *dev); @@ -466,9 +408,7 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int speedo_close(struct device *dev); static struct enet_statistics *speedo_get_stats(struct device *dev); -#ifdef HAVE_PRIVATE_IOCTL static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd); -#endif static void set_rx_mode(struct device *dev); @@ -477,109 +417,101 @@ /* 'options' is used to pass a transceiver override or full-duplex flag e.g. "options=16" for FD, "options=32" for 100mbps-only. */ static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1}; -#ifdef MODULE static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1}; +#ifdef MODULE static int debug = -1; /* The debug level */ #endif +#ifdef honor_default_port +/* Optional driver feature to allow forcing the transceiver setting. + Not recommended. */ +static int mii_ctrl[8] = { 0x3300, 0x3100, 0x0000, 0x0100, + 0x2000, 0x2100, 0x0400, 0x3100}; +#endif + /* A list of all installed Speedo devices, for removing the driver module. */ static struct device *root_speedo_dev = NULL; int eepro100_init(struct device *dev) { int cards_found = 0; + static int pci_index = 0; - if (pci_present()) { - static int pci_index = 0; + if (! pcibios_present()) + return cards_found; - for (; pci_index < 8; pci_index++) { - unsigned char pci_bus, pci_device_fn, pci_latency; -#if (LINUX_VERSION_CODE >= VERSION(2,1,85)) - unsigned int pci_irq_line; - struct pci_dev *pdev; -#else - unsigned char pci_irq_line; -#endif -#if (LINUX_VERSION_CODE >= VERSION(1,3,44)) - int pci_ioaddr; -#else - long pci_ioaddr; -#endif - unsigned short pci_command; - - if (pcibios_find_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82557, - pci_index, &pci_bus, - &pci_device_fn)) - break; -#if (LINUX_VERSION_CODE >= VERSION(2,1,85)) - pdev = pci_find_slot(pci_bus, pci_device_fn); - pci_irq_line = pdev->irq; - pci_ioaddr = pdev->base_address[1]; -#else - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq_line); - /* Note: BASE_ADDRESS_0 is for memory-mapping the registers. */ - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, &pci_ioaddr); -#endif - /* Remove I/O space marker in bit 0. */ - pci_ioaddr &= ~3; - if (speedo_debug > 2) - printk("Found Intel i82557 PCI Speedo at I/O %#x, IRQ %d.\n", - (int)pci_ioaddr, pci_irq_line); - - /* Get and check the bus-master and latency values. */ - pcibios_read_config_word(pci_bus, pci_device_fn, - PCI_COMMAND, &pci_command); - if ( ! (pci_command & PCI_COMMAND_MASTER)) { - printk(" PCI Master Bit has not been set! Setting...\n"); - pci_command |= PCI_COMMAND_MASTER; - pcibios_write_config_word(pci_bus, pci_device_fn, - PCI_COMMAND, pci_command); - } - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_LATENCY_TIMER, &pci_latency); - if (pci_latency < 10) { - printk(" PCI latency timer (CFLT) is unreasonably low at %d." - " Setting to 255 clocks.\n", pci_latency); - pcibios_write_config_byte(pci_bus, pci_device_fn, - PCI_LATENCY_TIMER, 255); - } else if (speedo_debug > 1) - printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency); - -#ifdef MODULE - speedo_found1(dev, pci_ioaddr, pci_irq_line, options[cards_found], - cards_found); -#else - speedo_found1(dev, pci_ioaddr, pci_irq_line, - dev ? dev->mem_start : 0, -1); -#endif - dev = NULL; - cards_found++; + for (; pci_index < 8; pci_index++) { + unsigned char pci_bus, pci_device_fn, pci_latency; + long ioaddr; + int irq; + + u16 pci_command, new_command; + + if (pcibios_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82557, + pci_index, &pci_bus, + &pci_device_fn)) + break; + { + struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); + ioaddr = pdev->base_address[1]; /* Use [0] to mem-map */ + irq = pdev->irq; } + /* Remove I/O space marker in bit 0. */ + ioaddr &= ~3; + if (speedo_debug > 2) + printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n", + ioaddr, irq); + + /* Get and check the bus-master and latency values. */ + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, &pci_command); + new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO; + if (pci_command != new_command) { + printk(KERN_INFO " The PCI BIOS has not enabled this" + " device! Updating PCI command %4.4x->%4.4x.\n", + pci_command, new_command); + pcibios_write_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, new_command); + } + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, &pci_latency); + if (pci_latency < 32) { + printk(" PCI latency timer (CFLT) is unreasonably low at %d." + " Setting to 32 clocks.\n", pci_latency); + pcibios_write_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, 32); + } else if (speedo_debug > 1) + printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency); + + speedo_found1(dev, ioaddr, irq, cards_found); + dev = NULL; + cards_found++; } return cards_found; } -static void speedo_found1(struct device *dev, int ioaddr, int irq, int options, +static void speedo_found1(struct device *dev, long ioaddr, int irq, int card_idx) { static int did_version = 0; /* Already printed version info. */ struct speedo_private *sp; char *product; - int i; + int i, option; u16 eeprom[0x40]; if (speedo_debug > 0 && did_version++ == 0) printk(version); -#if (LINUX_VERSION_CODE >= VERSION(1,3,44)) dev = init_etherdev(dev, sizeof(struct speedo_private)); -#else - dev = init_etherdev(dev, sizeof(struct speedo_private), 0); -#endif + + if (dev->mem_start > 0) + option = dev->mem_start; + else if (card_idx >= 0 && options[card_idx] >= 0) + option = options[card_idx]; + else + option = 0; /* Read the station address EEPROM before doing the reset. Perhaps this should even be done before accepting the device, @@ -587,8 +519,10 @@ { u16 sum = 0; int j; + int addr_len = read_eeprom(ioaddr, 0, 6) == 0xffff ? 8 : 6; + for (j = 0, i = 0; i < 0x40; i++) { - u16 value = read_eeprom(ioaddr, i); + u16 value = read_eeprom(ioaddr, i, addr_len); eeprom[i] = value; sum += value; if (i < 3) { @@ -614,7 +548,7 @@ else product = "Intel EtherExpress Pro 10/100"; - printk(KERN_INFO "%s: %s at %#3x, ", dev->name, product, ioaddr); + printk(KERN_INFO "%s: %s at %#3lx, ", dev->name, product, ioaddr); for (i = 0; i < 5; i++) printk("%2.2X:", dev->dev_addr[i]); @@ -643,17 +577,6 @@ if (eeprom[7] & 0x0700) printk(KERN_INFO " Secondary interface chip %s.\n", phys[(eeprom[7]>>8)&7]); -#if defined(notdef) - /* ToDo: Read and set PHY registers through MDIO port. */ - for (i = 0; i < 2; i++) - printk(KERN_INFO" MDIO register %d is %4.4x.\n", - i, mdio_read(ioaddr, eeprom[6] & 0x1f, i)); - for (i = 5; i < 7; i++) - printk(KERN_INFO" MDIO register %d is %4.4x.\n", - i, mdio_read(ioaddr, eeprom[6] & 0x1f, i)); - printk(KERN_INFO" MDIO register %d is %4.4x.\n", - 25, mdio_read(ioaddr, eeprom[6] & 0x1f, 25)); -#endif if (((eeprom[6]>>8) & 0x3f) == DP83840 || ((eeprom[6]>>8) & 0x3f) == DP83840A) { int mdi_reg23 = mdio_read(ioaddr, eeprom[6] & 0x1f, 23) | 0x0422; @@ -663,13 +586,13 @@ mdi_reg23); mdio_write(ioaddr, eeprom[6] & 0x1f, 23, mdi_reg23); } - if ((options >= 0) && (options & 0x60)) { + if ((option >= 0) && (option & 0x70)) { printk(KERN_INFO " Forcing %dMbs %s-duplex operation.\n", - (options & 0x20 ? 100 : 10), - (options & 0x10 ? "full" : "half")); + (option & 0x20 ? 100 : 10), + (option & 0x10 ? "full" : "half")); mdio_write(ioaddr, eeprom[6] & 0x1f, 0, - ((options & 0x20) ? 0x2000 : 0) | /* 100mbps? */ - ((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */ + ((option & 0x20) ? 0x2000 : 0) | /* 100mbps? */ + ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */ } /* Perform a system self-test. */ @@ -678,11 +601,7 @@ self_test_results[1] = -1; outl(virt_to_bus(self_test_results) | 1, ioaddr + SCBPort); do { -#ifdef _LINUX_DELAY_H udelay(10); -#else - SLOW_DOWN_IO; -#endif } while (self_test_results[1] == -1 && --boguscnt >= 0); if (boguscnt < 0) { /* Test optimized out. */ @@ -704,8 +623,6 @@ } #endif /* kernel_bloat */ - outl(0, ioaddr + SCBPort); - /* We do a request_region() only to register /proc/ioports info. */ request_region(ioaddr, SPEEDO3_TOTAL_SIZE, "Intel Speedo3 Ethernet"); @@ -719,12 +636,12 @@ sp->next_module = root_speedo_dev; root_speedo_dev = dev; + sp->full_duplex = option >= 0 && (option & 0x10) ? 1 : 0; if (card_idx >= 0) { if (full_duplex[card_idx] >= 0) sp->full_duplex = full_duplex[card_idx]; - } else - sp->full_duplex = options >= 0 && (options & 0x10) ? 1 : 0; - sp->default_port = options >= 0 ? (options & 0x0f) : 0; + } + sp->default_port = option >= 0 ? (option & 0x0f) : 0; sp->phy[0] = eeprom[6]; sp->phy[1] = eeprom[7]; @@ -738,12 +655,8 @@ dev->hard_start_xmit = &speedo_start_xmit; dev->stop = &speedo_close; dev->get_stats = &speedo_get_stats; -#ifdef NEW_MULTICAST dev->set_multicast_list = &set_rx_mode; -#endif -#ifdef HAVE_PRIVATE_IOCTL dev->do_ioctl = &speedo_ioctl; -#endif return; } @@ -760,38 +673,31 @@ #define EE_ENB (0x4800 | EE_CS) /* Delay between EEPROM clock transitions. - This is a "nasty" timing loop, but PC compatible machines are defined - to delay an ISA compatible period for the SLOW_DOWN_IO macro. */ -#ifdef _LINUX_DELAY_H + This will actually work with no delay on 33Mhz PCI. */ #define eeprom_delay(nanosec) udelay(1); -#else -#define eeprom_delay(nanosec) do { int _i = 3; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0) -#endif /* The EEPROM commands include the alway-set leading bit. */ -#define EE_WRITE_CMD (5 << 6) -#define EE_READ_CMD (6 << 6) -#define EE_ERASE_CMD (7 << 6) +#define EE_WRITE_CMD (5 << addr_len) +#define EE_READ_CMD (6 << addr_len) +#define EE_ERASE_CMD (7 << addr_len) -static int read_eeprom(int ioaddr, int location) +static int read_eeprom(long ioaddr, int location, int addr_len) { - int i; unsigned short retval = 0; int ee_addr = ioaddr + SCBeeprom; int read_cmd = location | EE_READ_CMD; + int i; outw(EE_ENB & ~EE_CS, ee_addr); outw(EE_ENB, ee_addr); /* Shift the read command bits out. */ - for (i = 10; i >= 0; i--) { + for (i = 12; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; outw(EE_ENB | dataval, ee_addr); eeprom_delay(100); outw(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); eeprom_delay(150); - outw(EE_ENB | dataval, ee_addr); /* Finish EEPROM a clock tick. */ - eeprom_delay(250); } outw(EE_ENB, ee_addr); @@ -808,16 +714,11 @@ return retval; } -static int mdio_read(int ioaddr, int phy_id, int location) +static int mdio_read(long ioaddr, int phy_id, int location) { - int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */ + int val, boguscnt = 64*10; /* <64 usec. to complete, typ 27 ticks */ outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI); do { -#ifdef _LINUX_DELAY_H - udelay(16); -#else - SLOW_DOWN_IO; -#endif val = inl(ioaddr + SCBCtrlMDI); if (--boguscnt < 0) { printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val); @@ -826,17 +727,12 @@ return val & 0xffff; } -static int mdio_write(int ioaddr, int phy_id, int location, int value) +static int mdio_write(long ioaddr, int phy_id, int location, int value) { - int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */ + int val, boguscnt = 64*10; /* <64 usec. to complete, typ 27 ticks */ outl(0x04000000 | (location<<16) | (phy_id<<21) | value, ioaddr + SCBCtrlMDI); do { -#ifdef _LINUX_DELAY_H - udelay(16); -#else - SLOW_DOWN_IO; -#endif val = inl(ioaddr + SCBCtrlMDI); if (--boguscnt < 0) { printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val); @@ -850,24 +746,38 @@ speedo_open(struct device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; - int ioaddr = dev->base_addr; + long ioaddr = dev->base_addr; #ifdef notdef /* We could reset the chip, but should not need to. */ + /* In fact we MUST NOT, unless we also re-do the init */ outl(0, ioaddr + SCBPort); - for (i = 40; i >= 0; i--) - SLOW_DOWN_IO; /* At least 250ns */ + udelay(10); #endif - if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, - "Intel EtherExpress Pro 10/100 Ethernet", dev)) { - return -EAGAIN; - } + /* This had better be initialized before we initialize the interrupt! */ + sp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED; if (speedo_debug > 1) printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq); - MOD_INC_USE_COUNT; +#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us + /* Retrigger negotiation to reset previous errors. */ + if ((sp->phy[0] & 0x8000) == 0) { + int phy_addr = sp->phy[0] & 0x1f ; + /* Use 0x3300 for restarting NWay, other values to force xcvr: + 0x0000 10-HD + 0x0100 10-FD + 0x2000 100-HD + 0x2100 100-FD + */ +#ifdef honor_default_port + mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]); +#else + mdio_write(ioaddr, phy_addr, 0, 0x3300); +#endif + } +#endif /* Load the statistics block address. */ wait_for_cmd_done(ioaddr + SCBCmd); @@ -921,6 +831,7 @@ /* Setup the chip and configure the multicast list. */ sp->mc_setup_frm = NULL; sp->mc_setup_frm_len = 0; + sp->mc_setup_busy = 0; sp->rx_mode = -1; /* Invalid -> always reset the mode. */ set_rx_mode(dev); @@ -928,6 +839,24 @@ printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n", dev->name, inw(ioaddr + SCBStatus)); } + + wait_for_cmd_done(ioaddr + SCBCmd); + outw(CU_DUMPSTATS, ioaddr + SCBCmd); + /* No need to wait for the command unit to accept here. */ + if ((sp->phy[0] & 0x8000) == 0) + mdio_read(ioaddr, sp->phy[0] & 0x1f, 0); + + /* + * Request the IRQ last, after we have set up all data structures. + * It would be bad to get an interrupt before we're ready. + */ + if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, + "Intel EtherExpress Pro 10/100 Ethernet", dev)) { + return -EAGAIN; + } + + MOD_INC_USE_COUNT; + /* Set the timer. The timer serves a dual purpose: 1) to monitor the media interface (e.g. link beat) and perhaps switch to an alternate media type @@ -939,8 +868,6 @@ sp->timer.function = &speedo_timer; /* timer handler */ add_timer(&sp->timer); - wait_for_cmd_done(ioaddr + SCBCmd); - outw(CU_DUMPSTATS, ioaddr + SCBCmd); return 0; } @@ -949,24 +876,22 @@ { struct device *dev = (struct device *)data; struct speedo_private *sp = (struct speedo_private *)dev->priv; - int tickssofar = jiffies - sp->last_rx_time; if (speedo_debug > 3) { - int ioaddr = dev->base_addr; - printk(KERN_DEBUG "%s: Media selection tick, status %4.4x.\n", + long ioaddr = dev->base_addr; + printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n", dev->name, inw(ioaddr + SCBStatus)); } - if (sp->rx_bug) { - if (tickssofar > 2*HZ || sp->rx_mode < 0) { - /* We haven't received a packet in a Long Time. We might have been - bitten by the receiver hang bug. This can be cleared by sending - a set multicast list command. */ - set_rx_mode(dev); - } - /* We must continue to monitor the media. */ - sp->timer.expires = RUN_AT(2*HZ); /* 2.0 sec. */ - add_timer(&sp->timer); + if (sp->rx_mode < 0 || + (sp->rx_bug && jiffies - sp->last_rx_time > 2*HZ)) { + /* We haven't received a packet in a Long Time. We might have been + bitten by the receiver hang bug. This can be cleared by sending + a set multicast list command. */ + set_rx_mode(dev); } + /* We must continue to monitor the media. */ + sp->timer.expires = RUN_AT(2*HZ); /* 2.0 sec. */ + add_timer(&sp->timer); } /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ @@ -978,43 +903,32 @@ int i; sp->cur_rx = 0; - sp->dirty_rx = RX_RING_SIZE - 1; for (i = 0; i < RX_RING_SIZE; i++) { struct sk_buff *skb; -#ifndef KERNEL_1_2 skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); -#else - skb = alloc_skb(PKT_BUF_SZ, GFP_ATOMIC); -#endif sp->rx_skbuff[i] = skb; if (skb == NULL) - break; /* Bad news! */ + break; /* OK. Just initially short of Rx bufs. */ skb->dev = dev; /* Mark as being used by this device. */ - -#if LINUX_VERSION_CODE >= 0x10300 rxf = (struct RxFD *)skb->tail; - skb_reserve(skb, sizeof(struct RxFD)); -#else - /* Save the data in the header region -- it's restored later. */ - rxf = (struct RxFD *)(skb->data - sizeof(struct RxFD)); - memcpy(&sp->saved_skhead[i], rxf, sizeof(struct RxFD)); -#endif sp->rx_ringp[i] = rxf; + skb_reserve(skb, sizeof(struct RxFD)); if (last_rxf) last_rxf->link = virt_to_bus(rxf); last_rxf = rxf; rxf->status = 0x00000001; /* '1' is flag value only. */ rxf->link = 0; /* None yet. */ -#if LINUX_VERSION_CODE < 0x10300 /* This field unused by i82557, we use it as a consistency check. */ - rxf->rx_buf_addr = virt_to_bus(skb->data); +#ifdef final_version + rxf->rx_buf_addr = 0xffffffff; #else rxf->rx_buf_addr = virt_to_bus(skb->tail); #endif rxf->count = 0; rxf->size = PKT_BUF_SZ; } + sp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); /* Mark the last entry as end-of-list. */ last_rxf->status = 0xC0000002; /* '2' is flag value only. */ sp->last_rxf = last_rxf; @@ -1023,40 +937,35 @@ static void speedo_tx_timeout(struct device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; - int ioaddr = dev->base_addr; - int i; + long ioaddr = dev->base_addr; printk(KERN_WARNING "%s: Transmit timed out: status %4.4x " - "command %4.4x.\n", - dev->name, inw(ioaddr + SCBStatus), inw(ioaddr + SCBCmd)); -#ifndef final_version - printk(KERN_WARNING "%s: Tx timeout fill index %d scavenge index %d.\n", - dev->name, sp->cur_tx, sp->dirty_tx); - printk(KERN_WARNING " Tx queue "); - for (i = 0; i < TX_RING_SIZE; i++) - printk(" %8.8x", (int)sp->tx_ring[i].status); - printk(".\n" KERN_WARNING " Rx ring "); - for (i = 0; i < RX_RING_SIZE; i++) - printk(" %8.8x", (int)sp->rx_ringp[i]->status); - printk(".\n"); - -#else - dev->if_port ^= 1; - printk(KERN_WARNING " (Media type switching not yet implemented.)\n"); - /* Do not do 'dev->tbusy = 0;' there -- it is incorrect. */ -#endif + " %4.4x at %d/%d command %8.8x.\n", + dev->name, inw(ioaddr + SCBStatus), inw(ioaddr + SCBCmd), + sp->dirty_tx, sp->cur_tx, + sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status); if ((inw(ioaddr + SCBStatus) & 0x00C0) != 0x0080) { - printk(KERN_WARNING "%s: Trying to restart the transmitter...\n", - dev->name); - outl(virt_to_bus(&sp->tx_ring[sp->dirty_tx % TX_RING_SIZE]), - ioaddr + SCBPointer); - outw(CU_START, ioaddr + SCBCmd); + printk(KERN_WARNING "%s: Trying to restart the transmitter...\n", + dev->name); + outl(virt_to_bus(&sp->tx_ring[sp->dirty_tx % TX_RING_SIZE]), + ioaddr + SCBPointer); + outw(CU_START, ioaddr + SCBCmd); } else { - outw(DRVR_INT, ioaddr + SCBCmd); + outw(DRVR_INT, ioaddr + SCBCmd); } - /* Reset the MII transceiver. */ - if ((sp->phy[0] & 0x8000) == 0) - mdio_write(ioaddr, sp->phy[0] & 0x1f, 0, 0x8000); +#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us + /* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */ + if ((sp->phy[0] & 0x8000) == 0) { + int phy_addr = sp->phy[0] & 0x1f; + mdio_write(ioaddr, phy_addr, 0, 0x0400); + mdio_write(ioaddr, phy_addr, 1, 0x0000); + mdio_write(ioaddr, phy_addr, 4, 0x0000); + mdio_write(ioaddr, phy_addr, 0, 0x8000); +#ifdef honor_default_port + mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]); +#endif + } +#endif sp->stats.tx_errors++; dev->trans_start = jiffies; return; @@ -1066,7 +975,7 @@ speedo_start_xmit(struct sk_buff *skb, struct device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; - int ioaddr = dev->base_addr; + long ioaddr = dev->base_addr; int entry; /* Block a timer-based transmit from overlapping. This could better be @@ -1082,7 +991,7 @@ return 1; } speedo_tx_timeout(dev); - return 0; + return 1; } /* Caution: the write order is important here, set the base address @@ -1091,8 +1000,8 @@ { /* Prevent interrupts from changing the Tx ring from underneath us. */ unsigned long flags; - save_flags(flags); - cli(); + spin_lock_irqsave(&sp->lock, flags); + /* Calculate the Tx descriptor entry. */ entry = sp->cur_tx++ % TX_RING_SIZE; @@ -1103,29 +1012,31 @@ sp->tx_ring[entry].link = virt_to_bus(&sp->tx_ring[sp->cur_tx % TX_RING_SIZE]); sp->tx_ring[entry].tx_desc_addr = - virt_to_bus(&sp->tx_ring[entry].tx_buf_addr); + virt_to_bus(&sp->tx_ring[entry].tx_buf_addr0); /* The data region is always in one buffer descriptor, Tx FIFO threshold of 256. */ sp->tx_ring[entry].count = 0x01208000; - sp->tx_ring[entry].tx_buf_addr = virt_to_bus(skb->data); - sp->tx_ring[entry].tx_buf_size = skb->len; + sp->tx_ring[entry].tx_buf_addr0 = virt_to_bus(skb->data); + sp->tx_ring[entry].tx_buf_size0 = skb->len; /* Todo: perhaps leave the interrupt bit set if the Tx queue is more than half full. Argument against: we should be receiving packets and scavenging the queue. Argument for: if so, it shouldn't matter. */ sp->last_cmd->command &= ~(CmdSuspend | CmdIntr); sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; + /* Trigger the command unit resume. */ wait_for_cmd_done(ioaddr + SCBCmd); outw(CU_RESUME, ioaddr + SCBCmd); - restore_flags(flags); + + spin_unlock_irqrestore(&sp->lock, flags); } /* Leave room for set_rx_mode() to fill two entries. */ if (sp->cur_tx - sp->dirty_tx > TX_RING_SIZE - 3) sp->tx_full = 1; else - dev->tbusy = 0; + clear_bit(0, (void*)&dev->tbusy); dev->trans_start = jiffies; @@ -1138,7 +1049,7 @@ { struct device *dev = (struct device *)dev_instance; struct speedo_private *sp; - int ioaddr, boguscnt = max_interrupt_work; + long ioaddr, boguscnt = max_interrupt_work; unsigned short status; #ifndef final_version @@ -1150,11 +1061,9 @@ ioaddr = dev->base_addr; sp = (struct speedo_private *)dev->priv; + spin_lock(&sp->lock); + #ifndef final_version - if (dev->interrupt) { - printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name); - return; - } dev->interrupt = 1; #endif @@ -1174,19 +1083,6 @@ speedo_rx(dev); if (status & 0x1000) { -#ifdef notdef - int i; - printk(KERN_WARNING"%s: The EEPro100 receiver left the ready" - " state -- %4.4x! Index %d (%d).\n", dev->name, status, - sp->cur_rx, sp->cur_rx % RX_RING_SIZE); - printk(KERN_WARNING " Rx ring:\n "); - for (i = 0; i < RX_RING_SIZE; i++) - printk(" %d %8.8x %8.8x %8.8x %d %d.\n", - i, sp->rx_ringp[i]->status, sp->rx_ringp[i]->link, - sp->rx_ringp[i]->rx_buf_addr, sp->rx_ringp[i]->count, - sp->rx_ringp[i]->size); -#endif - if ((status & 0x003c) == 0x0028) /* No more Rx buffers. */ outw(RX_RESUMENR, ioaddr + SCBCmd); else if ((status & 0x003c) == 0x0008) { /* No resources (why?!) */ @@ -1209,14 +1105,15 @@ if (speedo_debug > 5) printk(KERN_DEBUG " scavenge candidate %d status %4.4x.\n", entry, status); - if ((status & 0x8000) == 0) + if ((status & StatusComplete) == 0) break; /* It still hasn't been processed. */ /* Free the original skb. */ if (sp->tx_skbuff[entry]) { sp->stats.tx_packets++; /* Count only user packets. */ - dev_kfree_skb(sp->tx_skbuff[entry]); + dev_free_skb(sp->tx_skbuff[entry]); sp->tx_skbuff[entry] = 0; - } + } else if ((sp->tx_ring[entry].status&0x70000) == CmdNOp << 16) + sp->mc_setup_busy = 0; dirty_tx++; } @@ -1233,7 +1130,7 @@ && dirty_tx > sp->cur_tx - TX_RING_SIZE + 2) { /* The ring is no longer full, clear tbusy. */ sp->tx_full = 0; - dev->tbusy = 0; + clear_bit(0, (void*)&dev->tbusy); mark_bh(NET_BH); } @@ -1253,19 +1150,8 @@ printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", dev->name, inw(ioaddr + SCBStatus)); -#ifndef final_version - /* Special code for testing *only*. */ - { - static int stopit = 100; - if (dev->start == 0 && --stopit < 0) { - printk(KERN_ALERT "%s: Emergency stop, interrupt is stuck.\n", - dev->name); - free_irq(irq, dev); - } - } -#endif - dev->interrupt = 0; + spin_unlock(&sp->lock); return; } @@ -1275,150 +1161,104 @@ struct speedo_private *sp = (struct speedo_private *)dev->priv; int entry = sp->cur_rx % RX_RING_SIZE; int status; + int rx_work_limit = sp->dirty_rx + RX_RING_SIZE - sp->cur_rx; if (speedo_debug > 4) printk(KERN_DEBUG " In speedo_rx().\n"); /* If we own the next entry, it's a new packet. Send it up. */ - while ((status = sp->rx_ringp[entry]->status) & RX_COMPLETE) { + while (sp->rx_ringp[entry] != NULL && + (status = sp->rx_ringp[entry]->status) & RxComplete) { + if (--rx_work_limit < 0) + break; if (speedo_debug > 4) printk(KERN_DEBUG " speedo_rx() status %8.8x len %d.\n", status, sp->rx_ringp[entry]->count & 0x3fff); - if (status & 0x0200) { - printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, " - "status %8.8x!\n", dev->name, status); - } else if ( ! (status & 0x2000)) { - /* There was a fatal error. This *should* be impossible. */ - sp->stats.rx_errors++; - printk(KERN_ERR "%s: Anomalous event in speedo_rx(), status %8.8x.\n", - dev->name, status); + if ((status & (RxErrTooBig|RxOK)) != RxOK) { + if (status & RxErrTooBig) + printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, " + "status %8.8x!\n", dev->name, status); + else if ( ! (status & 0x2000)) { + /* There was a fatal error. This *should* be impossible. */ + sp->stats.rx_errors++; + printk(KERN_ERR "%s: Anomalous event in speedo_rx(), " + "status %8.8x.\n", + dev->name, status); + } } else { - /* Malloc up new buffer, compatible with net-2e. */ int pkt_len = sp->rx_ringp[entry]->count & 0x3fff; struct sk_buff *skb; - int rx_in_place = 0; /* Check if the packet is long enough to just accept without copying to a properly sized skbuff. */ - if (pkt_len > rx_copybreak) { - struct sk_buff *newskb; - char *temp; - - /* Pass up the skb already on the Rx ring. */ - skb = sp->rx_skbuff[entry]; -#ifdef KERNEL_1_2 - temp = skb->data; - if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp) - printk(KERN_ERR "%s: Warning -- the skbuff addresses do not match" - " in speedo_rx: %p vs. %p / %p.\n", dev->name, - bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), - temp, skb->data); - /* Get a fresh skbuff to replace the filled one. */ - newskb = alloc_skb(PKT_BUF_SZ, GFP_ATOMIC); -#else - temp = skb_put(skb, pkt_len); - if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp) - printk(KERN_ERR "%s: Warning -- the skbuff addresses do not match" - " in speedo_rx: %8.8x vs. %p / %p.\n", dev->name, - sp->rx_ringp[entry]->rx_buf_addr, skb->head, temp); - /* Get a fresh skbuff to replace the filled one. */ - newskb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); -#endif - if (newskb) { - struct RxFD *rxf; - rx_in_place = 1; - sp->rx_skbuff[entry] = newskb; - newskb->dev = dev; -#ifdef KERNEL_1_2 - /* Restore the data in the old header region. */ - memcpy(skb->data - sizeof(struct RxFD), - &sp->saved_skhead[entry], sizeof(struct RxFD)); - /* Save the data in this header region. */ - rxf = (struct RxFD *)(newskb->data - sizeof(struct RxFD)); - sp->rx_ringp[entry] = rxf; - memcpy(&sp->saved_skhead[entry], rxf, sizeof(struct RxFD)); - rxf->rx_buf_addr = virt_to_bus(newskb->data); -#else - rxf = sp->rx_ringp[entry] = (struct RxFD *)newskb->tail; - skb_reserve(newskb, sizeof(struct RxFD)); - /* Unused by i82557, consistency check only. */ - rxf->rx_buf_addr = virt_to_bus(newskb->tail); -#endif - rxf->status = 0x00000001; - } else /* No memory, drop the packet. */ - skb = 0; - } else -#ifdef KERNEL_1_2 - skb = alloc_skb(pkt_len, GFP_ATOMIC); -#else - skb = dev_alloc_skb(pkt_len + 2); -#endif - if (skb == NULL) { - int i; - printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n", dev->name); - /* Check that at least two ring entries are free. - If not, free one and mark stats->rx_dropped++. */ - /* ToDo: This is not correct!!!! We should count the number - of linked-in Rx buffer to very that we have at least two - remaining. */ - for (i = 0; i < RX_RING_SIZE; i++) - if (! ((sp->rx_ringp[(entry+i) % RX_RING_SIZE]->status) - & RX_COMPLETE)) - break; - - if (i > RX_RING_SIZE -2) { - sp->stats.rx_dropped++; - sp->rx_ringp[entry]->status = 0; - sp->cur_rx++; - } - break; - } - skb->dev = dev; -#if (LINUX_VERSION_CODE >= VERSION(1,3,44)) - if (! rx_in_place) { - skb_reserve(skb, 2); /* 16 byte align the data fields */ -#if defined(__i386__) && notyet + if (pkt_len < rx_copybreak + && (skb = dev_alloc_skb(pkt_len + 2)) != 0) { + skb->dev = dev; + skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ + /* 'skb_put()' points to the start of sk_buff data area. */ +#if 1 || USE_IP_CSUM /* Packet is in one chunk -- we can copy + cksum. */ - eth_io_copy_and_sum(skb, bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), - pkt_len, 0); + eth_copy_and_sum(skb, + bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), + pkt_len, 0); + skb_put(skb, pkt_len); #else memcpy(skb_put(skb, pkt_len), bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), pkt_len); #endif + } else { + void *temp; + /* Pass up the already-filled skbuff. */ + skb = sp->rx_skbuff[entry]; + if (skb == NULL) { + printk(KERN_ERR "%s: Inconsistent Rx descriptor chain.\n", + dev->name); + break; + } + sp->rx_skbuff[entry] = NULL; + temp = skb_put(skb, pkt_len); + if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp) + printk(KERN_ERR "%s: Rx consistency error -- the skbuff " + "addresses do not match in speedo_rx: %p vs. %p " + "/ %p.\n", dev->name, + bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), + skb->head, temp); + sp->rx_ringp[entry] = NULL; } skb->protocol = eth_type_trans(skb, dev); -#else -#ifdef KERNEL_1_3 -#warning This code has only been tested with later 1.3.* kernels. - skb->len = pkt_len; - memcpy(skb->data, bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), - pkt_len); - /* Needed for 1.3.*. */ - skb->protocol = eth_type_trans(skb, dev); -#else /* KERNEL_1_2 */ - skb->len = pkt_len; - if (! rx_in_place) { - memcpy(skb->data, - bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), pkt_len); - } -#endif -#endif netif_rx(skb); sp->stats.rx_packets++; } + entry = (++sp->cur_rx) % RX_RING_SIZE; + } - /* ToDo: This is better than before, but should be checked. */ - { - struct RxFD *rxf = sp->rx_ringp[entry]; - rxf->status = 0xC0000003; /* '3' for verification only */ - rxf->link = 0; /* None yet. */ - rxf->count = 0; - rxf->size = PKT_BUF_SZ; - sp->last_rxf->link = virt_to_bus(rxf); - sp->last_rxf->status &= ~0xC0000000; - sp->last_rxf = rxf; - entry = (++sp->cur_rx) % RX_RING_SIZE; + /* Refill the Rx ring buffers. */ + for (; sp->dirty_rx < sp->cur_rx; sp->dirty_rx++) { + struct RxFD *rxf; + entry = sp->dirty_rx % RX_RING_SIZE; + if (sp->rx_skbuff[entry] == NULL) { + struct sk_buff *skb; + /* Get a fresh skbuff to replace the consumed one. */ + skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); + sp->rx_skbuff[entry] = skb; + if (skb == NULL) { + sp->rx_ringp[entry] = NULL; + break; /* Better luck next time! */ + } + rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail; + skb->dev = dev; + skb_reserve(skb, sizeof(struct RxFD)); + rxf->rx_buf_addr = virt_to_bus(skb->tail); + } else { + rxf = sp->rx_ringp[entry]; } + rxf->status = 0xC0000001; /* '1' for driver use only. */ + rxf->link = 0; /* None yet. */ + rxf->count = 0; + rxf->size = PKT_BUF_SZ; + sp->last_rxf->link = virt_to_bus(rxf); + sp->last_rxf->status &= ~0xC0000000; + sp->last_rxf = rxf; } sp->last_rx_time = jiffies; @@ -1428,7 +1268,7 @@ static int speedo_close(struct device *dev) { - int ioaddr = dev->base_addr; + long ioaddr = dev->base_addr; struct speedo_private *sp = (struct speedo_private *)dev->priv; int i; @@ -1454,7 +1294,7 @@ sp->rx_skbuff[i] = 0; /* Clear the Rx descriptors. */ if (skb) - dev_kfree_skb(skb); + dev_free_skb(skb); } for (i = 0; i < TX_RING_SIZE; i++) { @@ -1462,7 +1302,7 @@ sp->tx_skbuff[i] = 0; /* Clear the Tx descriptors. */ if (skb) - dev_kfree_skb(skb); + dev_free_skb(skb); } if (sp->mc_setup_frm) { kfree(sp->mc_setup_frm); @@ -1507,7 +1347,7 @@ speedo_get_stats(struct device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; - int ioaddr = dev->base_addr; + long ioaddr = dev->base_addr; if (sp->lstats.done_marker == 0xA007) { /* Previous dump finished */ sp->stats.tx_aborted_errors += sp->lstats.tx_coll16_errs; @@ -1530,11 +1370,10 @@ return &sp->stats; } -#ifdef HAVE_PRIVATE_IOCTL static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd) { struct speedo_private *sp = (struct speedo_private *)dev->priv; - int ioaddr = dev->base_addr; + long ioaddr = dev->base_addr; u16 *data = (u16 *)&rq->ifr_data; int phy = sp->phy[0] & 0x1f; @@ -1545,7 +1384,7 @@ data[3] = mdio_read(ioaddr, data[0], data[1]); return 0; case SIOCDEVPRIVATE+2: /* Write the specified MII register */ - if (!capable(CAP_NET_ADMIN)) + if (!suser()) return -EPERM; mdio_write(ioaddr, data[0], data[1], data[2]); return 0; @@ -1553,7 +1392,6 @@ return -EOPNOTSUPP; } } -#endif /* HAVE_PRIVATE_IOCTL */ /* Set or clear the multicast filter for this adaptor. This is very ugly with Intel chips -- we usually have to execute an @@ -1568,14 +1406,16 @@ set_rx_mode(struct device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; - int ioaddr = dev->base_addr; + long ioaddr = dev->base_addr; + struct descriptor *last_cmd; char new_rx_mode; unsigned long flags; int entry, i; if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ new_rx_mode = 3; - } else if (dev->flags & IFF_ALLMULTI) { + } else if ((dev->flags & IFF_ALLMULTI) || + dev->mc_count > multicast_filter_limit) { new_rx_mode = 1; } else new_rx_mode = 0; @@ -1588,57 +1428,54 @@ } if (new_rx_mode != sp->rx_mode) { - /* We must change the configuration. Construct a CmdConfig frame. */ - memcpy(sp->config_cmd_data, basic_config_cmd,sizeof(basic_config_cmd)); - sp->config_cmd_data[1] = (txfifo << 4) | rxfifo; - sp->config_cmd_data[4] = rxdmacount; - sp->config_cmd_data[5] = txdmacount + 0x80; - sp->config_cmd_data[15] = (new_rx_mode & 2) ? 0x49 : 0x48; - sp->config_cmd_data[19] = sp->full_duplex ? 0xC0 : 0x80; - sp->config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05; + u8 *config_cmd_data; + + spin_lock_irqsave(&sp->lock, flags); + entry = sp->cur_tx++ % TX_RING_SIZE; + last_cmd = sp->last_cmd; + sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; + + sp->tx_skbuff[entry] = 0; /* Redundant. */ + sp->tx_ring[entry].status = (CmdSuspend | CmdConfigure) << 16; + sp->tx_ring[entry].link = + virt_to_bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]); + config_cmd_data = (void *)&sp->tx_ring[entry].tx_desc_addr; + /* Construct a full CmdConfig frame. */ + memcpy(config_cmd_data, i82558_config_cmd, sizeof(i82558_config_cmd)); + config_cmd_data[1] = (txfifo << 4) | rxfifo; + config_cmd_data[4] = rxdmacount; + config_cmd_data[5] = txdmacount + 0x80; + config_cmd_data[15] |= (new_rx_mode & 2) ? 1 : 0; + config_cmd_data[19] |= sp->full_duplex ? 0x40 : 0; + config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05; if (sp->phy[0] & 0x8000) { /* Use the AUI port instead. */ - sp->config_cmd_data[15] |= 0x80; - sp->config_cmd_data[8] = 0; + config_cmd_data[15] |= 0x80; + config_cmd_data[8] = 0; } - save_flags(flags); - cli(); - /* Fill the "real" tx_ring frame with a no-op and point it to us. */ - entry = sp->cur_tx++ % TX_RING_SIZE; - sp->tx_skbuff[entry] = 0; /* Nothing to free. */ - sp->tx_ring[entry].status = CmdNOp << 16; - sp->tx_ring[entry].link = virt_to_bus(&sp->config_cmd); - sp->config_cmd.status = 0; - sp->config_cmd.command = CmdSuspend | CmdConfigure; - sp->config_cmd.link = - virt_to_bus(&(sp->tx_ring[sp->cur_tx % TX_RING_SIZE])); - sp->last_cmd->command &= ~CmdSuspend; - /* Immediately trigger the command unit resume. */ + /* Trigger the command unit resume. */ + last_cmd->command &= ~CmdSuspend; + wait_for_cmd_done(ioaddr + SCBCmd); outw(CU_RESUME, ioaddr + SCBCmd); - sp->last_cmd = &sp->config_cmd; - restore_flags(flags); - if (speedo_debug > 5) { - int i; - printk(KERN_DEBUG " CmdConfig frame in entry %d.\n", entry); - for(i = 0; i < 32; i++) - printk(" %2.2x", ((unsigned char *)&sp->config_cmd)[i]); - printk(".\n"); - } + + spin_unlock_irqrestore(&sp->lock, flags); } - if (new_rx_mode == 0 && dev->mc_count < 3) { - /* The simple case of 0-2 multicast list entries occurs often, and + if (new_rx_mode == 0 && dev->mc_count < 4) { + /* The simple case of 0-3 multicast list entries occurs often, and fits within one tx_ring[] entry. */ - u16 *setup_params, *eaddrs; struct dev_mc_list *mclist; + u16 *setup_params, *eaddrs; - save_flags(flags); - cli(); + spin_lock_irqsave(&sp->lock, flags); entry = sp->cur_tx++ % TX_RING_SIZE; + last_cmd = sp->last_cmd; + sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; + sp->tx_skbuff[entry] = 0; sp->tx_ring[entry].status = (CmdSuspend | CmdMulticastList) << 16; sp->tx_ring[entry].link = - virt_to_bus(&sp->tx_ring[sp->cur_tx % TX_RING_SIZE]); + virt_to_bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]); sp->tx_ring[entry].tx_desc_addr = 0; /* Really MC list count. */ setup_params = (u16 *)&sp->tx_ring[entry].tx_desc_addr; *setup_params++ = dev->mc_count*6; @@ -1651,36 +1488,42 @@ *setup_params++ = *eaddrs++; } - sp->last_cmd->command &= ~CmdSuspend; + last_cmd->command &= ~CmdSuspend; + /* Immediately trigger the command unit resume. */ wait_for_cmd_done(ioaddr + SCBCmd); outw(CU_RESUME, ioaddr + SCBCmd); - sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry]; - restore_flags(flags); + + spin_unlock_irqrestore(&sp->lock, flags); } else if (new_rx_mode == 0) { - /* This does not work correctly, but why not? */ struct dev_mc_list *mclist; - u16 *eaddrs; + u16 *setup_params, *eaddrs; struct descriptor *mc_setup_frm = sp->mc_setup_frm; - u16 *setup_params = (u16 *)mc_setup_frm->params; int i; if (sp->mc_setup_frm_len < 10 + dev->mc_count*6 || sp->mc_setup_frm == NULL) { - /* Allocate a new frame, 10bytes + addrs, with a few - extra entries for growth. */ + /* Allocate a full setup frame, 10bytes + . */ if (sp->mc_setup_frm) kfree(sp->mc_setup_frm); - sp->mc_setup_frm_len = 10 + dev->mc_count*6 + 24; + sp->mc_setup_busy = 0; + sp->mc_setup_frm_len = 10 + multicast_filter_limit*6; sp->mc_setup_frm = kmalloc(sp->mc_setup_frm_len, GFP_ATOMIC); if (sp->mc_setup_frm == NULL) { - printk(KERN_ERR "%s: Failed to allocate a setup frame.\n", dev->name); + printk(KERN_ERR "%s: Failed to allocate a setup frame.\n", + dev->name); sp->rx_mode = -1; /* We failed, try again. */ return; } } + /* If we are busy, someone might be quickly adding to the MC list. + Try again later when the list changes stop. */ + if (sp->mc_setup_busy) { + sp->rx_mode = -1; + return; + } mc_setup_frm = sp->mc_setup_frm; - /* Construct the new setup frame. */ + /* Fill the setup frame. */ if (speedo_debug > 1) printk(KERN_DEBUG "%s: Constructing a setup frame at %p, " "%d bytes.\n", @@ -1688,7 +1531,7 @@ mc_setup_frm->status = 0; mc_setup_frm->command = CmdSuspend | CmdIntr | CmdMulticastList; /* Link set below. */ - setup_params = (u16 *)mc_setup_frm->params; + setup_params = (u16 *)&mc_setup_frm->params; *setup_params++ = dev->mc_count*6; /* Fill in the multicast addresses. */ for (i = 0, mclist = dev->mc_list; i < dev->mc_count; @@ -1700,13 +1543,12 @@ } /* Disable interrupts while playing with the Tx Cmd list. */ - save_flags(flags); - cli(); - entry = sp->cur_tx++ % TX_RING_SIZE; + spin_lock_irqsave(&sp->lock, flags); - if (speedo_debug > 5) - printk(" CmdMCSetup frame length %d in entry %d.\n", - dev->mc_count, entry); + entry = sp->cur_tx++ % TX_RING_SIZE; + last_cmd = sp->last_cmd; + sp->last_cmd = mc_setup_frm; + sp->mc_setup_busy++; /* Change the command to a NoOp, pointing to the CmdMulti command. */ sp->tx_skbuff[entry] = 0; @@ -1715,41 +1557,25 @@ /* Set the link in the setup frame. */ mc_setup_frm->link = - virt_to_bus(&(sp->tx_ring[sp->cur_tx % TX_RING_SIZE])); + virt_to_bus(&(sp->tx_ring[(entry+1) % TX_RING_SIZE])); + + last_cmd->command &= ~CmdSuspend; - sp->last_cmd->command &= ~CmdSuspend; /* Immediately trigger the command unit resume. */ wait_for_cmd_done(ioaddr + SCBCmd); outw(CU_RESUME, ioaddr + SCBCmd); - sp->last_cmd = mc_setup_frm; - restore_flags(flags); - if (speedo_debug > 1) - printk(KERN_DEBUG "%s: Last command at %p is %4.4x.\n", - dev->name, sp->last_cmd, sp->last_cmd->command); + + spin_unlock_irqrestore(&sp->lock, flags); + + if (speedo_debug > 5) + printk(" CmdMCSetup frame length %d in entry %d.\n", + dev->mc_count, entry); } sp->rx_mode = new_rx_mode; } #ifdef MODULE -#if (LINUX_VERSION_CODE < VERSION(1,3,38)) /* 1.3.38 and later */ -char kernel_version[] = UTS_RELEASE; -#endif - -#if LINUX_VERSION_CODE > 0x20118 -MODULE_AUTHOR("Donald Becker "); -MODULE_DESCRIPTION("Intel i82557/i82558 EtherExpressPro driver"); -MODULE_PARM(debug, "i"); -MODULE_PARM(options, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(congenb, "i"); -MODULE_PARM(txfifo, "i"); -MODULE_PARM(rxfifo, "i"); -MODULE_PARM(txdmacount, "i"); -MODULE_PARM(rxdmacount, "i"); -MODULE_PARM(rx_copybreak, "i"); -MODULE_PARM(max_interrupt_work, "i"); -#endif int init_module(void) @@ -1796,7 +1622,8 @@ /* * Local variables: - * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c" + * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" * c-indent-level: 4 * c-basic-offset: 4 * tab-width: 4 diff -u --recursive --new-file v2.1.125/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c --- v2.1.125/linux/drivers/net/eth16i.c Thu Feb 12 20:56:08 1998 +++ linux/drivers/net/eth16i.c Fri Oct 9 11:56:59 1998 @@ -1,122 +1,207 @@ /* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux - - Written 1994-95 by Mika Kuoppala - - Copyright (C) 1994, 1995 by Mika Kuoppala - Based on skeleton.c and at1700.c by Donald Becker + + Written 1994-1998 by Mika Kuoppala + + Copyright (C) 1994-1998 by Mika Kuoppala + Based on skeleton.c and heavily on at1700.c by Donald Becker This software may be used and distributed according to the terms of the GNU Public Licence, incorporated herein by reference. - The author may be reached as miku@elt.icl.fi + The author may be reached as miku@iki.fi This driver supports following cards : - ICL EtherTeam 16i - - ICL EtherTeam 32 EISA + - ICL EtherTeam 32 EISA + (Uses true 32 bit transfers rather than 16i compability mode) + + Example Module usage: + insmod eth16i.o ioaddr=0x2a0 mediatype=bnc + + mediatype can be one of the following: bnc,tp,dix,auto,eprom + 'auto' will try to autoprobe mediatype. + 'eprom' will use whatever type defined in eprom. + + I have benchmarked driver with PII/300Mhz as a ftp client + and 486/33Mhz as a ftp server. Top speed was 1128.37 kilobytes/sec. + Sources: - skeleton.c a sample network driver core for linux, written by Donald Becker - - at1700.c a driver for Allied Telesis AT1700, written + - at1700.c a driver for Allied Telesis AT1700, written by Donald Becker. - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i written by Markku Viima - The Fujitsu MB86965 databook. - - Valuable assistance from: - Markku Viima (ICL) - Ari Valve (ICL) + + Author thanks following persons due to their valueble assistance: + Markku Viima (ICL) + Ari Valve (ICL) + Donald Becker + Kurt Huwig Revision history: Version Date Description - - 0.01 15.12-94 Initial version (card detection) + + 0.01 15.12-94 Initial version (card detection) 0.02 23.01-95 Interrupt is now hooked correctly 0.03 01.02-95 Rewrote initialization part 0.04 07.02-95 Base skeleton done... - Made a few changes to signature checking - to make it a bit reliable. - - fixed bug in tx_buf mapping - - fixed bug in initialization (DLC_EN - wasn't enabled when initialization - was done.) - 0.05 08.02-95 If there were more than one packet to send, - transmit was jammed due to invalid - register write...now fixed - 0.06 19.02-95 Rewrote interrupt handling + Made a few changes to signature checking + to make it a bit reliable. + - fixed bug in tx_buf mapping + - fixed bug in initialization (DLC_EN + wasn't enabled when initialization + was done.) + 0.05 08.02-95 If there were more than one packet to send, + transmit was jammed due to invalid + register write...now fixed + 0.06 19.02-95 Rewrote interrupt handling 0.07 13.04-95 Wrote EEPROM read routines Card configuration now set according to - data read from EEPROM + data read from EEPROM 0.08 23.06-95 Wrote part that tries to probe used interface port if AUTO is selected - 0.09 01.09-95 Added module support - - 0.10 04.09-95 Fixed receive packet allocation to work - with kernels > 1.3.x + 0.09 01.09-95 Added module support + + 0.10 04.09-95 Fixed receive packet allocation to work + with kernels > 1.3.x + + 0.20 20.09-95 Added support for EtherTeam32 EISA - 0.20 20.09-95 Added support for EtherTeam32 EISA - - 0.21 17.10-95 Removed the unnecessary extern + 0.21 17.10-95 Removed the unnecessary extern init_etherdev() declaration. Some other cleanups. + + 0.22 22.02-96 Receive buffer was not flushed + correctly when faulty packet was + received. Now fixed. + + 0.23 26.02-96 Made resetting the adapter + more reliable. + + 0.24 27.02-96 Rewrote faulty packet handling in eth16i_rx + + 0.25 22.05-96 kfree() was missing from cleanup_module. + + 0.26 11.06-96 Sometimes card was not found by + check_signature(). Now made more reliable. + + 0.27 23.06-96 Oops. 16 consecutive collisions halted + adapter. Now will try to retransmit + MAX_COL_16 times before finally giving up. + + 0.28 28.10-97 Added dev_id parameter (NULL) for free_irq + + 0.29 29.10-97 Multiple card support for module users + + 0.30 30.10-97 Fixed irq allocation bug. + (request_irq moved from probe to open) + + 0.30a 21.08-98 Card detection made more relaxed. Driver + had problems with some TCP/IP-PROM boots + to find the card. Suggested by + Kurt Huwig + + 0.31 28.08-98 Media interface port can now be selected + with module parameters or kernel + boot parameters. + + 0.32 31.08-98 IRQ was never freed if open/close + pair wasn't called. Now fixed. + + 0.33 10.09-98 When eth16i_open() was called after + eth16i_close() chip never recovered. + Now more shallow reset is made on + close. + Bugs: - In some cases the interface autoprobing code doesn't find - the correct interface type. In this case you can - manually choose the interface type in DOS with E16IC.EXE which is + In some cases the media interface autoprobing code doesn't find + the correct interface type. In this case you can + manually choose the interface type in DOS with E16IC.EXE which is configuration software for EtherTeam16i and EtherTeam32 cards. + This is also true for IRQ setting. You cannot use module + parameter to configure IRQ of the card (yet). To do: - Real multicast support + - Rewrite the media interface autoprobing code. Its _horrible_ ! + - Possibly merge all the MB86965 specific code to external + module for use by eth16.c and Donald's at1700.c + - IRQ configuration with module parameter. I will do + this when i will get enough info about setting + irq without configuration utility. */ -static char *version = - "eth16i.c: v0.21 17-10-95 Mika Kuoppala (miku@elt.icl.fi)\n"; +static char *version = + "eth16i.c: v0.33 10-09-98 Mika Kuoppala (miku@iki.fi)\n"; #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include #include #include #include -#include -#include -#include +#include +#include +#include #include -#include + +#ifndef LINUX_VERSION_CODE +#include +#endif + +#if LINUX_VERSION_CODE >= 0x20123 +#include +#else +#define __init +#define __initdata +#define __initfunc(x) x +#endif + +#if LINUX_VERSION_CODE < 0x20138 +#define test_and_set_bit(val,addr) set_bit(val,addr) +#endif + +#if LINUX_VERSION_CODE < 0x020100 +typedef struct enet_statistics eth16i_stats_type; +#else +typedef struct net_device_stats eth16i_stats_type; +#endif /* Few macros */ -#define BIT(a) ( (1 << (a)) ) -#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr))) +#define BIT(a) ( (1 << (a)) ) +#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr))) #define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr))) /* This is the I/O address space for Etherteam 16i adapter. */ -#define ETH16I_IO_EXTENT 32 +#define ETH16I_IO_EXTENT 32 /* Ticks before deciding that transmit has timed out */ -#define TIMEOUT_TICKS 30 +#define TX_TIMEOUT (400*HZ/1000) /* Maximum loop count when receiving packets */ -#define MAX_RX_LOOP 40 +#define MAX_RX_LOOP 20 /* Some interrupt masks */ -#define ETH16I_INTR_ON 0x8f82 +#define ETH16I_INTR_ON 0xef8a /* Higher is receive mask */ #define ETH16I_INTR_OFF 0x0000 - + /* Buffers header status byte meanings */ #define PKT_GOOD BIT(5) #define PKT_GOOD_RMT BIT(4) @@ -131,6 +216,7 @@ #define NET_BUSY BIT(6) #define TX_PKT_RCD BIT(5) #define CR_LOST BIT(4) +#define TX_JABBER_ERR BIT(3) #define COLLISION BIT(2) #define COLLISIONS_16 BIT(1) @@ -142,7 +228,7 @@ #define ALIGN_ERR BIT(2) #define CRC_ERR BIT(1) #define RX_BUF_OVERFLOW BIT(0) - + /* Transmit Interrupt Enable Register (DLCR2) */ #define TX_INTR_REG 2 #define TX_INTR_DONE BIT(7) @@ -181,18 +267,18 @@ #define SRAM_CYCLE_TIME_100NS BIT(6) #define SYSTEM_BUS_WIDTH_8 BIT(5) /* 1 = 8bit, 0 = 16bit */ #define BUFFER_WIDTH_8 BIT(4) /* 1 = 8bit, 0 = 16bit */ -#define TBS1 BIT(3) +#define TBS1 BIT(3) #define TBS0 BIT(2) -#define MBS1 BIT(1) /* 00=8kb, 01=16kb */ -#define MBS0 BIT(0) /* 10=32kb, 11=64kb */ +#define SRAM_BS1 BIT(1) /* 00=8kb, 01=16kb */ +#define SRAM_BS0 BIT(0) /* 10=32kb, 11=64kb */ -#ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */ -#define ETH16I_TX_BUF_SIZE 2 /* 2 = 8kb, 3 = 16kb */ -#endif -#define TX_BUF_1x2048 0 -#define TX_BUF_2x2048 1 -#define TX_BUF_2x4098 2 -#define TX_BUF_2x8192 3 +#ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */ +#define ETH16I_TX_BUF_SIZE 3 /* 2 = 8kb, 3 = 16kb */ +#endif +#define TX_BUF_1x2048 0 +#define TX_BUF_2x2048 1 +#define TX_BUF_2x4098 2 +#define TX_BUF_2x8192 3 /* Configuration Register 1 (DLCR7) */ #define CONFIG_REG_1 7 @@ -212,18 +298,21 @@ #define HASH_TABLE_RB 1 /* Buffer memory ports */ -#define BUFFER_MEM_PORT_LB 8 -#define DATAPORT BUFFER_MEM_PORT_LB -#define BUFFER_MEM_PORT_HB 9 +#define BUFFER_MEM_PORT_LB 8 +#define DATAPORT BUFFER_MEM_PORT_LB +#define BUFFER_MEM_PORT_HB 9 /* 16 Collision control register (BMPR11) */ #define COL_16_REG 11 #define HALT_ON_16 0x00 #define RETRANS_AND_HALT_ON_16 0x02 +/* Maximum number of attempts to send after 16 concecutive collisions */ +#define MAX_COL_16 10 + /* DMA Burst and Transceiver Mode Register (BMPR13) */ #define TRANSCEIVER_MODE_REG 13 -#define TRANSCEIVER_MODE_RB 2 +#define TRANSCEIVER_MODE_RB 2 #define IO_BASE_UNLOCK BIT(7) #define LOWER_SQUELCH_TRESH BIT(6) #define LINK_TEST_DISABLE BIT(5) @@ -232,9 +321,8 @@ /* Filter Self Receive Register (BMPR14) */ #define FILTER_SELF_RX_REG 14 -#define SKIP_RECEIVE_PACKET BIT(2) +#define SKIP_RX_PACKET BIT(2) #define FILTER_SELF_RECEIVE BIT(0) -#define RX_BUF_SKIP_PACKET SKIP_RECEIVE_PACKET | FILTER_SELF_RECEIVE /* EEPROM Control Register (BMPR 16) */ #define EEPROM_CTRL_REG 16 @@ -254,19 +342,20 @@ #define EEPROM_READ 0x80 /* NMC93CSx6 EEPROM Addresses */ -#define E_NODEID_0 0x02 -#define E_NODEID_1 0x03 -#define E_NODEID_2 0x04 -#define E_PORT_SELECT 0x14 - #define E_PORT_BNC 0 - #define E_PORT_DIX 1 - #define E_PORT_TP 2 - #define E_PORT_AUTO 3 -#define E_PRODUCT_CFG 0x30 - +#define E_NODEID_0 0x02 +#define E_NODEID_1 0x03 +#define E_NODEID_2 0x04 +#define E_PORT_SELECT 0x14 + #define E_PORT_BNC 0x00 + #define E_PORT_DIX 0x01 + #define E_PORT_TP 0x02 + #define E_PORT_AUTO 0x03 + #define E_PORT_FROM_EPROM 0x04 +#define E_PRODUCT_CFG 0x30 + /* Macro to slow down io between EEPROM clock transitions */ -#define eeprom_slow_io() udelay(100) /* FIXME: smaller but right value here */ +#define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { inb(0x80); }}while(0) /* Jumperless Configuration Register (BMPR19) */ #define JUMPERLESS_CONFIG 19 @@ -277,31 +366,24 @@ #define RESET ID_ROM_0 /* This is the I/O address list to be probed when seeking the card */ -static unsigned int eth16i_portlist[] __initdata = { - 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 -}; +static unsigned int eth16i_portlist[] = + { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 }; -static unsigned int eth32i_portlist[] __initdata = { - 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000, - 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 -}; +static unsigned int eth32i_portlist[] = + { 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000, + 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 }; /* This is the Interrupt lookup table for Eth16i card */ -static unsigned int eth16i_irqmap[] __initdata = { - 9, 10, 5, 15 -}; +static unsigned int eth16i_irqmap[] = { 9, 10, 5, 15, 0 }; +#define NUM_OF_ISA_IRQS 4 /* This is the Interrupt lookup table for Eth32i card */ -static unsigned int eth32i_irqmap[] __initdata = { - 3, 5, 7, 9, 10, 11, 12, 15 -}; - +static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15, 0 }; #define EISA_IRQ_REG 0xc89 +#define NUM_OF_EISA_IRQS 8 -static unsigned int eth16i_tx_buf_map[] = { - 2048, 2048, 4096, 8192 -}; -unsigned int boot = 1; +static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 }; +static unsigned int boot = 1; /* Use 0 for production, 1 for verification, >2 for debug */ #ifndef ETH16I_DEBUG @@ -310,60 +392,76 @@ static unsigned int eth16i_debug = ETH16I_DEBUG; /* Information for each board */ -struct eth16i_local -{ - struct net_device_stats stats; - unsigned int tx_started:1; - unsigned char tx_queue; /* Number of packets in transmit buffer */ - unsigned short tx_queue_len; - unsigned int tx_buf_size; - unsigned long open_time; + +struct eth16i_local { + eth16i_stats_type stats; + unsigned char tx_started; + unsigned char tx_buf_busy; + unsigned short tx_queue; /* Number of packets in transmit buffer */ + unsigned short tx_queue_len; + unsigned int tx_buf_size; + unsigned long open_time; + unsigned long tx_buffered_packets; + unsigned long col_16; }; /* Function prototypes */ -extern int eth16i_probe(struct device *dev); +extern int eth16i_probe(struct device *dev); + +static int eth16i_probe1(struct device *dev, int ioaddr); +static int eth16i_check_signature(int ioaddr); +static int eth16i_probe_port(int ioaddr); +static void eth16i_set_port(int ioaddr, int porttype); +static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l); +static int eth16i_receive_probe_packet(int ioaddr); +static int eth16i_get_irq(int ioaddr); +static int eth16i_read_eeprom(int ioaddr, int offset); +static int eth16i_read_eeprom_word(int ioaddr); +static void eth16i_eeprom_cmd(int ioaddr, unsigned char command); +static int eth16i_open(struct device *dev); +static int eth16i_close(struct device *dev); +static int eth16i_tx(struct sk_buff *skb, struct device *dev); +static void eth16i_rx(struct device *dev); +static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static void eth16i_reset(struct device *dev); +static void eth16i_skip_packet(struct device *dev); +static void eth16i_multicast(struct device *dev); +static void eth16i_select_regbank(unsigned char regbank, int ioaddr); +static void eth16i_initialize(struct device *dev); + +#if 0 +static int eth16i_set_irq(struct device *dev); +#endif + +#ifdef MODULE +static ushort eth16i_parse_mediatype(const char* s); +#endif -static int eth16i_probe1(struct device *dev, short ioaddr); -static int eth16i_check_signature(short ioaddr); -static int eth16i_probe_port(short ioaddr); -static void eth16i_set_port(short ioaddr, int porttype); -static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l); -static int eth16i_receive_probe_packet(short ioaddr); -static int eth16i_get_irq(short ioaddr); -static int eth16i_read_eeprom(int ioaddr, int offset); -static int eth16i_read_eeprom_word(int ioaddr); -static void eth16i_eeprom_cmd(int ioaddr, unsigned char command); -static int eth16i_open(struct device *dev); -static int eth16i_close(struct device *dev); -static int eth16i_tx(struct sk_buff *skb, struct device *dev); -static void eth16i_rx(struct device *dev); -static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void eth16i_multicast(struct device *dev); -static void eth16i_select_regbank(unsigned char regbank, short ioaddr); -static void eth16i_initialize(struct device *dev); -static struct net_device_stats *eth16i_get_stats(struct device *dev); +static struct enet_statistics *eth16i_get_stats(struct device *dev); static char *cardname = "ICL EtherTeam 16i/32"; -#ifdef HAVE_DEVLIST +#ifdef HAVE_DEVLIST + /* Support for alternate probe manager */ -/struct netdev_entry eth16i_drv = - {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; +/struct netdev_entry eth16i_drv = + {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; #else /* Not HAVE_DEVLIST */ + __initfunc(int eth16i_probe(struct device *dev)) { int i; int ioaddr; int base_addr = dev ? dev->base_addr : 0; + + if(eth16i_debug > 4) + printk(KERN_DEBUG "Probing started for %s\n", cardname); - if(eth16i_debug > 4) - printk("Probing started for %s\n", cardname); - - if(base_addr > 0x1ff) /* Check only single location */ + if(base_addr > 0x1ff) /* Check only single location */ return eth16i_probe1(dev, base_addr); - else if(base_addr != 0) /* Don't probe at all */ + else if(base_addr != 0) /* Don't probe at all */ return ENXIO; /* Seek card from the ISA io address space */ @@ -377,88 +475,107 @@ /* Seek card from the EISA io address space */ for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++) { if(check_region(ioaddr, ETH16I_IO_EXTENT)) - continue; + continue; if(eth16i_probe1(dev, ioaddr) == 0) - return 0; - } + return 0; + } return ENODEV; } -#endif /* Not HAVE_DEVLIST */ +#endif /* Not HAVE_DEVLIST */ -__initfunc(static int eth16i_probe1(struct device *dev, short ioaddr)) +__initfunc(static int eth16i_probe1(struct device *dev, int ioaddr)) { static unsigned version_printed = 0; - unsigned int irq = 0; - boot = 1; /* To inform initialization that we are in boot probe */ + boot = 1; /* To inform initilization that we are in boot probe */ /* - The MB86985 chip has on register which holds information in which - io address the chip lies. First read this register and compare - it to our current io address and if match then this could - be our chip. - */ + The MB86985 chip has on register which holds information in which + io address the chip lies. First read this register and compare + it to our current io address and if match then this could + be our chip. + */ if(ioaddr < 0x1000) { - if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] != ioaddr) + + if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] + != ioaddr) return -ENODEV; } /* Now we will go a bit deeper and try to find the chip's signature */ - if(eth16i_check_signature(ioaddr) != 0) /* Can we find the signature here */ + if(eth16i_check_signature(ioaddr) != 0) return -ENODEV; - /* - Now it seems that we have found an ethernet chip in this particular - ioaddr. The MB86985 chip has this feature, that when you read a - certain register it will increase its io base address to next - configurable slot. Now when we have found the chip, first thing is - to make sure that the chip's ioaddr will hold still here. - */ + /* + Now it seems that we have found a ethernet chip in this particular + ioaddr. The MB86985 chip has this feature, that when you read a + certain register it will increase it's io base address to next + configurable slot. Now when we have found the chip, first thing is + to make sure that the chip's ioaddr will hold still here. + */ eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr); outb(0x00, ioaddr + TRANSCEIVER_MODE_REG); - outb(0x00, ioaddr + RESET); /* Will reset some parts of chip */ - BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* This will disable the data link */ + outb(0x00, ioaddr + RESET); /* Reset some parts of chip */ + BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* Disable the data link */ if(dev == NULL) - dev = init_etherdev(0, sizeof(struct eth16i_local)); + dev = init_etherdev(0, 0); if( (eth16i_debug & version_printed++) == 0) - printk(version); + printk(KERN_INFO "%s", version); dev->base_addr = ioaddr; + +#if 0 + if(dev->irq) { + if(eth16i_set_irq(dev)) { + dev->irq = eth16i_get_irq(ioaddr); + } + + } + else { +#endif - irq = eth16i_get_irq(ioaddr); - dev->irq = irq; + dev->irq = eth16i_get_irq(ioaddr); /* Try to obtain interrupt vector */ - if(request_irq(dev->irq, ð16i_interrupt, 0, "eth16i", dev)) { - printk("%s: %s at %#3x, but is unusable due - conflict on IRQ %d.\n", dev->name, cardname, ioaddr, irq); - return EAGAIN; + + if (request_irq(dev->irq, (void *)ð16i_interrupt, 0, "eth16i", dev)) { + printk(KERN_WARNING "%s: %s at %#3x, but is unusable due conflicting IRQ %d.\n", + dev->name, cardname, ioaddr, dev->irq); + return -EAGAIN; } - printk("%s: %s at %#3x, IRQ %d, ", - dev->name, cardname, ioaddr, dev->irq); +#if 0 + irq2dev_map[dev->irq] = dev; +#endif + + printk(KERN_INFO "%s: %s at %#3x, IRQ %d, ", + dev->name, cardname, ioaddr, dev->irq); /* Let's grab the region */ request_region(ioaddr, ETH16I_IO_EXTENT, "eth16i"); /* Now we will have to lock the chip's io address */ eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr); - outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); + outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); - eth16i_initialize(dev); /* Initialize rest of the chip's registers */ + eth16i_initialize(dev); /* Initialize rest of the chip's registers */ /* Now let's same some energy by shutting down the chip ;) */ BITCLR(ioaddr + CONFIG_REG_1, POWERUP); /* Initialize the device structure */ - if(dev->priv == NULL) + if(dev->priv == NULL) { dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL); + if(dev->priv == NULL) + return -ENOMEM; + } + memset(dev->priv, 0, sizeof(struct eth16i_local)); dev->open = eth16i_open; @@ -478,7 +595,7 @@ static void eth16i_initialize(struct device *dev) { - short ioaddr = dev->base_addr; + int ioaddr = dev->base_addr; int i, node_w = 0; unsigned char node_byte = 0; @@ -489,11 +606,9 @@ ((unsigned short *)dev->dev_addr)[i] = ntohs(node_val); } - for(i = 0; i < 6; i++) - { + for(i = 0; i < 6; i++) { outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i); - if(boot) - { + if(boot) { printk("%02x", inb(ioaddr + NODE_ID_0 + i)); if(i != 5) printk(":"); @@ -502,14 +617,14 @@ /* Now we will set multicast addresses to accept none */ eth16i_select_regbank(HASH_TABLE_RB, ioaddr); - for(i = 0; i < 8; i++) + for(i = 0; i < 8; i++) outb(0x00, ioaddr + HASH_TABLE_0 + i); /* - Now let's disable the transmitter and receiver, set the buffer ram - cycle time, bus width and buffer data path width. Also we shall - set transmit buffer size and total buffer size. - */ + Now let's disable the transmitter and receiver, set the buffer ram + cycle time, bus width and buffer data path width. Also we shall + set transmit buffer size and total buffer size. + */ eth16i_select_regbank(2, ioaddr); @@ -519,38 +634,56 @@ if( (node_w & 0xFF00) == 0x0800) node_byte |= BUFFER_WIDTH_8; - node_byte |= MBS1; + node_byte |= SRAM_BS1; if( (node_w & 0x00FF) == 64) - node_byte |= MBS0; + node_byte |= SRAM_BS0; node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2); outb(node_byte, ioaddr + CONFIG_REG_0); /* We shall halt the transmitting, if 16 collisions are detected */ - outb(RETRANS_AND_HALT_ON_16, ioaddr + COL_16_REG); + outb(HALT_ON_16, ioaddr + COL_16_REG); - if(boot) /* Now set port type */ - { - char *porttype[] = {"BNC", "DIX", "TP", "AUTO"}; +#ifdef MODULE + /* if_port already set by init_module() */ +#else + dev->if_port = (dev->mem_start < E_PORT_FROM_EPROM) ? + dev->mem_start : E_PORT_FROM_EPROM; +#endif - ushort ptype = eth16i_read_eeprom(ioaddr, E_PORT_SELECT); - dev->if_port = (ptype & 0x00FF); + /* Set interface port type */ + if(boot) { + char *porttype[] = {"BNC", "DIX", "TP", "AUTO", "FROM_EPROM" }; - printk(" %s interface.\n", porttype[dev->if_port]); + switch(dev->if_port) + { + + case E_PORT_FROM_EPROM: + dev->if_port = eth16i_read_eeprom(ioaddr, E_PORT_SELECT); + break; + + case E_PORT_AUTO: + dev->if_port = eth16i_probe_port(ioaddr); + break; + + case E_PORT_BNC: + case E_PORT_TP: + case E_PORT_DIX: + break; + } - if(ptype == E_PORT_AUTO) - ptype = eth16i_probe_port(ioaddr); + printk(" %s interface.\n", porttype[dev->if_port]); - eth16i_set_port(ioaddr, ptype); + eth16i_set_port(ioaddr, dev->if_port); } /* Set Receive Mode to normal operation */ outb(MODE_2, ioaddr + RECEIVE_MODE_REG); } -static int eth16i_probe_port(short ioaddr) +static int eth16i_probe_port(int ioaddr) { int i; int retcode; @@ -579,136 +712,163 @@ eth16i_set_port(ioaddr, i); if(eth16i_debug > 1) - printk("Set port number %d\n", i); + printk(KERN_DEBUG "Set port number %d\n", i); retcode = eth16i_send_probe_packet(ioaddr, dummy_packet, 64); - if(retcode == 0) - { + if(retcode == 0) { retcode = eth16i_receive_probe_packet(ioaddr); - if(retcode != -1) - { + if(retcode != -1) { if(eth16i_debug > 1) - printk("Eth16i interface port found at %d\n", i); + printk(KERN_DEBUG "Eth16i interface port found at %d\n", i); return i; } } else { if(eth16i_debug > 1) - printk("TRANSMIT_DONE timeout\n"); + printk(KERN_DEBUG "TRANSMIT_DONE timeout when probing interface port\n"); } } if( eth16i_debug > 1) - printk("Using default port\n"); + printk(KERN_DEBUG "Using default port\n"); return E_PORT_BNC; } -static void eth16i_set_port(short ioaddr, int porttype) -{ +static void eth16i_set_port(int ioaddr, int porttype) +{ unsigned short temp = 0; eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr); outb(LOOPBACK_CONTROL, ioaddr + TRANSMIT_MODE_REG); temp |= DIS_AUTO_PORT_SEL; - switch(porttype) - { - case E_PORT_BNC : - temp |= AUI_SELECT; - break; + switch(porttype) { - case E_PORT_TP : - break; + case E_PORT_BNC : + temp |= AUI_SELECT; + break; + + case E_PORT_TP : + break; + + case E_PORT_DIX : + temp |= AUI_SELECT; + BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT); + break; + } - case E_PORT_DIX : - temp |= AUI_SELECT; - BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT); - break; - } outb(temp, ioaddr + TRANSCEIVER_MODE_REG); if(eth16i_debug > 1) { - printk("TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG)); - printk("TRANSCEIVER_MODE_REG = %x\n", inb(ioaddr+TRANSCEIVER_MODE_REG)); + printk(KERN_DEBUG "TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG)); + printk(KERN_DEBUG "TRANSCEIVER_MODE_REG = %x\n", + inb(ioaddr+TRANSCEIVER_MODE_REG)); } } -static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l) +static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l) { int starttime; outb(0xff, ioaddr + TX_STATUS_REG); outw(l, ioaddr + DATAPORT); - outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1); + outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1); starttime = jiffies; - outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); + outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); - while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) - if( (jiffies - starttime) > TIMEOUT_TICKS) - break; - return(0); + while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) { + if( (jiffies - starttime) > TX_TIMEOUT) { + return -1; + } + } + + return 0; } -static int eth16i_receive_probe_packet(short ioaddr) +static int eth16i_receive_probe_packet(int ioaddr) { int starttime; starttime = jiffies; - while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) - { - if( (jiffies - starttime) > TIMEOUT_TICKS) - { + while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) { + if( (jiffies - starttime) > TX_TIMEOUT) { + if(eth16i_debug > 1) - printk("Timeout occurred waiting transmit packet received\n"); + printk(KERN_DEBUG "Timeout occured waiting transmit packet received\n"); starttime = jiffies; - while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) - { - if( (jiffies - starttime) > TIMEOUT_TICKS) - { + while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) { + if( (jiffies - starttime) > TX_TIMEOUT) { if(eth16i_debug > 1) - printk("Timeout occurred waiting receive packet\n"); + printk(KERN_DEBUG "Timeout occured waiting receive packet\n"); return -1; } } if(eth16i_debug > 1) - printk("RECEIVE_PACKET\n"); + printk(KERN_DEBUG "RECEIVE_PACKET\n"); return(0); /* Found receive packet */ } } if(eth16i_debug > 1) { - printk("TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG)); - printk("RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG)); + printk(KERN_DEBUG "TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG)); + printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG)); } return(0); /* Return success */ } -static int eth16i_get_irq(short ioaddr) +#if 0 +static int eth16i_set_irq(struct device* dev) +{ + const int ioaddr = dev->base_addr; + const int irq = dev->irq; + int i = 0; + + if(ioaddr < 0x1000) { + while(eth16i_irqmap[i] && eth16i_irqmap[i] != irq) + i++; + + if(i < NUM_OF_ISA_IRQS) { + u8 cbyte = inb(ioaddr + JUMPERLESS_CONFIG); + cbyte = (cbyte & 0x3F) | (i << 6); + outb(cbyte, ioaddr + JUMPERLESS_CONFIG); + return 0; + } + } + else { + printk(KERN_NOTICE "%s: EISA Interrupt cannot be set. Use EISA Configuration utility.\n", dev->name); + } + + return -1; + +} +#endif + +static int eth16i_get_irq(int ioaddr) { unsigned char cbyte; if( ioaddr < 0x1000) { cbyte = inb(ioaddr + JUMPERLESS_CONFIG); - return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] ); - } else { /* Oh..the card is EISA so method getting IRQ different */ - unsigned short index = 0; - cbyte = inb(ioaddr + EISA_IRQ_REG); - while( (cbyte & 0x01) == 0) { - cbyte = cbyte >> 1; - index++; - } - return( eth32i_irqmap[ index ] ); + return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] ); + } else { /* Oh..the card is EISA so method getting IRQ different */ + unsigned short index = 0; + cbyte = inb(ioaddr + EISA_IRQ_REG); + while( (cbyte & 0x01) == 0) { + cbyte = cbyte >> 1; + index++; + } + return( eth32i_irqmap[ index ] ); } } -static int eth16i_check_signature(short ioaddr) +static int eth16i_check_signature(int ioaddr) { int i; unsigned char creg[4] = { 0 }; @@ -718,36 +878,37 @@ creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i); if(eth16i_debug > 1) - printk("eth16i: read signature byte %x at %x\n", creg[i], - ioaddr + TRANSMIT_MODE_REG + i); + printk("eth16i: read signature byte %x at %x\n", + creg[i], + ioaddr + TRANSMIT_MODE_REG + i); } creg[0] &= 0x0F; /* Mask collision cnr */ creg[2] &= 0x7F; /* Mask DCLEN bit */ -#if 0 -/* - This was removed because the card was sometimes left to state - from which it couldn't be find anymore. If there is need - to have a more strict check still this have to be fixed. -*/ - if( !( (creg[0] == 0x06) && (creg[1] == 0x41)) ) { +#ifdef 0 + /* + This was removed because the card was sometimes left to state + from which it couldn't be find anymore. If there is need + to more strict check still this have to be fixed. + */ + if( ! ((creg[0] == 0x06) && (creg[1] == 0x41)) ) { if(creg[1] != 0x42) return -1; } #endif - if( !( (creg[2] == 0x36) && (creg[3] == 0xE0)) ) - { - creg[2] &= 0x42; + if( !((creg[2] == 0x36) && (creg[3] == 0xE0)) ) { + creg[2] &= 0x40; creg[3] &= 0x03; - - if( !( (creg[2] == 0x42) && (creg[3] == 0x00)) ) + + if( !((creg[2] == 0x40) && (creg[3] == 0x00)) ) return -1; } - + if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0) return -1; + if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00) return -1; @@ -763,20 +924,22 @@ data = eth16i_read_eeprom_word(ioaddr); outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG); - return(data); + return(data); } static int eth16i_read_eeprom_word(int ioaddr) { int i; int data = 0; - + for(i = 16; i > 0; i--) { outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG); eeprom_slow_io(); outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG); eeprom_slow_io(); - data = (data << 1) | ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0); + data = (data << 1) | + ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0); + eeprom_slow_io(); } @@ -800,25 +963,26 @@ eeprom_slow_io(); outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG); eeprom_slow_io(); - } + } } static int eth16i_open(struct device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; - + /* Powerup the chip */ outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1); /* Initialize the chip */ - eth16i_initialize(dev); + eth16i_initialize(dev); /* Set the transmit buffer size */ lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03]; - if(eth16i_debug > 3) - printk("%s: transmit buffer size %d\n", dev->name, lp->tx_buf_size); + if(eth16i_debug > 0) + printk(KERN_DEBUG "%s: transmit buffer size %d\n", + dev->name, lp->tx_buf_size); /* Now enable Transmitter and Receiver sections */ BITCLR(ioaddr + CONFIG_REG_0, DLC_EN); @@ -832,15 +996,13 @@ lp->tx_queue_len = 0; /* Turn on interrupts*/ - outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); + outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; -#ifdef MODULE MOD_INC_USE_COUNT; -#endif return 0; } @@ -850,23 +1012,26 @@ struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; - lp->open_time = 0; + eth16i_reset(dev); + + /* Turn off interrupts*/ + outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); - dev->tbusy = 1; dev->start = 0; + dev->tbusy = 1; + + lp->open_time = 0; /* Disable transmit and receive */ BITSET(ioaddr + CONFIG_REG_0, DLC_EN); /* Reset the chip */ - outb(0xff, ioaddr + RESET); + /* outb(0xff, ioaddr + RESET); */ + /* outw(0xffff, ioaddr + TX_STATUS_REG); */ + + outb(0x00, ioaddr + CONFIG_REG_1); - /* Save some energy by switching off power */ - BITCLR(ioaddr + CONFIG_REG_1, POWERUP); - -#ifdef MODULE MOD_DEC_USE_COUNT; -#endif return 0; } @@ -875,88 +1040,120 @@ { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; int ioaddr = dev->base_addr; + int status = 0; if(dev->tbusy) { - /* - If we get here, some higher level has decided that we are broken. - There should really be a "kick me" function call instead. - */ + + /* + If we get here, some higher level has decided that + we are broken. There should really be a "kick me" + function call instead. + */ int tickssofar = jiffies - dev->trans_start; - if(tickssofar < TIMEOUT_TICKS) /* Let's not rush with our timeout, */ - return 1; /* wait a couple of ticks first */ + if(tickssofar < TX_TIMEOUT) + return 1; - printk("%s: transmit timed out with status %04x, %s ?\n", dev->name, - inw(ioaddr + TX_STATUS_REG), - (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ? - "IRQ conflict" : "network cable problem"); + outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); - /* Let's dump all registers */ - if(eth16i_debug > 0) { - printk("%s: timeout regs: %02x %02x %02x %02x %02x %02x %02x %02x.\n", - dev->name, inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2), - inb(ioaddr + 3), inb(ioaddr + 4), inb(ioaddr + 5), - inb(ioaddr + 6), inb(ioaddr + 7)); + printk(KERN_WARNING "%s: transmit timed out with status %04x, %s ?\n", + dev->name, + inw(ioaddr + TX_STATUS_REG), + (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ? + "IRQ conflict" : "network cable problem"); + dev->trans_start = jiffies; - printk("lp->tx_queue = %d\n", lp->tx_queue); - printk("lp->tx_queue_len = %d\n", lp->tx_queue_len); - printk("lp->tx_started = %d\n", lp->tx_started); + /* Let's dump all registers */ + if(eth16i_debug > 0) { + printk(KERN_DEBUG "%s: timeout: %02x %02x %02x %02x %02x %02x %02x %02x.\n", + dev->name, inb(ioaddr + 0), + inb(ioaddr + 1), inb(ioaddr + 2), + inb(ioaddr + 3), inb(ioaddr + 4), + inb(ioaddr + 5), + inb(ioaddr + 6), inb(ioaddr + 7)); + + printk(KERN_DEBUG "%s: transmit start reg: %02x. collision reg %02x\n", + dev->name, inb(ioaddr + TRANSMIT_START_REG), + inb(ioaddr + COL_16_REG)); + + printk(KERN_DEBUG "lp->tx_queue = %d\n", lp->tx_queue); + printk(KERN_DEBUG "lp->tx_queue_len = %d\n", lp->tx_queue_len); + printk(KERN_DEBUG "lp->tx_started = %d\n", lp->tx_started); } lp->stats.tx_errors++; - /* Now let's try to restart the adaptor */ - - BITSET(ioaddr + CONFIG_REG_0, DLC_EN); - outw(0xffff, ioaddr + RESET); - eth16i_initialize(dev); - outw(0xffff, ioaddr + TX_STATUS_REG); - BITCLR(ioaddr + CONFIG_REG_0, DLC_EN); + eth16i_reset(dev); - lp->tx_started = 0; - lp->tx_queue = 0; - lp->tx_queue_len = 0; + dev->trans_start = jiffies; outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); - dev->tbusy = 0; - dev->trans_start = jiffies; } - /* Block a timer based transmitter from overlapping. This could better be - done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ + /* + If some higher layer thinks we've missed an tx-done interrupt + we are passed NULL. Caution: dev_tint() handles the cli()/sti() + itself + */ + + if(skb == NULL) { +#if LINUX_VERSION_CODE < 0x020100 + dev_tint(dev); +#endif + if(eth16i_debug > 0) + printk(KERN_WARNING "%s: Missed tx-done interrupt.\n", dev->name); + return 0; + } + + /* Block a timer based transmitter from overlapping. + This could better be done with atomic_swap(1, dev->tbusy), + but set_bit() works as well. */ + set_bit(0, (void *)&lp->tx_buf_busy); + /* Turn off TX interrupts */ outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); - if(test_and_set_bit(0, (void *)&dev->tbusy) != 0) - printk("%s: Transmitter access conflict.\n", dev->name); + if(test_and_set_bit(0, (void *)&dev->tbusy) != 0) { + printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name); + status = -1; + } else { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + ushort length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; - outw(length, ioaddr + DATAPORT); - - if( ioaddr < 0x1000 ) - outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1); - else - { - unsigned char frag = length % 4; - - outsl(ioaddr + DATAPORT, buf, length >> 2); + if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) { + if(eth16i_debug > 0) + printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name); + } + else { + outw(length, ioaddr + DATAPORT); - if( frag != 0 ) - { - outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1); - if( frag == 3 ) - outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC) + 2), 1); + if( ioaddr < 0x1000 ) + outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1); + else { + unsigned char frag = length % 4; + + outsl(ioaddr + DATAPORT, buf, length >> 2); + + if( frag != 0 ) { + outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1); + if( frag == 3 ) + outsw(ioaddr + DATAPORT, + (buf + (length & 0xFFFC) + 2), 1); + } } - } - lp->tx_queue++; - lp->tx_queue_len += length + 2; + lp->tx_buffered_packets++; + lp->tx_queue++; + lp->tx_queue_len += length + 2; + + } + + lp->tx_buf_busy = 0; if(lp->tx_started == 0) { /* If the transmitter is idle..always trigger a transmit */ @@ -971,15 +1168,21 @@ /* There is still more room for one more packet in tx buffer */ dev->tbusy = 0; } - + outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); - + /* Turn TX interrupts back on */ /* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */ - } + status = 0; + } + +#if LINUX_VERSION_CODE >= 0x020100 dev_kfree_skb(skb); +#else + dev_kfree_skb(skb, FREE_WRITE); +#endif - return 0; + return status; } static void eth16i_rx(struct device *dev) @@ -989,71 +1192,63 @@ int boguscount = MAX_RX_LOOP; /* Loop until all packets have been read */ - while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) - { - /* Read status byte from receive buffer */ + while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) { + + /* Read status byte from receive buffer */ ushort status = inw(ioaddr + DATAPORT); - if(eth16i_debug > 4) - printk("%s: Receiving packet mode %02x status %04x.\n", - dev->name, inb(ioaddr + RECEIVE_MODE_REG), status); + /* Get the size of the packet from receive buffer */ + ushort pkt_len = inw(ioaddr + DATAPORT); - if( !(status & PKT_GOOD) ) - { - /* Hmm..something went wrong. Let's check what error occurred */ + if(eth16i_debug > 4) + printk(KERN_DEBUG "%s: Receiving packet mode %02x status %04x.\n", + dev->name, + inb(ioaddr + RECEIVE_MODE_REG), status); + + if( !(status & PKT_GOOD) ) { lp->stats.rx_errors++; - if( status & PKT_SHORT) + + if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) { lp->stats.rx_length_errors++; - if( status & PKT_ALIGN_ERR ) - lp->stats.rx_frame_errors++; - if( status & PKT_CRC_ERR ) - lp->stats.rx_crc_errors++; - if( status & PKT_RX_BUF_OVERFLOW) - lp->stats.rx_over_errors++; + eth16i_reset(dev); + return; + } + else { + eth16i_skip_packet(dev); + lp->stats.rx_dropped++; + } } - else - { /* Ok so now we should have a good packet */ + else { /* Ok so now we should have a good packet */ struct sk_buff *skb; - /* Get the size of the packet from receive buffer */ - ushort pkt_len = inw(ioaddr + DATAPORT); - - if(pkt_len > ETH_FRAME_LEN) - { - printk("%s: %s claimed a very large packet, size of %d bytes.\n", - dev->name, cardname, pkt_len); - outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG); - lp->stats.rx_dropped++; - break; - } skb = dev_alloc_skb(pkt_len + 3); - if( skb == NULL ) - { - printk("%s: Couldn't allocate memory for packet (len %d)\n", - dev->name, pkt_len); - outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG); + if( skb == NULL ) { + printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n", + dev->name, pkt_len); + eth16i_skip_packet(dev); lp->stats.rx_dropped++; break; } + skb->dev = dev; skb_reserve(skb,2); - /* - Now let's get the packet out of buffer. - size is (pkt_len + 1) >> 1, cause we are now reading words - and it has to be even aligned. - */ - - if( ioaddr < 0x1000) - insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), (pkt_len + 1) >> 1); - else - { + + /* + Now let's get the packet out of buffer. + size is (pkt_len + 1) >> 1, cause we are now reading words + and it have to be even aligned. + */ + + if(ioaddr < 0x1000) + insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), + (pkt_len + 1) >> 1); + else { unsigned char *buf = skb_put(skb, pkt_len); unsigned char frag = pkt_len % 4; insl(ioaddr + DATAPORT, buf, pkt_len >> 2); - if(frag != 0) - { + if(frag != 0) { unsigned short rest[2]; rest[0] = inw( ioaddr + DATAPORT ); if(frag == 3) @@ -1067,13 +1262,13 @@ netif_rx(skb); lp->stats.rx_packets++; - if( eth16i_debug > 5 ) - { + if( eth16i_debug > 5 ) { int i; - printk("%s: Received packet of length %d.\n", dev->name, pkt_len); - for(i = 0; i < 14; i++) - printk(" %02x", skb->data[i]); - printk(".\n"); + printk(KERN_DEBUG "%s: Received packet of length %d.\n", + dev->name, pkt_len); + for(i = 0; i < 14; i++) + printk(KERN_DEBUG " %02x", skb->data[i]); + printk(KERN_DEBUG ".\n"); } } /* else */ @@ -1087,16 +1282,16 @@ { int i; - for(i = 0; i < 20; i++) - { - if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == RX_BUFFER_EMPTY) + for(i = 0; i < 20; i++) { + if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == + RX_BUFFER_EMPTY) break; inw(ioaddr + DATAPORT); - outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG); + outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG); } if(eth16i_debug > 1) - printk("%s: Flushed receive buffer.\n", dev->name); + printk(KERN_DEBUG "%s: Flushed receive buffer.\n", dev->name); } #endif @@ -1108,126 +1303,302 @@ struct device *dev = dev_id; struct eth16i_local *lp; int ioaddr = 0, - status; + status; if(dev == NULL) { - printk("eth16i_interrupt(): irq %d for unknown device. \n", irq); + printk(KERN_WARNING "eth16i_interrupt(): irq %d for unknown device. \n", irq); return; } /* Turn off all interrupts from adapter */ outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); + set_bit(0, (void *)&dev->tbusy); /* Set the device busy so that */ + /* eth16i_tx wont be called */ + + if(dev->interrupt) + printk(KERN_WARNING "%s: Re-entering the interrupt handler.\n", dev->name); dev->interrupt = 1; ioaddr = dev->base_addr; lp = (struct eth16i_local *)dev->priv; - status = inw(ioaddr + TX_STATUS_REG); /* Get the status */ - outw(status, ioaddr + TX_STATUS_REG); /* Clear status bits */ + status = inw(ioaddr + TX_STATUS_REG); /* Get the status */ + outw(status, ioaddr + TX_STATUS_REG); /* Clear status bits */ if(eth16i_debug > 3) - printk("%s: Interrupt with status %04x.\n", dev->name, status); + printk(KERN_DEBUG "%s: Interrupt with status %04x.\n", dev->name, status); + + if( status & 0x7f00 ) { + + lp->stats.rx_errors++; + + if(status & (BUS_RD_ERR << 8) ) + printk(KERN_WARNING "%s: Bus read error.\n",dev->name); + if(status & (SHORT_PKT_ERR << 8) ) lp->stats.rx_length_errors++; + if(status & (ALIGN_ERR << 8) ) lp->stats.rx_frame_errors++; + if(status & (CRC_ERR << 8) ) lp->stats.rx_crc_errors++; + if(status & (RX_BUF_OVERFLOW << 8) ) lp->stats.rx_over_errors++; + } + if( status & 0x001a) { + + lp->stats.tx_errors++; + + if(status & CR_LOST) lp->stats.tx_carrier_errors++; + if(status & TX_JABBER_ERR) lp->stats.tx_window_errors++; - if( status & 0x00ff ) { /* Let's check the transmit status reg */ - if(status & TX_DONE) - { /* The transmit has been done */ - lp->stats.tx_packets++; - if(lp->tx_queue) - { /* Are there still packets ? */ +#if 0 + if(status & COLLISION) { + lp->stats.collisions += + ((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4); + } +#endif + if(status & COLLISIONS_16) { + if(lp->col_16 < MAX_COL_16) { + lp->col_16++; + lp->stats.collisions++; + /* Resume transmitting, skip failed packet */ + outb(0x02, ioaddr + COL_16_REG); + } + else { + printk(KERN_WARNING "%s: bailing out due to many consecutive 16-in-a-row collisions. Network cable problem?\n", dev->name); + } + } + } + + if( status & 0x00ff ) { /* Let's check the transmit status reg */ + + if(status & TX_DONE) { /* The transmit has been done */ + lp->stats.tx_packets = lp->tx_buffered_packets; + lp->col_16 = 0; + + if(lp->tx_queue) { /* Is there still packets ? */ /* There was packet(s) so start transmitting and write also - how many packets there is to be sent */ + how many packets there is to be sended */ outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG); lp->tx_queue = 0; lp->tx_queue_len = 0; + lp->tx_started = 1; dev->trans_start = jiffies; - dev->tbusy = 0; - mark_bh(NET_BH); + mark_bh(NET_BH); } - else - { + else { lp->tx_started = 0; - dev->tbusy = 0; mark_bh(NET_BH); } } } - if( ( status & 0xff00 ) || - ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) { - eth16i_rx(dev); /* We have packet in receive buffer */ - } - + if( ( status & 0x8000 ) || + ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) { + eth16i_rx(dev); /* We have packet in receive buffer */ + } + dev->interrupt = 0; - + /* Turn interrupts back on */ outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG); - + + if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) { + /* There is still more room for one more packet in tx buffer */ + dev->tbusy = 0; + } + return; } -static void eth16i_multicast(struct device *dev) +static void eth16i_skip_packet(struct device *dev) +{ + int ioaddr = dev->base_addr; + + inw(ioaddr + DATAPORT); + inw(ioaddr + DATAPORT); + inw(ioaddr + DATAPORT); + + outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG); + while( inb( ioaddr + FILTER_SELF_RX_REG ) != 0); +} + +static void eth16i_reset(struct device *dev) { - short ioaddr = dev->base_addr; + struct eth16i_local *lp = (struct eth16i_local *)dev->priv; + int ioaddr = dev->base_addr; + + if(eth16i_debug > 1) + printk(KERN_DEBUG "%s: Resetting device.\n", dev->name); + + BITSET(ioaddr + CONFIG_REG_0, DLC_EN); + outw(0xffff, ioaddr + TX_STATUS_REG); + eth16i_select_regbank(2, ioaddr); + + lp->tx_started = 0; + lp->tx_buf_busy = 0; + lp->tx_queue = 0; + lp->tx_queue_len = 0; + + dev->interrupt = 0; + dev->start = 1; + dev->tbusy = 0; + BITCLR(ioaddr + CONFIG_REG_0, DLC_EN); +} - if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) +static void eth16i_multicast(struct device *dev) +{ + int ioaddr = dev->base_addr; + + if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) { dev->flags|=IFF_PROMISC; /* Must do this */ - outb(3, ioaddr + RECEIVE_MODE_REG); + outb(3, ioaddr + RECEIVE_MODE_REG); } else { outb(2, ioaddr + RECEIVE_MODE_REG); } } -static struct net_device_stats *eth16i_get_stats(struct device *dev) +static struct enet_statistics *eth16i_get_stats(struct device *dev) { struct eth16i_local *lp = (struct eth16i_local *)dev->priv; return &lp->stats; } -static void eth16i_select_regbank(unsigned char banknbr, short ioaddr) +static void eth16i_select_regbank(unsigned char banknbr, int ioaddr) { unsigned char data; data = inb(ioaddr + CONFIG_REG_1); - outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1); + outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1); } #ifdef MODULE -static char devicename[9] = { 0, }; -static struct device dev_eth16i = { - devicename, - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, eth16i_probe + +static ushort eth16i_parse_mediatype(const char* s) +{ + if(!s) + return E_PORT_FROM_EPROM; + + if (!strncmp(s, "bnc", 3)) + return E_PORT_BNC; + else if (!strncmp(s, "tp", 2)) + return E_PORT_TP; + else if (!strncmp(s, "dix", 3)) + return E_PORT_DIX; + else if (!strncmp(s, "auto", 4)) + return E_PORT_AUTO; + else + return E_PORT_FROM_EPROM; +} + +#define MAX_ETH16I_CARDS 4 /* Max number of Eth16i cards per module */ +#define NAMELEN 8 /* number of chars for storing dev->name */ + +static char namelist[NAMELEN * MAX_ETH16I_CARDS] = { 0, }; +static struct device dev_eth16i[MAX_ETH16I_CARDS] = { + { + NULL, + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, NULL + }, }; -int io = 0x2a0; -int irq = 0; +static int ioaddr[MAX_ETH16I_CARDS] = { 0, }; +#if 0 +static int irq[MAX_ETH16I_CARDS] = { 0, }; +#endif +static char* mediatype[MAX_ETH16I_CARDS] = { 0, }; +static int debug = -1; -MODULE_PARM(io, "i"); -MODULE_PARM(irq, "i"); +#if (LINUX_VERSION_CODE >= 0x20115) +MODULE_AUTHOR("Mika Kuoppala "); +MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver"); + +MODULE_PARM(ioaddr, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i"); +MODULE_PARM_DESC(ioaddr, "eth16i io base address"); + +#if 0 +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i"); +MODULE_PARM_DESC(irq, "eth16i interrupt request number"); +#endif + +MODULE_PARM(mediatype, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "s"); +MODULE_PARM_DESC(mediatype, "eth16i interfaceport mediatype"); + +MODULE_PARM(debug, "i"); +MODULE_PARM_DESC(debug, "eth16i debug level (0-4)"); +#endif int init_module(void) { - if(io == 0) - printk("eth16i: You should not use auto-probing with insmod!\n"); + int this_dev, found = 0; - dev_eth16i.base_addr = io; - dev_eth16i.irq = irq; - if( register_netdev( &dev_eth16i ) != 0 ) { - printk("eth16i: register_netdev() returned non-zero.\n"); - return -EIO; - } + for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) + { + struct device *dev = &dev_eth16i[this_dev]; + + dev->name = namelist + (NAMELEN*this_dev); + dev->irq = 0; /* irq[this_dev]; */ + dev->base_addr = ioaddr[this_dev]; + dev->init = eth16i_probe; + + if(debug != -1) + eth16i_debug = debug; + + if(eth16i_debug > 1) + printk(KERN_NOTICE "eth16i(%d): interface type %s\n", this_dev, mediatype[this_dev] ? mediatype[this_dev] : "none" ); + dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]); + + if(ioaddr[this_dev] == 0) + { + if(this_dev != 0) break; /* Only autoprobe 1st one */ + + printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n"); + } + + if(register_netdev(dev) != 0) + { + printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n", + ioaddr[this_dev]); + + if(found != 0) return 0; + return -ENXIO; + } + + found++; + } return 0; } - + void cleanup_module(void) { - unregister_netdev( &dev_eth16i ); - free_irq( dev_eth16i.irq, &dev_eth16i ); - release_region( dev_eth16i.base_addr, ETH16I_IO_EXTENT ); -} + int this_dev; + for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) + { + struct device* dev = &dev_eth16i[this_dev]; + + if(dev->priv != NULL) + { + unregister_netdev(dev); + kfree(dev->priv); + dev->priv = NULL; + + free_irq(dev->irq, dev); + release_region(dev->base_addr, ETH16I_IO_EXTENT); + + } + } +} #endif /* MODULE */ + +/* + * Local variables: + * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c eth16i.c" + * alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict -prototypes -O6 -c eth16i.c" + * tab-width: 8 + * c-basic-offset: 8 + * c-indent-level: 8 + * End: + */ + +/* End of file eth16i.c */ diff -u --recursive --new-file v2.1.125/linux/drivers/net/ethertap.c linux/drivers/net/ethertap.c --- v2.1.125/linux/drivers/net/ethertap.c Fri Oct 9 13:27:09 1998 +++ linux/drivers/net/ethertap.c Fri Oct 23 08:12:32 1998 @@ -329,7 +329,7 @@ #ifdef MODULE -int unit; +static int unit; MODULE_PARM(unit,"i"); static char devicename[9] = { 0, }; diff -u --recursive --new-file v2.1.125/linux/drivers/net/hamradio/baycom_epp.c linux/drivers/net/hamradio/baycom_epp.c --- v2.1.125/linux/drivers/net/hamradio/baycom_epp.c Tue Jul 21 00:15:31 1998 +++ linux/drivers/net/hamradio/baycom_epp.c Fri Oct 9 12:20:27 1998 @@ -1010,14 +1010,6 @@ /* --------------------------------------------------------------------- */ -static int epp_preempt(void *handle) -{ - /* we cannot relinquish the port in the middle of an operation */ - return 1; -} - -/* --------------------------------------------------------------------- */ - static void epp_wakeup(void *handle) { struct device *dev = (struct device *)handle; @@ -1070,8 +1062,8 @@ } #endif memset(&bc->modem, 0, sizeof(bc->modem)); - if (!(bc->pdev = parport_register_device(pp, dev->name, epp_preempt, epp_wakeup, - epp_interrupt, PARPORT_DEV_LURK, dev))) { + if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup, + epp_interrupt, PARPORT_DEV_EXCL, dev))) { printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base); return -ENXIO; } diff -u --recursive --new-file v2.1.125/linux/drivers/net/hamradio/baycom_par.c linux/drivers/net/hamradio/baycom_par.c --- v2.1.125/linux/drivers/net/hamradio/baycom_par.c Tue Jun 9 11:57:29 1998 +++ linux/drivers/net/hamradio/baycom_par.c Fri Oct 9 12:20:27 1998 @@ -357,14 +357,6 @@ /* --------------------------------------------------------------------- */ -static int par96_preempt(void *handle) -{ - /* we cannot relinquish the port in the middle of an operation */ - return 1; -} - -/* --------------------------------------------------------------------- */ - static void par96_wakeup(void *handle) { struct device *dev = (struct device *)handle; @@ -396,8 +388,8 @@ } memset(&bc->modem, 0, sizeof(bc->modem)); bc->hdrv.par.bitrate = 9600; - if (!(bc->pdev = parport_register_device(pp, dev->name, par96_preempt, par96_wakeup, - par96_interrupt, PARPORT_DEV_LURK, dev))) { + if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, par96_wakeup, + par96_interrupt, PARPORT_DEV_EXCL, dev))) { printk(KERN_ERR "baycom_par: cannot register parport at 0x%lx\n", pp->base); return -ENXIO; } diff -u --recursive --new-file v2.1.125/linux/drivers/net/hamradio/dmascc.c linux/drivers/net/hamradio/dmascc.c --- v2.1.125/linux/drivers/net/hamradio/dmascc.c Thu Sep 17 17:53:36 1998 +++ linux/drivers/net/hamradio/dmascc.c Fri Oct 9 11:56:59 1998 @@ -966,6 +966,7 @@ { struct scc_priv *priv = dev->priv; int cb, cmd = priv->cmd; + unsigned long flags; /* See Figure 2-15. Only overrun and EOF need to be checked. */ @@ -976,9 +977,12 @@ } else if (rc & END_FR) { /* End of frame. Get byte count */ if (dev->dma) { + flags=claim_dma_lock(); disable_dma(dev->dma); clear_dma_ff(dev->dma); cb = BUF_SIZE - get_dma_residue(dev->dma) - 2; + release_dma_lock(flags); + } else { cb = priv->rx_ptr - 2; } @@ -1013,9 +1017,13 @@ } /* Get ready for new frame */ if (dev->dma) { + + flags=claim_dma_lock(); set_dma_addr(dev->dma, (int) priv->rx_buf[priv->rx_head]); set_dma_count(dev->dma, BUF_SIZE); enable_dma(dev->dma); + release_dma_lock(flags); + } else { priv->rx_ptr = 0; } @@ -1102,6 +1110,7 @@ struct scc_info *info = priv->info; int i, cmd = priv->cmd; int st, dst, res; + unsigned long flags; /* Read status and reset interrupt bit */ st = read_scc(cmd, R0); @@ -1118,9 +1127,11 @@ /* Get remaining bytes */ i = priv->tx_tail; if (dev->dma) { + flags=claim_dma_lock(); disable_dma(dev->dma); clear_dma_ff(dev->dma); res = get_dma_residue(dev->dma); + release_dma_lock(flags); } else { res = priv->tx_len[i] - priv->tx_ptr; if (res) write_scc(cmd, R0, RES_Tx_P); @@ -1133,9 +1144,11 @@ /* Check if another frame is available and we are allowed to transmit */ if (priv->tx_count && (jiffies - priv->tx_start) < priv->param.txtime) { if (dev->dma) { + flags=claim_dma_lock(); set_dma_addr(dev->dma, (int) priv->tx_buf[priv->tx_tail]); set_dma_count(dev->dma, priv->tx_len[priv->tx_tail]); enable_dma(dev->dma); + release_dma_lock(flags); } else { /* If we have an ESCC, we are allowed to write data bytes immediately. Otherwise we have to wait for the next @@ -1170,12 +1183,14 @@ if (st & DCD) { if (dev->dma) { /* Program DMA controller */ + flags=claim_dma_lock(); disable_dma(dev->dma); clear_dma_ff(dev->dma); set_dma_mode(dev->dma, DMA_MODE_READ); set_dma_addr(dev->dma, (int) priv->rx_buf[priv->rx_head]); set_dma_count(dev->dma, BUF_SIZE); enable_dma(dev->dma); + release_dma_lock(flags); /* Configure PackeTwin DMA */ if (info->type == TYPE_TWIN) { outb_p((dev->dma == 1) ? TWIN_DMA_HDX_R1 : TWIN_DMA_HDX_R3, @@ -1195,7 +1210,12 @@ } } else { /* Disable DMA */ - if (dev->dma) disable_dma(dev->dma); + if (dev->dma) + { + flags=claim_dma_lock(); + disable_dma(dev->dma); + release_dma_lock(flags); + } /* Disable receiver */ write_scc(cmd, R3, Rx8); /* DMA disable, RX int disable, Ext int enable */ @@ -1228,11 +1248,13 @@ while (read_scc(cmd, R0) & Rx_CH_AV) read_scc(cmd, R8); priv->rx_over = 0; if (dev->dma) { + flags=claim_dma_lock(); disable_dma(dev->dma); clear_dma_ff(dev->dma); set_dma_addr(dev->dma, (int) priv->rx_buf[priv->rx_head]); set_dma_count(dev->dma, BUF_SIZE); enable_dma(dev->dma); + release_dma_lock(flags); } else { priv->rx_ptr = 0; } @@ -1245,6 +1267,7 @@ struct scc_priv *priv = dev->priv; struct scc_info *info = priv->info; int cmd = priv->cmd; + unsigned long flags; switch (priv->tx_state) { case TX_OFF: @@ -1266,12 +1289,16 @@ priv->tx_state = TX_ACTIVE; if (dev->dma) { /* Program DMA controller */ + + flags=claim_dma_lock(); disable_dma(dev->dma); clear_dma_ff(dev->dma); set_dma_mode(dev->dma, DMA_MODE_WRITE); set_dma_addr(dev->dma, (int) priv->tx_buf[priv->tx_tail]); set_dma_count(dev->dma, priv->tx_len[priv->tx_tail]); enable_dma(dev->dma); + release_dma_lock(flags); + /* Configure PackeTwin DMA */ if (info->type == TYPE_TWIN) { outb_p((dev->dma == 1) ? TWIN_DMA_HDX_T1 : TWIN_DMA_HDX_T3, diff -u --recursive --new-file v2.1.125/linux/drivers/net/hostess_sv11.c linux/drivers/net/hostess_sv11.c --- v2.1.125/linux/drivers/net/hostess_sv11.c Wed Sep 9 14:51:08 1998 +++ linux/drivers/net/hostess_sv11.c Fri Oct 16 23:30:21 1998 @@ -1,3 +1,5 @@ +#define LINUX_21 + /* * Comtrol SV11 card driver * @@ -7,7 +9,7 @@ * Its a genuine Z85230 * * It supports DMA using two DMA channels in SYNC mode. The driver doesn't - * use these facilities (yet). + * use these facilities * * The control port is at io+1, the data at io+3 and turning off the DMA * is done by writing 0 to io+4 @@ -50,7 +52,7 @@ /* * Frame receive. Simple for our card as we do sync ppp and there - * is no funny garbage involved. This is very timing sensitive. + * is no funny garbage involved */ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb) @@ -58,13 +60,12 @@ /* Drop the CRC - its not a good idea to try and negotiate it ;) */ skb_trim(skb, skb->len-2); skb->protocol=htons(ETH_P_WAN_PPP); + skb->mac.raw=skb->data; skb->dev=c->netdevice; /* * Send it to the PPP layer. We dont have time to process * it right now. */ - skb->mac.raw = skb->data; - netif_rx(skb); } @@ -75,15 +76,24 @@ static int hostess_open(struct device *d) { struct sv11_device *sv11=d->priv; - int err; + int err = -1; /* * Link layer up */ - if(dma) - err=z8530_sync_dma_open(d, &sv11->sync.chanA); - else - err=z8530_sync_open(d, &sv11->sync.chanA); + switch(dma) + { + case 0: + err=z8530_sync_open(d, &sv11->sync.chanA); + break; + case 1: + err=z8530_sync_dma_open(d, &sv11->sync.chanA); + break; + case 2: + err=z8530_sync_txdma_open(d, &sv11->sync.chanA); + break; + } + if(err) return err; /* @@ -92,10 +102,18 @@ err=sppp_open(d); if(err) { - if(dma) - z8530_sync_dma_close(d, &sv11->sync.chanA); - else - z8530_sync_close(d, &sv11->sync.chanA); + switch(dma) + { + case 0: + z8530_sync_close(d, &sv11->sync.chanA); + break; + case 1: + z8530_sync_dma_close(d, &sv11->sync.chanA); + break; + case 2: + z8530_sync_txdma_close(d, &sv11->sync.chanA); + break; + } return err; } sv11->sync.chanA.rx_function=hostess_input; @@ -123,10 +141,19 @@ * Link layer down */ d->tbusy=1; - if(dma) - z8530_sync_dma_close(d, &sv11->sync.chanA); - else - z8530_sync_close(d, &sv11->sync.chanA); + + switch(dma) + { + case 0: + z8530_sync_close(d, &sv11->sync.chanA); + break; + case 1: + z8530_sync_dma_close(d, &sv11->sync.chanA); + break; + case 2: + z8530_sync_txdma_close(d, &sv11->sync.chanA); + break; + } MOD_DEC_USE_COUNT; return 0; } @@ -135,10 +162,10 @@ { struct sv11_device *sv11=d->priv; /* z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ - return sppp_do_ioctl(d, ifr, cmd); + return sppp_do_ioctl(d, ifr,cmd); } -static struct net_device_stats *hostess_get_stats(struct device *d) +static struct enet_statistics *hostess_get_stats(struct device *d) { struct sv11_device *sv11=d->priv; if(sv11) @@ -157,6 +184,7 @@ return z8530_queue_xmit(&sv11->sync.chanA, skb); } +#ifdef LINUX_21 static int hostess_neigh_setup(struct neighbour *n) { if (n->nud_state == NUD_NONE) { @@ -176,6 +204,15 @@ return 0; } +#else + +static int return_0(struct device *d) +{ + return 0; +} + +#endif + /* * Description block for a Comtrol Hostess SV11 card */ @@ -243,13 +280,17 @@ * You can have DMA off or 1 and 3 thats the lot * on the Comtrol. */ - dev->chanA.txdma=1; - dev->chanA.rxdma=3; - outb(14, iobase+4); /* DMA on */ + dev->chanA.txdma=3; + dev->chanA.rxdma=1; + outb(0x03|0x08, iobase+4); /* DMA on */ if(request_dma(dev->chanA.txdma, "Hostess SV/11 (TX)")!=0) goto fail; - if(request_dma(dev->chanA.rxdma, "Hostess SV/11 (RX)")!=0) - goto dmafail; + + if(dma==1) + { + if(request_dma(dev->chanA.rxdma, "Hostess SV/11 (RX)")!=0) + goto dmafail; + } } save_flags(flags); cli(); @@ -259,7 +300,10 @@ */ if(z8530_init(dev)!=0) + { + printk(KERN_ERR "Z8530 series device not found.\n"); goto dmafail2; + } z8530_channel_load(&dev->chanB, z8530_dead_port); if(dev->type==Z85C30) z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream); @@ -269,8 +313,6 @@ restore_flags(flags); - printk(KERN_INFO "begin loading hdlc\n"); - /* * Now we can take the IRQ */ @@ -291,7 +333,6 @@ * Local fields */ sprintf(sv->name,"hdlc%d", i); - printk("Filling in device '%s' at %p\n", sv->name, d); d->name = sv->name; d->base_addr = iobase; @@ -305,8 +346,12 @@ d->get_stats = hostess_get_stats; d->set_multicast_list = NULL; d->do_ioctl = hostess_ioctl; +#ifdef LINUX_21 d->neigh_setup = hostess_neigh_setup_dev; dev_init_buffers(d); +#else + d->init = return_0; +#endif d->set_mac_address = NULL; if(register_netdev(d)==-1) @@ -322,11 +367,11 @@ } } dmafail2: - if(!dma) - goto fail; - free_dma(dev->chanA.rxdma); + if(dma==1) + free_dma(dev->chanA.rxdma); dmafail: - free_dma(dev->chanA.txdma); + if(dma) + free_dma(dev->chanA.txdma); fail: free_irq(irq, dev); fail2: @@ -342,8 +387,11 @@ z8530_shutdown(&dev->sync); unregister_netdev(&dev->netdev.dev); free_irq(dev->sync.irq, dev); - free_dma(dev->sync.chanA.rxdma); - free_dma(dev->sync.chanA.txdma); + if(dma) + { + free_dma(dev->sync.chanA.rxdma); + free_dma(dev->sync.chanA.txdma); + } release_region(dev->sync.chanA.ctrlio-1, 8); } @@ -352,6 +400,7 @@ static int io=0x200; static int irq=9; +#ifdef LINUX_21 MODULE_PARM(io,"i"); MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card"); MODULE_PARM(dma,"i"); @@ -361,12 +410,13 @@ MODULE_AUTHOR("Bulding Number Three Ltd"); MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11"); +#endif static struct sv11_device *sv11_unit; int init_module(void) { - printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.02.\n"); + printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.01.\n"); printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n"); if(dma) printk(KERN_WARNING "DMA mode probably wont work right now.\n"); diff -u --recursive --new-file v2.1.125/linux/drivers/net/lance.c linux/drivers/net/lance.c --- v2.1.125/linux/drivers/net/lance.c Tue Jul 28 14:21:08 1998 +++ linux/drivers/net/lance.c Fri Oct 9 11:56:59 1998 @@ -377,6 +377,7 @@ unsigned char hpJ2405A = 0; /* HP ISA adaptor */ int hp_builtin = 0; /* HP on-board ethernet. */ static int did_version = 0; /* Already printed version info. */ + unsigned long flags; /* First we look for special cases. Check for HP's on-board ethernet by looking for 'HP' in the BIOS. @@ -563,8 +564,11 @@ outw(0x7f04, ioaddr+LANCE_DATA); /* Clear the memory error bits. */ if (request_dma(dma, chipname)) continue; + + flags=claim_dma_lock(); set_dma_mode(dma, DMA_MODE_CASCADE); enable_dma(dma); + release_dma_lock(flags); /* Trigger an initialization. */ outw(0x0001, ioaddr+LANCE_DATA); @@ -576,7 +580,9 @@ printk(", DMA %d.\n", dev->dma); break; } else { + flags=claim_dma_lock(); disable_dma(dma); + release_dma_lock(flags); free_dma(dma); } } @@ -649,8 +655,10 @@ /* The DMA controller is used as a no-operation slave, "cascade mode". */ if (dev->dma != 4) { + unsigned long flags=claim_dma_lock(); enable_dma(dev->dma); set_dma_mode(dev->dma, DMA_MODE_CASCADE); + release_dma_lock(flags); } /* Un-Reset the LANCE, needed only for the NE2100. */ @@ -1121,7 +1129,11 @@ outw(0x0004, ioaddr+LANCE_DATA); if (dev->dma != 4) + { + unsigned long flags=claim_dma_lock(); disable_dma(dev->dma); + release_dma_lock(flags); + } free_irq(dev->irq, dev); diff -u --recursive --new-file v2.1.125/linux/drivers/net/ltpc.c linux/drivers/net/ltpc.c --- v2.1.125/linux/drivers/net/ltpc.c Mon Feb 23 18:12:05 1998 +++ linux/drivers/net/ltpc.c Fri Oct 9 11:56:59 1998 @@ -352,13 +352,17 @@ /* called *only* from idle, non-reentrant */ int dma = dev->dma; int base = dev->base_addr; + unsigned long flags; + + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma,DMA_MODE_READ); set_dma_addr(dma,virt_to_bus(ltdmacbuf)); set_dma_count(dma,50); enable_dma(dma); + release_dma_lock(flags); inb_p(base+3); inb_p(base+2); @@ -370,13 +374,16 @@ { int dma = dev->dma; int base = dev->base_addr; + unsigned long flags; + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma,DMA_MODE_READ); set_dma_addr(dma,virt_to_bus(ltdmabuf)); set_dma_count(dma,800); enable_dma(dma); + release_dma_lock(flags); inb_p(base+3); inb_p(base+2); @@ -391,21 +398,25 @@ /* on entry, 0xfb and ltdmabuf holds data */ int dma = dev->dma; int base = dev->base_addr; - - + unsigned long flags; + + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma,DMA_MODE_WRITE); set_dma_addr(dma,virt_to_bus(ltdmabuf)); set_dma_count(dma,800); enable_dma(dma); - + release_dma_lock(flags); + inb_p(base+3); inb_p(base+2); if ( wait_timeout(dev,0xfb) ) { + flags=claim_dma_lock(); printk("timed out in handlewrite, dma res %d\n", get_dma_residue(dev->dma) ); + release_dma_lock(flags); } } @@ -415,15 +426,17 @@ /* on exit, ltdmabuf holds data */ int dma = dev->dma; int base = dev->base_addr; + unsigned long flags; - - + + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma,DMA_MODE_READ); set_dma_addr(dma,virt_to_bus(ltdmabuf)); set_dma_count(dma,800); enable_dma(dma); + release_dma_lock(flags); inb_p(base+3); inb_p(base+2); @@ -435,14 +448,16 @@ /* on entry, 0xfa and ltdmacbuf holds command */ int dma = dev->dma; int base = dev->base_addr; + unsigned long flags; + flags=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma,DMA_MODE_WRITE); set_dma_addr(dma,virt_to_bus(ltdmacbuf)); set_dma_count(dma,50); enable_dma(dma); - + release_dma_lock(flags); inb_p(base+3); inb_p(base+2); if ( wait_timeout(dev,0xfa) ) printk("timed out in handlecommand\n"); @@ -978,6 +993,7 @@ int probe3, probe4, probe9; unsigned short straymask; unsigned long flags; + unsigned long f; err = ltpc_init(dev); if (err) return err; @@ -1089,6 +1105,7 @@ inb_p(base+6); /* tri-state interrupt line */ timeout = jiffies+100; + while(timeout>jiffies) { /* wait for the card to complete initialization */ } @@ -1098,21 +1115,26 @@ /* set up both dma 1 and 3 for read call */ if (!request_dma(1,"ltpc")) { + + f=claim_dma_lock(); disable_dma(1); clear_dma_ff(1); set_dma_mode(1,DMA_MODE_WRITE); set_dma_addr(1,virt_to_bus(ltdmabuf)); set_dma_count(1,sizeof(struct lt_mem)); enable_dma(1); + release_dma_lock(f); dma|=1; } if (!request_dma(3,"ltpc")) { + f=claim_dma_lock(); disable_dma(3); clear_dma_ff(3); set_dma_mode(3,DMA_MODE_WRITE); set_dma_addr(3,virt_to_bus(ltdmabuf)); set_dma_count(3,sizeof(struct lt_mem)); enable_dma(3); + release_dma_lock(f); dma|=2; } @@ -1174,13 +1196,15 @@ if(debug&DEBUG_VERBOSE) { printk("finishing up transfer\n"); } - + + f=claim_dma_lock(); disable_dma(dma); clear_dma_ff(dma); set_dma_mode(dma,DMA_MODE_READ); set_dma_addr(dma,virt_to_bus(ltdmabuf)); set_dma_count(dma,0x100); enable_dma(dma); + release_dma_lock(f); (void) inb_p(base+3); (void) inb_p(base+2); diff -u --recursive --new-file v2.1.125/linux/drivers/net/ne2.c linux/drivers/net/ne2.c --- v2.1.125/linux/drivers/net/ne2.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/ne2.c Sat Oct 17 15:33:45 1998 @@ -0,0 +1,698 @@ +/* ne2.c: A NE/2 Ethernet Driver for Linux. */ +/* + Based on the NE2000 driver written by Donald Becker (1992-94). + modified by Wim Dumon (Apr 1996) + + This software may be used and distributed according to the terms + of the GNU Public License, incorporated herein by reference. + + The author may be reached as wimpie@linux.cc.kuleuven.ac.be + + Currently supported: NE/2 + This patch was never tested on other MCA-ethernet adapters, but it + might work. Just give it a try and let me know if you have problems. + Also mail me if it really works, please! + + Changelog: + Mon Feb 3 16:26:02 MET 1997 + - adapted the driver to work with the 2.1.25 kernel + - multiple ne2 support (untested) + - module support (untested) + + Fri Aug 28 00:18:36 CET 1998 (David Weinehall) + - fixed a few minor typos + - made the MODULE_PARM conditional (it only works with the v2.1.x kernels) + - fixed the module support (Now it's working...) + + Mon Sep 7 19:01:44 CET 1998 (David Weinehall) + - added support for Arco Electronics AE/2-card (experimental) + + Mon Sep 14 09:53:42 CET 1998 (David Weinehall) + - added support for Compex ENET-16MC/P (experimental) + + Tue Sep 15 16:21:12 CET 1998 (David Weinehall, Magnus Jonsson, Tomas Ogren) + - Miscellaneous bugfixes + + Tue Sep 19 16:21:12 CET 1998 (Magnus Jonsson) + - Cleanup + + Wed Sep 23 14:33:34 CET 1998 (David Weinehall) + - Restructuring and rewriting for v2.1.x compliance + + Wed Oct 14 17:19:21 CET 1998 (David Weinehall) + - Added code that unregisters irq and proc-info + - Version# bump + + * WARNING + ------- + This is alpha-test software. It is not guaranteed to work. As a + matter of fact, I'm quite sure there are *LOTS* of bugs in here. I + would like to hear from you if you use this driver, even if it works. + If it doesn't work, be sure to send me a mail with the problems ! +*/ + +static const char *version = +"ne2.c:v0.90 Oct 14 1998 David Weinehall \n"; + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "8390.h" + + + +/* Some defines that people can play with if so inclined. */ + +/* Do we perform extra sanity checks on stuff ? */ +/* #define NE_SANITY_CHECK */ + +/* Do we implement the read before write bugfix ? */ +/* #define NE_RW_BUGFIX */ + +/* Do we have a non std. amount of memory? (in units of 256 byte pages) */ +/* #define PACKETBUF_MEMSIZE 0x40 */ + + +/* ---- No user-serviceable parts below ---- */ + +#define NE_BASE (dev->base_addr) +#define NE_CMD 0x00 +#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ +#define NE_RESET 0x20 /* Issue a read to reset, a write to clear. */ +#define NE_IO_EXTENT 0x30 + +#define NE1SM_START_PG 0x20 /* First page of TX buffer */ +#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ +#define NESM_START_PG 0x40 /* First page of TX buffer */ +#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ + +/* From the .ADF file: */ +static unsigned int addresses[7]= + {0x1000, 0x2020, 0x8020, 0xa0a0, 0xb0b0, 0xc0c0, 0xc3d0}; +static int irqs[4] = {3, 4, 5, 9}; + +struct ne2_adapters_t { + unsigned int id; + char *name; +}; + +const struct ne2_adapters_t ne2_adapters[] = { + { 0x6354, "Arco Ethernet Adapter AE/2" }, + { 0x70DE, "Compex ENET-16 MC/P" }, + { 0x7154, "Novell Ethernet Adapter NE/2" }, + { 0x0000, NULL } +}; + +extern int netcard_probe(struct device *dev); + +static int ne2_probe1(struct device *dev, int slot); + +static int ne_open(struct device *dev); +static int ne_close(struct device *dev); + +static void ne_reset_8390(struct device *dev); +static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, + int ring_page); +static void ne_block_input(struct device *dev, int count, + struct sk_buff *skb, int ring_offset); +static void ne_block_output(struct device *dev, const int count, + const unsigned char *buf, const int start_page); + + +/* + * Note that at boot, this probe only picks up one card at a time. + */ + +__initfunc (int ne2_probe(struct device *dev)) +{ + static int current_mca_slot = -1; + int i; + int adapter_found = 0; + + /* Do not check any supplied i/o locations. + POS registers usually don't fail :) */ + + /* MCA cards have POS registers. + Autodetecting MCA cards is extremely simple. + Just search for the card. */ + + for(i = 0; (ne2_adapters[i].name != NULL) && !adapter_found; i++) { + current_mca_slot = + mca_find_unused_adapter(ne2_adapters[i].id, 0); + + if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) { + mca_set_adapter_name(current_mca_slot, + ne2_adapters[i].name); + mca_mark_as_used(current_mca_slot); + + return ne2_probe1(dev, current_mca_slot); + } + } + return ENODEV; +} + + +static int ne2_procinfo(char *buf, int slot, struct device *dev) +{ + int len=0; + + len += sprintf(buf+len, "The NE/2 Ethernet Adapter\n" ); + len += sprintf(buf+len, "Driver written by Wim Dumon "); + len += sprintf(buf+len, "\n"); + len += sprintf(buf+len, "Modified by "); + len += sprintf(buf+len, "David Weinehall \n"); + len += sprintf(buf+len, "and by Magnus Jonsson \n"); + len += sprintf(buf+len, "Based on the original NE2000 drivers\n" ); + len += sprintf(buf+len, "Base IO: %#x\n", (unsigned int)dev->base_addr); + len += sprintf(buf+len, "IRQ : %d\n", dev->irq); + +#define HW_ADDR(i) dev->dev_addr[i] + len += sprintf(buf+len, "HW addr : %x:%x:%x:%x:%x:%x\n", + HW_ADDR(0), HW_ADDR(1), HW_ADDR(2), + HW_ADDR(3), HW_ADDR(4), HW_ADDR(5) ); +#undef HW_ADDR + + return len; +} + + +__initfunc (static int ne2_probe1(struct device *dev, int slot)) +{ + int i, base_addr, irq; + unsigned char POS; + unsigned char SA_prom[32]; + const char *name = "NE/2"; + int start_page, stop_page; + static unsigned version_printed = 0; + + /* We should have a "dev" from Space.c or the static module table. */ + if (dev == NULL) { + printk(KERN_ERR "ne2.c: Passed a NULL device.\n"); + dev = init_etherdev(0, 0); + } + + if (ei_debug && version_printed++ == 0) + printk(version); + + printk("NE/2 ethercard found in slot %d:", slot); + + /* Read base IO and IRQ from the POS-registers */ + POS = mca_read_stored_pos(slot, 2); + if(!(POS % 2)) { + printk(" disabled.\n"); + return ENODEV; + } + + i = (POS & 0xE)>>1; + /* printk("Halleluja sdog, als er na de pijl een 1 staat is 1 - 1 == 0" + " en zou het moeten werken -> %d\n", i); + The above line was for remote testing, thanx to sdog ... */ + base_addr = addresses[i - 1]; + irq = irqs[(POS & 0x60)>>5]; + +#ifdef DEBUG + printk("POS info : pos 2 = %#x ; base = %#x ; irq = %ld\n", POS, + base_addr, irq); +#endif + +#ifndef CRYNWR_WAY + /* Reset the card the way they do it in the Crynwr packet driver */ + for (i=0; i<8; i++) + outb(0x0, base_addr + NE_RESET); + inb(base_addr + NE_RESET); + outb(0x21, base_addr + NE_CMD); + if (inb(base_addr + NE_CMD) != 0x21) { + printk("NE/2 adapter not responding\n"); + return ENODEV; + } + + /* In the crynwr sources they do a RAM-test here. I skip it. I suppose + my RAM is okay. Suppose your memory is broken. Then this test + should fail and you won't be able to use your card. But if I do not + test, you won't be able to use your card, neither. So this test + won't help you. */ + +#else /* _I_ never tested it this way .. Go ahead and try ...*/ + /* Reset card. Who knows what dain-bramaged state it was left in. */ + { + unsigned long reset_start_time = jiffies; + + /* DON'T change these to inb_p/outb_p or reset will fail on + clones.. */ + outb(inb(base_addr + NE_RESET), base_addr + NE_RESET); + + while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0) + if (jiffies - reset_start_time > 2*HZ/100) { + printk(" not found (no reset ack).\n"); + return ENODEV; + } + + outb_p(0xff, base_addr + EN0_ISR); /* Ack all intr. */ + } +#endif + + + /* Read the 16 bytes of station address PROM. + We must first initialize registers, similar to + NS8390_init(eifdev, 0). + We can't reliably read the SAPROM address without this. + (I learned the hard way!). */ + { + struct { + unsigned char value, offset; + } program_seq[] = { + /* Select page 0 */ + {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, + {0x49, EN0_DCFG}, /* Set WORD-wide (0x49) access. */ + {0x00, EN0_RCNTLO}, /* Clear the count regs. */ + {0x00, EN0_RCNTHI}, + {0x00, EN0_IMR}, /* Mask completion irq. */ + {0xFF, EN0_ISR}, + {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ + {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ + {32, EN0_RCNTLO}, + {0x00, EN0_RCNTHI}, + {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ + {0x00, EN0_RSARHI}, + {E8390_RREAD+E8390_START, E8390_CMD}, + }; + + for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) + outb_p(program_seq[i].value, base_addr + + program_seq[i].offset); + + } + for(i = 0; i < 6 /*sizeof(SA_prom)*/; i+=1) { + SA_prom[i] = inb(base_addr + NE_DATAPORT); + } + + start_page = NESM_START_PG; + stop_page = NESM_STOP_PG; + + dev->irq=irq; + + /* Snarf the interrupt now. There's no point in waiting since we cannot + share and the board will usually be enabled. */ + { + int irqval = request_irq(dev->irq, ei_interrupt, + 0, name, NULL); + if (irqval) { + printk (" unable to get IRQ %d (irqval=%d).\n", + dev->irq, +irqval); + return EAGAIN; + } + } + + dev->base_addr = base_addr; + + /* Allocate dev->priv and fill in 8390 specific dev fields. */ + if (ethdev_init(dev)) { + printk (" unable to get memory for dev->priv.\n"); + free_irq(dev->irq, NULL); + return -ENOMEM; + } + + request_region(base_addr, NE_IO_EXTENT, name); + + for(i = 0; i < ETHER_ADDR_LEN; i++) { + printk(" %2.2x", SA_prom[i]); + dev->dev_addr[i] = SA_prom[i]; + } + + printk("\n%s: %s found at %#x, using IRQ %d.\n", + dev->name, name, base_addr, dev->irq); + + mca_set_adapter_procfn(slot, (MCA_ProcFn) ne2_procinfo, dev); + + ei_status.name = name; + ei_status.tx_start_page = start_page; + ei_status.stop_page = stop_page; + ei_status.word16 = (2 == 2); + + ei_status.rx_start_page = start_page + TX_PAGES; +#ifdef PACKETBUF_MEMSIZE + /* Allow the packet buffer size to be overridden by know-it-alls. */ + ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; +#endif + + ei_status.reset_8390 = &ne_reset_8390; + ei_status.block_input = &ne_block_input; + ei_status.block_output = &ne_block_output; + ei_status.get_8390_hdr = &ne_get_8390_hdr; + + ei_status.priv = slot; + + dev->open = &ne_open; + dev->stop = &ne_close; + NS8390_init(dev, 0); + return 0; +} + +static int ne_open(struct device *dev) +{ + ei_open(dev); + MOD_INC_USE_COUNT; + return 0; +} + +static int ne_close(struct device *dev) +{ + if (ei_debug > 1) + printk("%s: Shutting down ethercard.\n", dev->name); + ei_close(dev); + MOD_DEC_USE_COUNT; + return 0; +} + +/* Hard reset the card. This used to pause for the same period that a + 8390 reset command required, but that shouldn't be necessary. */ +static void ne_reset_8390(struct device *dev) +{ + unsigned long reset_start_time = jiffies; + + if (ei_debug > 1) + printk("resetting the 8390 t=%ld...", jiffies); + + /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ + outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); + + ei_status.txing = 0; + ei_status.dmaing = 0; + + /* This check _should_not_ be necessary, omit eventually. */ + while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) + if (jiffies - reset_start_time > 2*HZ/100) { + printk("%s: ne_reset_8390() did not complete.\n", + dev->name); + break; + } + outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ +} + +/* Grab the 8390 specific header. Similar to the block_input routine, but + we don't need to be concerned with ring wrap as the header will be at + the start of a page, so we optimize accordingly. */ + +static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, + int ring_page) +{ + + int nic_base = dev->base_addr; + + /* This *shouldn't* happen. + If it does, it's the last thing you'll see */ + if (ei_status.dmaing) { + printk("%s: DMAing conflict in ne_get_8390_hdr " + "[DMAstat:%d][irqlock:%d][intr:%ld].\n", + dev->name, ei_status.dmaing, ei_status.irqlock, + dev->interrupt); + return; + } + + ei_status.dmaing |= 0x01; + outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); + outb_p(0, nic_base + EN0_RCNTHI); + outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ + outb_p(ring_page, nic_base + EN0_RSARHI); + outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); + + if (ei_status.word16) + insw(NE_BASE + NE_DATAPORT, hdr, + sizeof(struct e8390_pkt_hdr)>>1); + else + insb(NE_BASE + NE_DATAPORT, hdr, + sizeof(struct e8390_pkt_hdr)); + + outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; +} + +/* Block input and output, similar to the Crynwr packet driver. If you + are porting to a new ethercard, look at the packet driver source for + hints. The NEx000 doesn't share the on-board packet memory -- you have + to put the packet out through the "remote DMA" dataport using outb. */ + +static void ne_block_input(struct device *dev, int count, struct sk_buff *skb, + int ring_offset) +{ +#ifdef NE_SANITY_CHECK + int xfer_count = count; +#endif + int nic_base = dev->base_addr; + char *buf = skb->data; + + /* This *shouldn't* happen. + If it does, it's the last thing you'll see */ + if (ei_status.dmaing) { + printk("%s: DMAing conflict in ne_block_input " + "[DMAstat:%d][irqlock:%d][intr:%ld].\n", + dev->name, ei_status.dmaing, ei_status.irqlock, + dev->interrupt); + return; + } + ei_status.dmaing |= 0x01; + outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + outb_p(count & 0xff, nic_base + EN0_RCNTLO); + outb_p(count >> 8, nic_base + EN0_RCNTHI); + outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); + outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); + outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); + if (ei_status.word16) { + insw(NE_BASE + NE_DATAPORT,buf,count>>1); + if (count & 0x01) { + buf[count-1] = inb(NE_BASE + NE_DATAPORT); +#ifdef NE_SANITY_CHECK + xfer_count++; +#endif + } + } else { + insb(NE_BASE + NE_DATAPORT, buf, count); + } + +#ifdef NE_SANITY_CHECK + /* This was for the ALPHA version only, but enough people have + been encountering problems so it is still here. If you see + this message you either 1) have a slightly incompatible clone + or 2) have noise/speed problems with your bus. */ + if (ei_debug > 1) { /* DMA termination address check... */ + int addr, tries = 20; + do { + /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here + -- it's broken for Rx on some cards! */ + int high = inb_p(nic_base + EN0_RSARHI); + int low = inb_p(nic_base + EN0_RSARLO); + addr = (high << 8) + low; + if (((ring_offset + xfer_count) & 0xff) == low) + break; + } while (--tries > 0); + if (tries <= 0) + printk("%s: RX transfer address mismatch," + "%#4.4x (expected) vs. %#4.4x (actual).\n", + dev->name, ring_offset + xfer_count, addr); + } +#endif + outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; +} + +static void ne_block_output(struct device *dev, int count, + const unsigned char *buf, const int start_page) +{ + int nic_base = NE_BASE; + unsigned long dma_start; +#ifdef NE_SANITY_CHECK + int retries = 0; +#endif + + /* Round the count up for word writes. Do we need to do this? + What effect will an odd byte count have on the 8390? + I should check someday. */ + if (ei_status.word16 && (count & 0x01)) + count++; + + /* This *shouldn't* happen. + If it does, it's the last thing you'll see */ + if (ei_status.dmaing) { + printk("%s: DMAing conflict in ne_block_output." + "[DMAstat:%d][irqlock:%d][intr:%ld]\n", + dev->name, ei_status.dmaing, ei_status.irqlock, + dev->interrupt); + return; + } + ei_status.dmaing |= 0x01; + /* We should already be in page 0, but to be safe... */ + outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); + +#ifdef NE_SANITY_CHECK +retry: +#endif + +#ifdef NE8390_RW_BUGFIX + /* Handle the read-before-write bug the same way as the + Crynwr packet driver -- the NatSemi method doesn't work. + Actually this doesn't always work either, but if you have + problems with your NEx000 this is better than nothing! */ + outb_p(0x42, nic_base + EN0_RCNTLO); + outb_p(0x00, nic_base + EN0_RCNTHI); + outb_p(0x42, nic_base + EN0_RSARLO); + outb_p(0x00, nic_base + EN0_RSARHI); + outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); + /* Make certain that the dummy read has occurred. */ + SLOW_DOWN_IO; + SLOW_DOWN_IO; + SLOW_DOWN_IO; +#endif + + outb_p(ENISR_RDC, nic_base + EN0_ISR); + + /* Now the normal output. */ + outb_p(count & 0xff, nic_base + EN0_RCNTLO); + outb_p(count >> 8, nic_base + EN0_RCNTHI); + outb_p(0x00, nic_base + EN0_RSARLO); + outb_p(start_page, nic_base + EN0_RSARHI); + + outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD); + if (ei_status.word16) { + outsw(NE_BASE + NE_DATAPORT, buf, count>>1); + } else { + outsb(NE_BASE + NE_DATAPORT, buf, count); + } + + dma_start = jiffies; + +#ifdef NE_SANITY_CHECK + /* This was for the ALPHA version only, but enough people have + been encountering problems so it is still here. */ + + if (ei_debug > 1) { /* DMA termination address check... */ + int addr, tries = 20; + do { + int high = inb_p(nic_base + EN0_RSARHI); + int low = inb_p(nic_base + EN0_RSARLO); + addr = (high << 8) + low; + if ((start_page << 8) + count == addr) + break; + } while (--tries > 0); + if (tries <= 0) { + printk("%s: Tx packet transfer address mismatch," + "%#4.4x (expected) vs. %#4.4x (actual).\n", + dev->name, (start_page << 8) + count, addr); + if (retries++ == 0) + goto retry; + } + } +#endif + + while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ + printk("%s: timeout waiting for Tx RDC.\n", dev->name); + ne_reset_8390(dev); + NS8390_init(dev,1); + break; + } + + outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ + ei_status.dmaing &= ~0x01; + return; +} + + +#ifdef MODULE +#define MAX_NE_CARDS 4 /* Max number of NE cards per module */ +#define NAMELEN 8 /* # of chars for storing dev->name */ +static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, }; +static struct device dev_ne[MAX_NE_CARDS] = { + { + NULL, /* assign a chunk of namelist[] below */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, NULL + }, +}; + +static int io[MAX_NE_CARDS] = { 0, }; +static int irq[MAX_NE_CARDS] = { 0, }; +static int bad[MAX_NE_CARDS] = { 0, }; /* 0xbad = bad sig or no reset ack */ + +#ifdef MODULE_PARM +MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); +MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i"); +#endif + +/* Module code fixed by David Weinehall */ + +int init_module(void) +{ + int this_dev, found = 0; + + for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { + struct device *dev = &dev_ne[this_dev]; + dev->name = namelist+(NAMELEN*this_dev); + dev->irq = irq[this_dev]; + dev->mem_end = bad[this_dev]; + dev->base_addr = io[this_dev]; + dev->init = ne2_probe; + if (register_netdev(dev) != 0) { + if (found != 0) return 0; /* Got at least one. */ + + printk(KERN_WARNING "ne2.c: No NE/2 card found.\n"); + return -ENXIO; + } + found++; + } + return 0; +} + +void cleanup_module(void) +{ + int this_dev; + + for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { + struct device *dev = &dev_ne[this_dev]; + if (dev->priv != NULL) { + mca_mark_as_unused(ei_status.priv); + mca_set_adapter_procfn( ei_status.priv, NULL, NULL); + kfree(dev->priv); + dev->priv = NULL; + free_irq(dev->irq, dev); + /* removed (temporary) fot */ + /* irq2dev_map[dev->irq] = NULL; */ + release_region(dev->base_addr, NE_IO_EXTENT); + unregister_netdev(dev); + } + } +} +#endif /* MODULE */ + +/* + * Local variables: + * compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c ne2.c" + * version-control: t + * kept-new-versions: 5 + * End: + */ diff -u --recursive --new-file v2.1.125/linux/drivers/net/ni65.c linux/drivers/net/ni65.c --- v2.1.125/linux/drivers/net/ni65.c Sun Jun 7 11:16:32 1998 +++ linux/drivers/net/ni65.c Fri Oct 9 11:56:59 1998 @@ -351,6 +351,7 @@ { int i,j; struct priv *p; + unsigned long flags; for(i=0;idev_addr,0,0); /* trigger memory access */ + + flags=claim_dma_lock(); disable_dma(dma); free_dma(dma); + release_dma_lock(flags); + if(readreg(CSR0) & CSR0_IDON) break; } @@ -718,20 +727,25 @@ { int i; struct priv *p = (struct priv *) dev->priv; + unsigned long flags; p->lock = 0; p->xmit_queued = 0; + flags=claim_dma_lock(); disable_dma(dev->dma); /* I've never worked with dma, but we do it like the packetdriver */ set_dma_mode(dev->dma,DMA_MODE_CASCADE); enable_dma(dev->dma); + release_dma_lock(flags); outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */ if( (i=readreg(CSR0) ) != 0x4) { printk(KERN_ERR "%s: can't RESET %s card: %04x\n",dev->name, cards[p->cardno].cardname,(int) i); + flags=claim_dma_lock(); disable_dma(dev->dma); + release_dma_lock(flags); return 0; } @@ -782,7 +796,9 @@ return 1; /* ->OK */ } printk(KERN_ERR "%s: can't init lance, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG)); + flags=claim_dma_lock(); disable_dma(dev->dma); + release_dma_lock(flags); return 0; /* ->Error */ } @@ -1167,8 +1183,10 @@ } #ifdef MODULE +static char devicename[9] = { 0, }; + static struct device dev_ni65 = { - " ", /* "ni6510": device name inserted by net_init.c */ + devicename, /* "ni6510": device name inserted by net_init.c */ 0, 0, 0, 0, 0x360, 9, /* I/O address, IRQ */ 0, 0, 0, NULL, ni65_probe }; diff -u --recursive --new-file v2.1.125/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v2.1.125/linux/drivers/net/plip.c Thu Sep 17 17:53:36 1998 +++ linux/drivers/net/plip.c Fri Oct 9 12:20:27 1998 @@ -242,7 +242,10 @@ pardev = parport_register_device(pb, dev->name, plip_preempt, plip_wakeup, plip_interrupt, - PARPORT_DEV_LURK, dev); + 0, dev); + + if (!pardev) + return -ENODEV; printk(KERN_INFO "%s", version); printk(KERN_INFO "%s: Parallel port at %#3lx, using IRQ %d\n", dev->name, diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdla_fr.c linux/drivers/net/sdla_fr.c --- v2.1.125/linux/drivers/net/sdla_fr.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/net/sdla_fr.c Fri Oct 9 11:56:59 1998 @@ -650,8 +650,8 @@ dev->irq = wandev->irq; dev->dma = wandev->dma; dev->base_addr = wandev->ioport; - dev->mem_start = wandev->maddr; - dev->mem_end = wandev->maddr + wandev->msize - 1; + dev->mem_start = (unsigned long)wandev->maddr; + dev->mem_end = dev->mem_start + wandev->msize - 1; /* Set transmit buffer queue length */ dev->tx_queue_len = 10; /* Initialize socket buffers */ diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdla_ppp.c linux/drivers/net/sdla_ppp.c --- v2.1.125/linux/drivers/net/sdla_ppp.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/net/sdla_ppp.c Fri Oct 9 11:56:59 1998 @@ -412,8 +412,8 @@ dev->irq = wandev->irq; dev->dma = wandev->dma; dev->base_addr = wandev->ioport; - dev->mem_start = wandev->maddr; - dev->mem_end = wandev->maddr + wandev->msize - 1; + dev->mem_start = (unsigned long)wandev->maddr; + dev->mem_end = dev->mem_start + wandev->msize - 1; /* Set transmit buffer queue length */ dev->tx_queue_len = 100; /* Initialize socket buffers */ diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdla_x25.c linux/drivers/net/sdla_x25.c --- v2.1.125/linux/drivers/net/sdla_x25.c Fri Oct 9 13:27:09 1998 +++ linux/drivers/net/sdla_x25.c Fri Oct 9 11:56:59 1998 @@ -560,8 +560,8 @@ dev->irq = wandev->irq; dev->dma = wandev->dma; dev->base_addr = wandev->ioport; - dev->mem_start = wandev->maddr; - dev->mem_end = wandev->maddr + wandev->msize - 1; + dev->mem_start = (unsigned long)wandev->maddr; + dev->mem_end = dev->mem_end + wandev->msize - 1; /* Set transmit buffer queue length */ dev->tx_queue_len = 10; diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdladrv.c linux/drivers/net/sdladrv.c --- v2.1.125/linux/drivers/net/sdladrv.c Wed Sep 9 14:51:08 1998 +++ linux/drivers/net/sdladrv.c Fri Oct 9 11:56:59 1998 @@ -421,10 +421,10 @@ return err; } } - else if (!get_option_index(dpmbase_opt, virt_to_phys((void *)hw->dpmbase))) + else if (!get_option_index(dpmbase_opt, virt_to_phys(hw->dpmbase))) { printk(KERN_ERR "%s: memory address 0x%lX is illegal!\n", - modname, hw->dpmbase) + modname, virt_to_phys(hw->dpmbase)) ; return -EINVAL; } @@ -432,16 +432,14 @@ { printk(KERN_ERR "%s: 8K memory region at 0x%lX is not available!\n", - modname, hw->dpmbase) - ; + modname, virt_to_phys(hw->dpmbase)); return -EINVAL; } printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n", - modname, virt_to_phys((void *)hw->dpmbase)) - ; + modname, virt_to_phys(hw->dpmbase)); + printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n", - modname, hw->memory / 1024) - ; + modname, hw->memory / 1024); /* Load firmware. If loader fails then shut down adapter */ err = sdla_load(hw, sfm, len); @@ -830,7 +828,7 @@ /* Relocate window and copy block of data */ err = sdla_mapmem(hw, curvec); - memcpy((void*)buf, (void*)(hw->dpmbase + curpos), curlen); + memcpy(buf, (void *)((u8 *)hw->dpmbase + curpos), curlen); addr += curlen; (char*)buf += curlen; len -= curlen; @@ -872,7 +870,7 @@ /* Relocate window and copy block of data */ sdla_mapmem(hw, curvec); - memcpy((void*)(hw->dpmbase + curpos), (void*)buf, curlen); + memcpy((void*)((u8 *)hw->dpmbase + curpos), buf, curlen); addr += curlen; (char*)buf += curlen; len -= curlen; @@ -980,7 +978,7 @@ for (i = opt[0]; i && err; --i) { - hw->dpmbase = (unsigned long )(phys_to_virt(opt[i])); + hw->dpmbase = phys_to_virt(opt[i]); err = sdla_setdpm(hw); } return err; @@ -1001,7 +999,7 @@ /* Shut down card and verify memory region */ sdla_down(hw); - if (check_memregion((void*)hw->dpmbase, hw->dpmsize)) + if (check_memregion(hw->dpmbase, hw->dpmsize)) return -EINVAL ; @@ -1154,7 +1152,7 @@ for (memsize = 0, winsize = hw->dpmsize; !sdla_mapmem(hw, memsize) && - (test_memregion((void*)hw->dpmbase, winsize) == winsize) + (test_memregion(hw->dpmbase, winsize) == winsize) ; memsize += winsize) ; @@ -1176,7 +1174,7 @@ if (sdla_mapmem(hw, sfminfo->dataoffs) != 0) return -EIO ; - data = (void*)(hw->dpmbase + (sfminfo->dataoffs - hw->vector)); + data = (void*)((u8 *)hw->dpmbase + (sfminfo->dataoffs - hw->vector)); memset(data, 0, sfminfo->datasize); data[0x00] = make_config_byte(hw); @@ -1229,7 +1227,7 @@ static int sdla_start (sdlahw_t* hw, unsigned addr) { unsigned port = hw->port; - unsigned char* bootp; + unsigned char *bootp; int err, tmp, i; if (!port) return -EFAULT; @@ -1237,14 +1235,15 @@ switch (hw->type) { case SDLA_S502A: - bootp = (void*)(hw->dpmbase + 0x66); + bootp = hw->dpmbase; + bootp += 0x66; break; case SDLA_S502E: case SDLA_S503: case SDLA_S507: case SDLA_S508: - bootp = (void*)hw->dpmbase; + bootp = hw->dpmbase; break; default: @@ -1333,7 +1332,7 @@ hw->regs[1] = 0xFF; /* Verify configuration options */ - i = get_option_index(s502a_dpmbase_options, virt_to_phys((void *)hw->dpmbase)); + i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) return -EINVAL ; @@ -1372,7 +1371,7 @@ ; /* Verify configuration options */ - i = get_option_index(s508_dpmbase_options, virt_to_phys((void *)hw->dpmbase)); + i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) return -EINVAL ; @@ -1416,7 +1415,7 @@ ; /* Verify configuration options */ - i = get_option_index(s508_dpmbase_options, virt_to_phys((void *)hw->dpmbase)); + i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) return -EINVAL ; @@ -1458,7 +1457,7 @@ ; /* Verify configuration options */ - i = get_option_index(s507_dpmbase_options, virt_to_phys((void *)hw->dpmbase)); + i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) return -EINVAL ; @@ -1515,7 +1514,7 @@ ; /* Verify configuration options */ - i = get_option_index(s508_dpmbase_options, virt_to_phys((void *)hw->dpmbase)); + i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase)); if (i == 0) return -EINVAL ; diff -u --recursive --new-file v2.1.125/linux/drivers/net/sdlamain.c linux/drivers/net/sdlamain.c --- v2.1.125/linux/drivers/net/sdlamain.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/net/sdlamain.c Fri Oct 9 11:56:59 1998 @@ -269,9 +269,9 @@ card->hw.irq = (conf->irq == 9) ? 2 : conf->irq; /* Compute the virtual address of the card in kernel space */ if(conf->maddr) - card->hw.dpmbase = (unsigned long)phys_to_virt(conf->maddr); + card->hw.dpmbase = phys_to_virt(conf->maddr); else /* But 0 means NULL */ - card->hw.dpmbase = conf->maddr; + card->hw.dpmbase = (void *)conf->maddr; card->hw.dpmsize = SDLA_WINDOWSIZE; card->hw.type = conf->hw_opt[0]; @@ -470,8 +470,8 @@ } /* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */ sti(); /* Not ideal but tough we have to do this */ - if(copy_to_user((void*)(dump.ptr), - (void*)(card->hw.dpmbase + pos), len)) + if(copy_to_user((void *)dump.ptr, + (u8 *)card->hw.dpmbase + pos, len)) return -EFAULT; cli(); dump.length -= len; diff -u --recursive --new-file v2.1.125/linux/drivers/net/sktr.c linux/drivers/net/sktr.c --- v2.1.125/linux/drivers/net/sktr.c Wed Jul 1 19:38:54 1998 +++ linux/drivers/net/sktr.c Fri Oct 9 11:56:59 1998 @@ -298,6 +298,7 @@ __initfunc(static int sktr_isa_chk_card(struct device *dev, int ioaddr)) { int i, err; + unsigned long flags; err = sktr_isa_chk_ioaddr(ioaddr); if(err < 0) @@ -373,9 +374,11 @@ } } + flags=claim_dma_lock(); disable_dma(dev->dma); set_dma_mode(dev->dma, DMA_MODE_CASCADE); enable_dma(dev->dma); + release_dma_lock(flags); printk("%s: %s found at %#4x, using IRQ %d and DMA %d.\n", dev->name, AdapterName, ioaddr, dev->irq, dev->dma); @@ -1446,7 +1449,12 @@ sktr_disable_interrupts(dev); if(dev->dma > 0) + { + unsigned long flags=claim_dma_lock(); disable_dma(dev->dma); + release_dma_lock(flags); + } + outw(0xFF00, dev->base_addr + SIFCMD); if(dev->dma > 0) outb(0xff, dev->base_addr + POSREG); diff -u --recursive --new-file v2.1.125/linux/drivers/net/syncppp.c linux/drivers/net/syncppp.c --- v2.1.125/linux/drivers/net/syncppp.c Wed Sep 9 14:51:08 1998 +++ linux/drivers/net/syncppp.c Sat Oct 17 15:33:45 1998 @@ -770,6 +770,7 @@ sp->obytes += skb->len; /* Control is high priority so it doesnt get queued behind data */ skb->priority=1; + skb->dev = dev; dev_queue_xmit(skb); } @@ -811,6 +812,7 @@ ch->par2, ch->rel, ch->time0, ch->time1); sp->obytes += skb->len; skb->priority=1; + skb->dev = dev; dev_queue_xmit(skb); } @@ -861,9 +863,20 @@ { case SPPPIOCCISCO: sp->pp_flags|=PP_CISCO; + dev->type = ARPHRD_HDLC; break; case SPPPIOCPPP: sp->pp_flags&=~PP_CISCO; + dev->type = ARPHRD_PPP; + break; + case SPPPIOCDEBUG: + sp->pp_flags&=~PP_DEBUG; + if(ifr->ifr_flags) + { + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + sp->pp_flags|=PP_DEBUG; + } break; default: return -EINVAL; @@ -908,7 +921,7 @@ dev->hard_header = sppp_hard_header; dev->rebuild_header = sppp_rebuild_header; dev->tx_queue_len = 10; - dev->type = ARPHRD_PPP; + dev->type = ARPHRD_HDLC; dev->addr_len = 0; dev->hard_header_len = sizeof(struct ppp_header); dev->mtu = PPP_MTU; @@ -924,7 +937,7 @@ dev->change_mtu = sppp_change_mtu; dev->hard_header_cache = NULL; dev->header_cache_update = NULL; - dev->flags = IFF_MULTICAST; + dev->flags = IFF_MULTICAST|IFF_POINTOPOINT|IFF_NOARP; dev_init_buffers(dev); } diff -u --recursive --new-file v2.1.125/linux/drivers/net/syncppp.h linux/drivers/net/syncppp.h --- v2.1.125/linux/drivers/net/syncppp.h Wed Sep 9 14:51:08 1998 +++ linux/drivers/net/syncppp.h Sat Oct 17 15:33:45 1998 @@ -20,6 +20,7 @@ #ifndef _SYNCPPP_H_ #define _SYNCPPP_H_ 1 +#ifdef __KERNEL__ struct slcp { u16 state; /* state machine */ u32 magic; /* local magic number */ @@ -71,7 +72,6 @@ #define IPCP_STATE_ACK_SENT 2 /* IPCP state: conf-ack sent */ #define IPCP_STATE_OPENED 3 /* IPCP state: opened */ -#ifdef __KERNEL__ void sppp_attach (struct ppp_device *pd); void sppp_detach (struct device *dev); void sppp_input (struct device *dev, struct sk_buff *m); @@ -85,5 +85,6 @@ #define SPPPIOCCISCO (SIOCDEVPRIVATE) #define SPPPIOCPPP (SIOCDEVPRIVATE+1) +#define SPPPIOCDEBUG (SIOCDEVPRIVATE+2) #endif /* _SYNCPPP_H_ */ diff -u --recursive --new-file v2.1.125/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c --- v2.1.125/linux/drivers/net/via-rhine.c Fri Oct 9 13:27:09 1998 +++ linux/drivers/net/via-rhine.c Sat Oct 17 15:33:45 1998 @@ -65,7 +65,6 @@ #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ /* Include files, designed to support most kernel versions 2.0.0 and later. */ -#include #include #ifdef MODULE #ifdef MODVERSIONS @@ -512,9 +511,8 @@ } #ifndef MODULE -static int via_rhine_probe(struct device *dev) +int via_rhine_probe(struct device *dev) { - printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB); return pci_etherdev_probe(dev, pci_tbl); } #endif @@ -523,8 +521,12 @@ struct device *dev, long ioaddr, int irq, int chip_id, int card_idx) { + static int did_version = 0; /* Already printed version info */ struct netdev_private *np; int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0; + + if (debug > 0 && did_version++ == 0) + printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB); dev = init_etherdev(dev, 0); diff -u --recursive --new-file v2.1.125/linux/drivers/net/z85230.c linux/drivers/net/z85230.c --- v2.1.125/linux/drivers/net/z85230.c Wed Sep 9 14:51:08 1998 +++ linux/drivers/net/z85230.c Sat Oct 17 15:33:45 1998 @@ -152,8 +152,9 @@ 3, ENT_HM|RxCRC_ENAB|Rx8, 5, TxCRC_ENAB|RTS|TxENAB|Tx8|DTR, 9, 0, /* Disable interrupts */ + 6, 0xFF, 7, FLAG, - 10, ABUNDER|MARKIDLE|NRZ|CRCPS, + 10, ABUNDER|NRZ|CRCPS,/*MARKIDLE ??*/ 11, TCTRxCP, 14, DISDPLL, 15, DCDIE|SYNCIE|CTSIE|TxUIE|BRKIE, @@ -176,8 +177,9 @@ 3, ENT_HM|RxCRC_ENAB|Rx8, 5, TxCRC_ENAB|RTS|TxENAB|Tx8|DTR, 9, 0, /* Disable interrupts */ + 6, 0xFF, 7, FLAG, - 10, ABUNDER|MARKIDLE|NRZ|CRCPS, + 10, ABUNDER|NRZ|CRCPS, /* MARKIDLE?? */ 11, TCTRxCP, 14, DISDPLL, 15, DCDIE|SYNCIE|CTSIE|TxUIE|BRKIE, @@ -389,6 +391,8 @@ if(chan->rxdma_on) { /* Special condition check only */ + u8 r7=read_zsreg(chan, R7); + u8 r6=read_zsreg(chan, R6); u8 status=read_zsreg(chan, R1); if(status&END_FR) { @@ -418,6 +422,7 @@ static void z8530_dma_status(struct z8530_channel *chan) { + unsigned long flags; u8 status=read_zsreg(chan, R0); u8 altered=chan->status^status; @@ -427,10 +432,12 @@ { if(status&TxEOM) { + flags=claim_dma_lock(); /* Transmit underrun */ disable_dma(chan->txdma); clear_dma_ff(chan->txdma); chan->txdma_on=0; + release_dma_lock(flags); z8530_tx_done(chan); } } @@ -461,6 +468,15 @@ EXPORT_SYMBOL(z8530_dma_sync); +struct z8530_irqhandler z8530_txdma_sync= +{ + z8530_rx, + z8530_dma_tx, + z8530_dma_status +}; + +EXPORT_SYMBOL(z8530_txdma_sync); + /* * Interrupt vectors for a Z8530 that is in 'parked' mode. * For machines with PCI Z85x30 cards, or level triggered interrupts @@ -566,7 +582,7 @@ irqs->status(&dev->chanB); } } - if(work==200) + if(work==5000) printk(KERN_ERR "%s: interrupt jammed - abort(0x%X)!\n", dev->name, intr); /* Ok all done */ locker=0; @@ -619,6 +635,8 @@ int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c) { + unsigned long flags; + c->sync = 1; c->mtu = dev->mtu; c->count = 0; @@ -665,6 +683,7 @@ return -ENOBUFS; } c->tx_dma_used=0; + c->dma_tx = 1; c->dma_num=0; c->dma_ready=1; @@ -672,13 +691,23 @@ * Enable DMA control mode */ - c->regs[R1]|= WT_RDY_RT|WT_FN_RDYFN; + /* + * TX DMA via DIR/REQ + */ + + c->regs[R14]|= DTRREQ; + write_zsreg(c, R14, c->regs[R14]); + + /* + * RX DMA via W/Req + */ + + c->regs[R1]|= WT_FN_RDYFN; + c->regs[R1]|= WT_RDY_RT; c->regs[R1]|= INT_ERR_Rx; write_zsreg(c, R1, c->regs[R1]); c->regs[R1]|= WT_RDY_ENAB; write_zsreg(c, R1, c->regs[R1]); - c->regs[R14]|= DTRREQ; - write_zsreg(c, R14, c->regs[R14]); /* * DMA interrupts @@ -688,9 +717,11 @@ * Set up the DMA configuration */ + flags=claim_dma_lock(); + disable_dma(c->rxdma); clear_dma_ff(c->rxdma); - set_dma_mode(c->rxdma, DMA_MODE_READ); + set_dma_mode(c->rxdma, DMA_MODE_READ|0x10); set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[0])); set_dma_count(c->rxdma, c->mtu); enable_dma(c->rxdma); @@ -700,6 +731,8 @@ set_dma_mode(c->txdma, DMA_MODE_WRITE); disable_dma(c->txdma); + release_dma_lock(flags); + /* * Select the DMA interrupt handlers */ @@ -719,6 +752,8 @@ int z8530_sync_dma_close(struct device *dev, struct z8530_channel *c) { u8 chk; + unsigned long flags; + c->irqs = &z8530_nop; c->max = 0; c->sync = 0; @@ -726,12 +761,17 @@ /* * Disable the PC DMA channels */ - + + flags=claim_dma_lock(); disable_dma(c->rxdma); clear_dma_ff(c->rxdma); + c->rxdma_on = 0; + disable_dma(c->txdma); clear_dma_ff(c->txdma); + release_dma_lock(flags); + c->txdma_on = 0; c->tx_dma_used = 0; @@ -775,6 +815,137 @@ EXPORT_SYMBOL(z8530_sync_dma_close); +int z8530_sync_txdma_open(struct device *dev, struct z8530_channel *c) +{ + printk("Opening sync interface for TX-DMA\n"); + c->sync = 1; + c->mtu = dev->mtu; + c->count = 0; + c->skb = NULL; + c->skb2 = NULL; + + /* + * Load the PIO receive ring + */ + + z8530_rx_done(c); + z8530_rx_done(c); + + /* + * Load the DMA interfaces up + */ + + c->rxdma_on = 0; + c->txdma_on = 0; + + c->tx_dma_buf[0]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA); + if(c->tx_dma_buf[0]==NULL) + { + kfree(c->rx_buf[0]); + kfree(c->rx_buf[1]); + c->rx_buf[0]=NULL; + return -ENOBUFS; + } + c->tx_dma_buf[1]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA); + if(c->tx_dma_buf[1]==NULL) + { + kfree(c->tx_dma_buf[0]); + kfree(c->rx_buf[0]); + kfree(c->rx_buf[1]); + c->rx_buf[0]=NULL; + c->rx_buf[1]=NULL; + c->tx_dma_buf[0]=NULL; + return -ENOBUFS; + } + c->tx_dma_used=0; + c->dma_num=0; + c->dma_ready=1; + c->dma_tx = 1; + + /* + * Enable DMA control mode + */ + + /* + * TX DMA via DIR/REQ + */ + c->regs[R14]|= DTRREQ; + write_zsreg(c, R14, c->regs[R14]); + + /* + * Set up the DMA configuration + */ + + disable_dma(c->txdma); + clear_dma_ff(c->txdma); + set_dma_mode(c->txdma, DMA_MODE_WRITE); + disable_dma(c->txdma); + + /* + * Select the DMA interrupt handlers + */ + + c->rxdma_on = 0; + c->txdma_on = 1; + c->tx_dma_used = 1; + + c->irqs = &z8530_txdma_sync; + printk("Loading RX\n"); + z8530_rtsdtr(c,1); + printk("Rx interrupts ON\n"); + write_zsreg(c, R3, c->regs[R3]|RxENABLE); + return 0; +} + +EXPORT_SYMBOL(z8530_sync_txdma_open); + +int z8530_sync_txdma_close(struct device *dev, struct z8530_channel *c) +{ + u8 chk; + c->irqs = &z8530_nop; + c->max = 0; + c->sync = 0; + + /* + * Disable the PC DMA channels + */ + + disable_dma(c->txdma); + clear_dma_ff(c->txdma); + c->txdma_on = 0; + c->tx_dma_used = 0; + + /* + * Disable DMA control mode + */ + + c->regs[R1]&= ~WT_RDY_ENAB; + write_zsreg(c, R1, c->regs[R1]); + c->regs[R1]&= ~(WT_RDY_RT|WT_FN_RDYFN|INT_ERR_Rx); + c->regs[R1]|= INT_ALL_Rx; + write_zsreg(c, R1, c->regs[R1]); + c->regs[R14]&= ~DTRREQ; + write_zsreg(c, R14, c->regs[R14]); + + if(c->tx_dma_buf[0]) + { + kfree(c->tx_dma_buf[0]); + c->tx_dma_buf[0]=NULL; + } + if(c->tx_dma_buf[1]) + { + kfree(c->tx_dma_buf[1]); + c->tx_dma_buf[1]=NULL; + } + chk=read_zsreg(c,R0); + write_zsreg(c, R3, c->regs[R3]); + z8530_rtsdtr(c,0); + return 0; +} + + +EXPORT_SYMBOL(z8530_sync_txdma_close); + /* * Describe a Z8530 in a standard format. We must pass the I/O as * the port offset isnt predictable. The main reason for this function @@ -929,7 +1100,12 @@ if(c->tx_skb==NULL) { /* Idle on */ - disable_dma(c->txdma); + if(c->txdma) + { + flags=claim_dma_lock(); + disable_dma(c->txdma); + release_dma_lock(flags); + } c->txcount=0; } else @@ -938,19 +1114,22 @@ c->txcount=c->tx_skb->len; - if(c->tx_dma_used) + if(c->dma_tx) { /* - * FIXME. DMA is broken for the non 85230, + * FIXME. DMA is broken for the original 8530, * on the older parts we need to set a flag and * wait for a further TX interrupt to fire this * stage off */ + + flags=claim_dma_lock(); disable_dma(c->txdma); clear_dma_ff(c->txdma); set_dma_addr(c->txdma, virt_to_bus(c->tx_ptr)); set_dma_count(c->txdma, c->txcount); enable_dma(c->txdma); + release_dma_lock(flags); write_zsreg(c, R5, c->regs[R5]|TxENAB); } else @@ -1020,16 +1199,21 @@ * Save the ready state and the buffer currently * being used as the DMA target */ + int ready=c->dma_ready; - char *rxb=c->rx_buf[c->dma_num]; + unsigned char *rxb=c->rx_buf[c->dma_num]; + unsigned long flags; /* * Complete this DMA. Neccessary to find the length */ + + flags=claim_dma_lock(); + disable_dma(c->rxdma); clear_dma_ff(c->rxdma); c->rxdma_on=0; - ct=c->mtu-get_dma_residue(c->rxdma)-4; + ct=c->mtu-get_dma_residue(c->rxdma); if(ct<0) ct=2; /* Shit happens.. */ c->dma_ready=0; @@ -1042,16 +1226,21 @@ if(ready) { c->dma_num^=1; - set_dma_mode(c->rxdma, DMA_MODE_READ); + set_dma_mode(c->rxdma, DMA_MODE_READ|0x10); set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[c->dma_num])); set_dma_count(c->rxdma, c->mtu); c->rxdma_on = 1; enable_dma(c->rxdma); + /* Stop any frames that we missed the head of + from passing */ + write_zsreg(c, R0, RES_Rx_CRC); } else /* Can't occur as we dont reenable the DMA irq until after the flip is done */ printk("DMA flip overrun!\n"); + + release_dma_lock(flags); /* * Shove the old buffer into an sk_buff. We can't DMA @@ -1068,7 +1257,6 @@ { skb_put(skb, ct); memcpy(skb->data, rxb, ct); - skb_pull(skb,2); } c->dma_ready=1; } @@ -1127,6 +1315,21 @@ printk("Lost a frame\n"); } +/* + * Cannot DMA over a 64K boundary on a PC + */ + +extern inline int spans_boundary(struct sk_buff *skb) +{ + unsigned long a=(unsigned long)skb->data; + a^=(a+skb->len); + if(a&0x00010000) /* If the 64K bit is different.. */ + { + printk("spanner\n"); + return 1; + } + return 0; +} /* * Queue a packet for transmission. Because we have rather @@ -1151,7 +1354,7 @@ * limit, then copy to the flip buffer */ - if(c->dma_tx && (unsigned long)(virt_to_bus(skb->data+skb->len))>=16*1024*1024) + if(c->dma_tx && ((unsigned long)(virt_to_bus(skb->data+skb->len))>=16*1024*1024 || spans_boundary(skb))) { /* * Send the flip buffer, and flip the flippy bit. diff -u --recursive --new-file v2.1.125/linux/drivers/net/z85230.h linux/drivers/net/z85230.h --- v2.1.125/linux/drivers/net/z85230.h Wed Sep 9 14:51:08 1998 +++ linux/drivers/net/z85230.h Sat Oct 17 15:33:45 1998 @@ -272,8 +272,8 @@ u8 status; /* Current DCD */ u8 sync; /* Set if in sync mode */ - u8 regs[16]; /* Register map for the chip */ - u8 pendregs[16]; /* Pending register values */ + u8 regs[32]; /* Register map for the chip */ + u8 pendregs[32]; /* Pending register values */ struct sk_buff *tx_skb; /* Buffer being transmitted */ struct sk_buff *tx_next_skb; /* Next transmit buffer */ @@ -401,6 +401,8 @@ extern int z8530_sync_close(struct device *, struct z8530_channel *); extern int z8530_sync_dma_open(struct device *, struct z8530_channel *); extern int z8530_sync_dma_close(struct device *, struct z8530_channel *); +extern int z8530_sync_txdma_open(struct device *, struct z8530_channel *); +extern int z8530_sync_txdma_close(struct device *, struct z8530_channel *); extern int z8530_channel_load(struct z8530_channel *, u8 *); extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb); extern struct net_device_stats *z8530_get_stats(struct z8530_channel *c); diff -u --recursive --new-file v2.1.125/linux/drivers/net/znet.c linux/drivers/net/znet.c --- v2.1.125/linux/drivers/net/znet.c Thu Feb 12 20:56:09 1998 +++ linux/drivers/net/znet.c Tue Oct 20 13:17:41 1998 @@ -591,6 +591,7 @@ /* The inverse routine to znet_open(). */ static int znet_close(struct device *dev) { + unsigned long flags; int ioaddr = dev->base_addr; dev->tbusy = 1; @@ -598,8 +599,10 @@ outb(CMD0_RESET, ioaddr); /* CMD0_RESET */ + flags=claim_dma_lock(); disable_dma(zn.rx_dma); disable_dma(zn.tx_dma); + release_dma_lock(flags); free_irq(dev->irq, dev); @@ -662,16 +665,21 @@ void show_dma(void) { + unsigned long flags; short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE; unsigned addr = inb(dma_port); addr |= inb(dma_port) << 8; + + flags=claim_dma_lock(); printk("Addr: %04x cnt:%3x...", addr<<1, get_dma_residue(zn.tx_dma)); + release_dma_lock(flags); } /* Initialize the hardware. We have to do this when the board is open()ed or when we come out of suspend mode. */ static void hardware_init(struct device *dev) { + unsigned long flags; short ioaddr = dev->base_addr; zn.rx_cur = zn.rx_start; @@ -680,22 +688,22 @@ /* Reset the chip, and start it up. */ outb(CMD0_RESET, ioaddr); - cli(); { /* Protect against a DMA flip-flop */ - disable_dma(zn.rx_dma); /* reset by an interrupting task. */ - clear_dma_ff(zn.rx_dma); - set_dma_mode(zn.rx_dma, DMA_RX_MODE); - set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start); - set_dma_count(zn.rx_dma, RX_BUF_SIZE); - enable_dma(zn.rx_dma); - /* Now set up the Tx channel. */ - disable_dma(zn.tx_dma); - clear_dma_ff(zn.tx_dma); - set_dma_mode(zn.tx_dma, DMA_TX_MODE); - set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start); - set_dma_count(zn.tx_dma, zn.tx_buf_len<<1); - enable_dma(zn.tx_dma); - } sti(); - + flags=claim_dma_lock(); + disable_dma(zn.rx_dma); /* reset by an interrupting task. */ + clear_dma_ff(zn.rx_dma); + set_dma_mode(zn.rx_dma, DMA_RX_MODE); + set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start); + set_dma_count(zn.rx_dma, RX_BUF_SIZE); + enable_dma(zn.rx_dma); + /* Now set up the Tx channel. */ + disable_dma(zn.tx_dma); + clear_dma_ff(zn.tx_dma); + set_dma_mode(zn.tx_dma, DMA_TX_MODE); + set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start); + set_dma_count(zn.tx_dma, zn.tx_buf_len<<1); + enable_dma(zn.tx_dma); + release_dma_lock(flags); + if (znet_debug > 1) printk(KERN_DEBUG "%s: Initializing the i82593, tx buf %p... ", dev->name, zn.tx_start); diff -u --recursive --new-file v2.1.125/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c --- v2.1.125/linux/drivers/pci/oldproc.c Fri Oct 9 13:27:10 1998 +++ linux/drivers/pci/oldproc.c Sun Oct 11 15:46:03 1998 @@ -1,5 +1,5 @@ /* - * $Id: oldproc.c,v 1.20 1998/08/23 12:12:01 mj Exp $ + * $Id: oldproc.c,v 1.24 1998/10/11 15:13:04 mj Exp $ * * Backward-compatible procfs interface for PCI. * @@ -200,6 +200,7 @@ DEVICE( PROMISE, PROMISE_5300, "DC5030"), DEVICE( N9, N9_I128, "Imagine 128"), DEVICE( N9, N9_I128_2, "Imagine 128v2"), + DEVICE( N9, N9_I128_T2R, "Revolution 3D"), DEVICE( UMC, UMC_UM8673F, "UM8673F"), DEVICE( UMC, UMC_UM8891A, "UM8891A"), DEVICE( UMC, UMC_UM8886BF, "UM8886BF"), @@ -528,10 +529,10 @@ DEVICE( ADAPTEC, ADAPTEC_7883, "AIC-7883U"), DEVICE( ADAPTEC, ADAPTEC_7884, "AIC-7884U"), DEVICE( ADAPTEC, ADAPTEC_1030, "ABA-1030 DVB receiver"), - DEVICE( ADAPTEC2, ADAPTEC2_2940U2, "AHA-2940U2"), - DEVICE( ADAPTEC2, ADAPTEC2_7890, "AIC-7890/1"), - DEVICE( ADAPTEC2, ADAPTEC2_3940U2, "AHA-3940U2"), - DEVICE( ADAPTEC2, ADAPTEC2_7896, "AIC-7896/7"), + DEVICE( ADAPTEC2, ADAPTEC2_2940U2,"AHA-2940U2"), + DEVICE( ADAPTEC2, ADAPTEC2_7890, "AIC-7890/1"), + DEVICE( ADAPTEC2, ADAPTEC2_3940U2,"AHA-3940U2"), + DEVICE( ADAPTEC2, ADAPTEC2_7896, "AIC-7896/7"), DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL"), DEVICE( TIGERJET, TIGERJET_300, "Tiger300 ISDN"), DEVICE( ARK, ARK_STING, "Stingray"), diff -u --recursive --new-file v2.1.125/linux/drivers/pnp/parport_probe.c linux/drivers/pnp/parport_probe.c --- v2.1.125/linux/drivers/pnp/parport_probe.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/pnp/parport_probe.c Fri Oct 9 12:20:27 1998 @@ -91,7 +91,7 @@ int parport_probe(struct parport *port, char *buffer, int len) { - struct pardevice *dev = parport_register_device(port, "IEEE 1284 probe", NULL, NULL, NULL, PARPORT_DEV_TRAN, &dev); + struct pardevice *dev = parport_register_device(port, "IEEE 1284 probe", NULL, NULL, NULL, 0, &dev); int result = 0; diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in --- v2.1.125/linux/drivers/scsi/Config.in Thu Sep 17 17:53:36 1998 +++ linux/drivers/scsi/Config.in Fri Oct 9 12:20:27 1998 @@ -53,7 +53,7 @@ if [ "$CONFIG_PARPORT" != "n" ]; then dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI $CONFIG_PARPORT if [ "$CONFIG_SCSI_PPA" != "n" ]; then - int ' Pedantic EPP-checking' CONFIG_SCSI_PPA_HAVE_PEDANTIC 2 0 3 + bool ' Pedantic EPP-checking' CONFIG_SCSI_PPA_HAVE_PEDANTIC fi dep_tristate 'IOMEGA ZIP Plus drive SCSI support' CONFIG_SCSI_IMM $CONFIG_SCSI $CONFIG_PARPORT fi diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c --- v2.1.125/linux/drivers/scsi/NCR53c406a.c Thu May 14 19:47:40 1998 +++ linux/drivers/scsi/NCR53c406a.c Fri Oct 9 11:56:59 1998 @@ -317,15 +317,14 @@ if ((count & 1) || (((unsigned) ptr) & 1)) panic ("NCR53c406a: attempted unaligned DMA transfer\n"); - save_flags(flags); - cli(); + flags=claim_dma_lock(); disable_dma(dma_chan); clear_dma_ff(dma_chan); set_dma_addr(dma_chan, (long) ptr); set_dma_count(dma_chan, count); set_dma_mode(dma_chan, mode); enable_dma(dma_chan); - restore_flags(flags); + release_dma_lock(flags); return count; } @@ -343,12 +342,12 @@ static __inline__ int NCR53c406a_dma_residual (void) { register int tmp; - unsigned long flags = 0; - save_flags(flags); - cli(); + unsigned long flags; + + flags=claim_dma_lock(); clear_dma_ff(dma_chan); tmp = get_dma_residue(dma_chan); - restore_flags(flags); + release_dma_lock(flags); return tmp; } diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/README.aic7xxx linux/drivers/scsi/README.aic7xxx --- v2.1.125/linux/drivers/scsi/README.aic7xxx Fri Oct 9 13:27:10 1998 +++ linux/drivers/scsi/README.aic7xxx Fri Oct 9 11:56:59 1998 @@ -412,7 +412,7 @@ the system. Each file presents the current configuration and transfer statistics (enabled with #define in aic7xxx.c) for each controller. - Thanks to Michael Neuffer for for his upper-level SCSI help, and + Thanks to Michael Neuffer for his upper-level SCSI help, and Matthew Jacob for statistics support. Debugging the driver diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c --- v2.1.125/linux/drivers/scsi/aha152x.c Wed Sep 9 14:51:08 1998 +++ linux/drivers/scsi/aha152x.c Fri Oct 9 11:38:15 1998 @@ -444,6 +444,7 @@ /* set by aha152x_setup according to the command line */ static int setup_count=0; +static int registered_count=0; static struct aha152x_setup { int io_port; int irq; @@ -951,6 +952,7 @@ shpnt = aha152x_host[setup[i].irq-IRQ_MIN] = scsi_register(tpnt, sizeof(struct aha152x_hostdata)); + registered_count++; shpnt->io_port = setup[i].io_port; shpnt->n_io_port = IO_RANGE; @@ -1013,7 +1015,7 @@ SETBITS(DMACNTRL0, INTEN); - ok = request_irq(shpnt->irq, aha152x_swintr, SA_INTERRUPT, "aha152x", NULL); + ok = request_irq(shpnt->irq, aha152x_swintr, SA_INTERRUPT, "aha152x", shpnt); if(ok<0) { if(ok == -EINVAL) printk("aha152x%d: bad IRQ %d.\n", i, shpnt->irq); @@ -1024,6 +1026,8 @@ printk("aha152x: driver needs an IRQ.\n"); scsi_unregister(shpnt); + registered_count--; + release_region(shpnt->io_port, IO_RANGE); shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0; continue; } @@ -1037,7 +1041,7 @@ while(!HOSTDATA(shpnt)->swint && jiffiesirq,0); + free_irq(shpnt->irq,shpnt); if(!HOSTDATA(shpnt)->swint) { if(TESTHI(DMASTAT, INTSTAT)) { @@ -1049,6 +1053,8 @@ printk("aha152x: IRQ %d possibly wrong. Please verify.\n", shpnt->irq); scsi_unregister(shpnt); + registered_count--; + release_region(shpnt->io_port, IO_RANGE); shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0; continue; } @@ -1061,12 +1067,23 @@ SETPORT(SSTAT0, 0x7f); SETPORT(SSTAT1, 0xef); - if(request_irq(shpnt->irq,aha152x_intr,SA_INTERRUPT,"aha152x",NULL)<0) { + if(request_irq(shpnt->irq,aha152x_intr,SA_INTERRUPT,"aha152x",shpnt)<0) { printk("aha152x: failed to reassign interrupt.\n"); } } - return (setup_count>0); + return (registered_count>0); +} + + +int aha152x_release(struct Scsi_Host *shpnt) +{ + if (shpnt->irq) + free_irq(shpnt->irq, shpnt); + if (shpnt->io_port) + release_region(shpnt->io_port, IO_RANGE); + + return 0; } /* diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h --- v2.1.125/linux/drivers/scsi/aha152x.h Fri Jul 31 17:08:24 1998 +++ linux/drivers/scsi/aha152x.h Fri Oct 23 10:16:48 1998 @@ -15,6 +15,7 @@ int aha152x_command(Scsi_Cmnd *); int aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int aha152x_abort(Scsi_Cmnd *); +int aha152x_release(struct Scsi_Host *shpnt); int aha152x_reset(Scsi_Cmnd *, unsigned int); int aha152x_biosparam(Disk *, kdev_t, int*); int aha152x_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); @@ -36,6 +37,7 @@ queuecommand: aha152x_queue, \ abort: aha152x_abort, \ reset: aha152x_reset, \ + release: aha152x_release, \ slave_attach: 0, \ bios_param: aha152x_biosparam, \ can_queue: 1, \ diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aic7xxx/bsd_q.h linux/drivers/scsi/aic7xxx/bsd_q.h --- v2.1.125/linux/drivers/scsi/aic7xxx/bsd_q.h Fri Oct 9 13:27:10 1998 +++ linux/drivers/scsi/aic7xxx/bsd_q.h Wed Dec 31 16:00:00 1969 @@ -1,507 +0,0 @@ -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $Id: queue.h,v 1.21 1998/05/12 03:55:25 gibbs Exp $ - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * This file defines five types of data structures: singly-linked lists, - * slingly-linked tail queues, lists, tail queues, and circular queues. - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A singly-linked tail queue is headed by a pair of pointers, one to the - * head of the list and the other to the tail of the list. The elements are - * singly linked for minimum space and pointer manipulation overhead at the - * expense of O(n) removal for arbitrary elements. New elements can be added - * to the list after an existing element, at the head of the list, or at the - * end of the list. Elements being removed from the head of the tail queue - * should use the explicit macro for this purpose for optimum efficiency. - * A singly-linked tail queue may only be traversed in the forward direction. - * Singly-linked tail queues are ideal for applications with large datasets - * and few or no removals or for implementing a FIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may only be traversed in the forward direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - * - * - * SLIST LIST STAILQ TAILQ CIRCLEQ - * _HEAD + + + + + - * _ENTRY + + + + + - * _INIT + + + + + - * _EMPTY + + + + + - * _FIRST + + - + + - * _NEXT + + - + + - * _PREV - - - + + - * _LAST - - - + + - * _FOREACH + + - + - - * _INSERT_HEAD + + + + + - * _INSERT_BEFORE - + - + + - * _INSERT_AFTER + + + + + - * _INSERT_TAIL - - + + + - * _REMOVE_HEAD + - + - - - * _REMOVE + + + + + - * - */ - -/* - * Singly-linked List definitions. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) - -#define SLIST_FIRST(head) ((head)->slh_first) - -#define SLIST_FOREACH(var, head, field) \ - for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) - -#define SLIST_INIT(head) { \ - (head)->slh_first = NULL; \ -} - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (0) - -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if ((head)->slh_first == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = (head)->slh_first; \ - while( curelm->field.sle_next != (elm) ) \ - curelm = curelm->field.sle_next; \ - curelm->field.sle_next = \ - curelm->field.sle_next->field.sle_next; \ - } \ -} while (0) - -/* - * Singly-linked Tail queue definitions. - */ -#define STAILQ_HEAD(name, type) \ -struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ -} - -#define STAILQ_ENTRY(type) \ -struct { \ - struct type *stqe_next; /* next element */ \ -} - -/* - * Singly-linked Tail queue functions. - */ -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) - -#define STAILQ_INIT(head) do { \ - (head)->stqh_first = NULL; \ - (head)->stqh_last = &(head)->stqh_first; \ -} while (0) - -#define STAILQ_FIRST(head) ((head)->stqh_first) -#define STAILQ_LAST(head) (*(head)->stqh_last) - -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ - (head)->stqh_last = &(elm)->field.stqe_next; \ - (head)->stqh_first = (elm); \ -} while (0) - -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.stqe_next = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &(elm)->field.stqe_next; \ -} while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\ - (head)->stqh_last = &(elm)->field.stqe_next; \ - (tqelm)->field.stqe_next = (elm); \ -} while (0) - -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if (((head)->stqh_first = \ - (head)->stqh_first->field.stqe_next) == NULL) \ - (head)->stqh_last = &(head)->stqh_first; \ -} while (0) - -#define STAILQ_REMOVE(head, elm, type, field) do { \ - if ((head)->stqh_first == (elm)) { \ - STAILQ_REMOVE_HEAD(head, field); \ - } \ - else { \ - struct type *curelm = (head)->stqh_first; \ - while( curelm->field.stqe_next != (elm) ) \ - curelm = curelm->field.stqe_next; \ - if((curelm->field.stqe_next = \ - curelm->field.stqe_next->field.stqe_next) == NULL) \ - (head)->stqh_last = &(curelm)->field.stqe_next; \ - } \ -} while (0) - -/* - * List definitions. - */ - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_FOREACH(var, head, field) \ - for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next) - -#define LIST_INIT(head) do { \ - (head)->lh_first = NULL; \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (0) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ -} while (0) - -/* - * Tail queue definitions. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * Tail queue functions. - */ -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) - -#define TAILQ_FOREACH(var, head, field) \ - for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field)) - -#define TAILQ_FIRST(head) ((head)->tqh_first) - -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#define TAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ -} while (0) - -/* - * Circular queue definitions. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue functions. - */ -#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) - -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for((var) = (head)->cqh_first; \ - (var) != (void *)(head); \ - (var) = (var)->field.cqe_next) - -#define CIRCLEQ_INIT(head) do { \ - (head)->cqh_first = (void *)(head); \ - (head)->cqh_last = (void *)(head); \ -} while (0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == (void *)(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == (void *)(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = (void *)(head); \ - if ((head)->cqh_last == (void *)(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.cqe_next = (void *)(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == (void *)(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} while (0) - -#define CIRCLEQ_LAST(head) ((head)->cqh_last) - -#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) - -#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - if ((elm)->field.cqe_next == (void *)(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == (void *)(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ -} while (0) - -#ifdef KERNEL - -/* - * XXX insque() and remque() are an old way of handling certain queues. - * They bogusly assumes that all queue heads look alike. - */ - -struct quehead { - struct quehead *qh_link; - struct quehead *qh_rlink; -}; - -#ifdef __GNUC__ - -static __inline void -insque(void *a, void *b) -{ - struct quehead *element = a, *head = b; - - element->qh_link = head->qh_link; - element->qh_rlink = head; - head->qh_link = element; - element->qh_link->qh_rlink = element; -} - -static __inline void -remque(void *a) -{ - struct quehead *element = a; - - element->qh_link->qh_rlink = element->qh_rlink; - element->qh_rlink->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -#else /* !__GNUC__ */ - -void insque __P((void *a, void *b)); -void remque __P((void *a)); - -#endif /* __GNUC__ */ - -#endif /* KERNEL */ - -#endif /* !_SYS_QUEUE_H_ */ diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aic7xxx/sequencer.h linux/drivers/scsi/aic7xxx/sequencer.h --- v2.1.125/linux/drivers/scsi/aic7xxx/sequencer.h Fri Oct 9 13:27:10 1998 +++ linux/drivers/scsi/aic7xxx/sequencer.h Fri Oct 9 11:37:17 1998 @@ -73,7 +73,9 @@ union ins_formats format; unsigned int srcline; struct symbol *patch_label; - STAILQ_ENTRY(instruction) links; + struct { + struct instruction *stqe_next; + } links; }; #define AIC_OP_OR 0x0 diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c --- v2.1.125/linux/drivers/scsi/aic7xxx.c Fri Oct 9 13:27:10 1998 +++ linux/drivers/scsi/aic7xxx.c Sat Oct 10 09:30:16 1998 @@ -328,7 +328,6 @@ #include "hosts.h" #include "aic7xxx.h" -#include "aic7xxx/bsd_q.h" #include "aic7xxx/sequencer.h" #include "aic7xxx/scsi_message.h" #include "aic7xxx_reg.h" @@ -350,7 +349,7 @@ 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -#define AIC7XXX_C_VERSION "5.1.0" +#define AIC7XXX_C_VERSION "5.1.2" #define NUMBER(arr) (sizeof(arr) / sizeof(arr[0])) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) @@ -6281,8 +6280,10 @@ (((aic_inb(p, SEQADDR1) << 8) & 0x100) | aic_inb(p, SEQADDR0))); if (aic7xxx_panic_on_abort) aic7xxx_panic_abort(p, NULL); +#ifdef CONFIG_PCI if (errno & PCIERRSTAT) aic7xxx_pci_intr(p); +#endif if (errno & (SQPARERR | ILLOPCODE | ILLSADDR)) { sti(); diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c --- v2.1.125/linux/drivers/scsi/eata.c Tue Jul 28 14:21:08 1998 +++ linux/drivers/scsi/eata.c Fri Oct 9 11:56:59 1998 @@ -1034,12 +1034,17 @@ if (HD(j)->subversion == ESA) sh[j]->unchecked_isa_dma = FALSE; else { + unsigned long flags; sh[j]->wish_block = TRUE; sh[j]->unchecked_isa_dma = TRUE; + + flags=claim_dma_lock(); disable_dma(dma_channel); clear_dma_ff(dma_channel); set_dma_mode(dma_channel, DMA_MODE_CASCADE); enable_dma(dma_channel); + release_dma_lock(flags); + } strcpy(BN(j), name); diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c --- v2.1.125/linux/drivers/scsi/fdomain.c Sun Jul 26 11:57:16 1998 +++ linux/drivers/scsi/fdomain.c Wed Oct 14 11:43:14 1998 @@ -107,6 +107,7 @@ 2.0.12 5.44 8 Aug 1996 Use ID 7 for all PCI cards 2.1.1 5.45 2 Oct 1996 Update ROM accesses for 2.1.x 2.1.97 5.46 23 Apr 1998 Rewritten PCI detection routines [mj] + 2.1.11x 5.47 9 Aug 1998 Touched for 8 SCSI disk majors support @@ -1891,7 +1892,11 @@ 0x0a bytes long. Heads are one less than we need to report. */ - drive = MINOR(dev) / 16; + if (MAJOR(dev) != SCSI_DISK0_MAJOR) { + printk("fdomain_16x0_biosparam: too many disks"); + return 0; + } + drive = MINOR(dev) >> 4; if (bios_major == 2) { switch (Quantum) { diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/imm.c linux/drivers/scsi/imm.c --- v2.1.125/linux/drivers/scsi/imm.c Mon Sep 28 10:51:34 1998 +++ linux/drivers/scsi/imm.c Fri Oct 9 12:20:27 1998 @@ -172,14 +172,29 @@ imm_hosts[i].dev = parport_register_device(pb, "imm", NULL, imm_wakeup, - NULL, PARPORT_DEV_TRAN, (void *) &imm_hosts[i]); + NULL, 0, (void *) &imm_hosts[i]); + + if (!imm_hosts[i].dev) + continue; /* Claim the bus so it remembers what we do to the control * registers. [ CTR and ECP ] */ - if (imm_pb_claim(i)) - while (imm_hosts[i].p_busy) - schedule(); /* We are safe to schedule here */ + if (imm_pb_claim(i)) + { + unsigned long now = jiffies; + while (imm_hosts[i].p_busy) + { + schedule(); /* We are safe to schedule here */ + if (jiffies > now + 3*HZ) + { + printk(KERN_ERR "imm%d: failed to claim parport because a " + "pardevice is owning the port for too longtime!\n", + i); + return 0; + } + } + } ppb = IMM_BASE(i) = imm_hosts[i].dev->port->base; w_ctr(ppb, 0x0c); diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c --- v2.1.125/linux/drivers/scsi/ppa.c Mon Sep 28 10:51:34 1998 +++ linux/drivers/scsi/ppa.c Fri Oct 9 12:20:27 1998 @@ -133,14 +133,29 @@ ppa_hosts[i].dev = parport_register_device(pb, "ppa", NULL, ppa_wakeup, - NULL, PARPORT_DEV_TRAN, (void *) &ppa_hosts[i]); + NULL, 0, (void *) &ppa_hosts[i]); + + if (!ppa_hosts[i].dev) + continue; /* Claim the bus so it remembers what we do to the control * registers. [ CTR and ECP ] */ if (ppa_pb_claim(i)) + { + unsigned long now = jiffies; while (ppa_hosts[i].p_busy) + { schedule(); /* We are safe to schedule here */ + if (jiffies > now + 3*HZ) + { + printk(KERN_ERR "ppa%d: failed to claim parport because a " + "pardevice is owning the port for too longtime!\n", + i); + return 0; + } + } + } ppb = PPA_BASE(i) = ppa_hosts[i].dev->port->base; w_ctr(ppb, 0x0c); diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.1.125/linux/drivers/scsi/scsi.c Fri Oct 9 13:27:11 1998 +++ linux/drivers/scsi/scsi.c Wed Oct 14 11:43:13 1998 @@ -1734,8 +1734,7 @@ host_active = NULL; /* For block devices "wake_up" is done in end_scsi_request */ - if (MAJOR(SCpnt->request.rq_dev) != SCSI_DISK_MAJOR && - MAJOR(SCpnt->request.rq_dev) != SCSI_CDROM_MAJOR) { + if (!SCSI_BLK_MAJOR(SCpnt->request.rq_dev)) { struct Scsi_Host * next; for (next = host->block; next != host; next = next->block) diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h --- v2.1.125/linux/drivers/scsi/scsi.h Thu Sep 17 17:53:36 1998 +++ linux/drivers/scsi/scsi.h Fri Oct 23 10:15:54 1998 @@ -690,16 +690,22 @@ * that an interrupt may start another request, so we run this with interrupts * turned off */ -#define INIT_SCSI_REQUEST \ - if (!CURRENT) { \ - CLEAR_INTR; \ - return; \ - } \ - if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \ - panic(DEVICE_NAME ": request list destroyed");\ - if (CURRENT->bh) { \ - if (!buffer_locked(CURRENT->bh)) \ - panic(DEVICE_NAME ": block not locked"); \ +#if MAJOR_NR == SCSI_DISK0_MAJOR +#define CHECK_INITREQ_SD_MAJOR(major) SCSI_DISK_MAJOR(major) +#else +#define CHECK_INITREQ_SD_MAJOR(major) ((major) == MAJOR_NR) +#endif + +#define INIT_SCSI_REQUEST \ + if (!CURRENT) { \ + CLEAR_INTR; \ + return; \ + } \ + if (!CHECK_INITREQ_SD_MAJOR(MAJOR(CURRENT->rq_dev)))\ + panic(DEVICE_NAME ": request list destroyed"); \ + if (CURRENT->bh) { \ + if (!buffer_locked(CURRENT->bh)) \ + panic(DEVICE_NAME ": block not locked"); \ } #endif diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c --- v2.1.125/linux/drivers/scsi/scsi_debug.c Wed Sep 9 14:51:09 1998 +++ linux/drivers/scsi/scsi_debug.c Wed Oct 14 11:43:13 1998 @@ -42,8 +42,8 @@ /* A few options that we want selected */ -#define NR_HOSTS_PRESENT 1 -#define NR_FAKE_DISKS 3 +#define NR_HOSTS_PRESENT 20 +#define NR_FAKE_DISKS 6 #define N_HEAD 32 #define N_SECTOR 64 #define DISK_READONLY(TGT) (1) @@ -55,6 +55,8 @@ /* Skip some consistency checking. Good for benchmarking */ #define SPEEDY +/* Read return zeros. Undefine for benchmarking */ +#define CLEAR /* Number of real scsi disks that will be detected ahead of time */ static int NR_REAL=-1; @@ -299,11 +301,8 @@ #if defined(SCSI_SETUP_LATENCY) || defined(SCSI_DATARATE) { int delay = SCSI_SETUP_LATENCY; - double usec; - usec = 0.0; - usec = (SCpnt->request.nr_sectors << 9) * 1.0e6 / SCSI_DATARATE; - delay += usec; + delay += SCpnt->request.nr_sectors * SCSI_DATARATE; if(delay) usleep(delay); }; #endif @@ -323,29 +322,31 @@ do{ VERIFY1_DEBUG(READ); /* For the speedy test, we do not even want to fill the buffer with anything */ -#ifndef SPEEDY +#ifdef CLEAR memset(buff, 0, bufflen); #endif /* If this is block 0, then we want to read the partition table for this * device. Let's make one up */ - if(block == 0 && target == 0) { + if(block == 0) { + int i; memset(buff, 0, bufflen); *((unsigned short *) (buff+510)) = 0xAA55; p = (struct partition* ) (buff + 0x1be); - npart = 0; - while(starts[npart+1]){ - p->start_sect = starts[npart]; - p->nr_sects = starts[npart+1] - starts [npart]; + i = 0; + while(starts[i+1]){ + p->start_sect = starts[i]; + p->nr_sects = starts[i+1] - starts [i]; p->sys_ind = 0x81; /* Linux partition */ - p->head = (npart == 0 ? 1 : 0); + p->head = (i == 0 ? 1 : 0); p->sector = 1; - p->cyl = starts[npart] / N_HEAD / N_SECTOR; + p->cyl = starts[i] / N_HEAD / N_SECTOR; p->end_head = N_HEAD - 1; p->end_sector = N_SECTOR; - p->end_cyl = starts[npart + 1] / N_HEAD / N_SECTOR; + p->end_cyl = starts[i + 1] / N_HEAD / N_SECTOR; p++; - npart++; + i++; }; + if (!npart) npart = i; scsi_debug_errsts = 0; break; }; @@ -376,7 +377,7 @@ } /* End phony disk change code */ #endif -#ifndef SPEEDY +#ifdef CLEAR memcpy(buff, &target, sizeof(target)); memcpy(buff+sizeof(target), cmd, 24); memcpy(buff+60, &block, sizeof(block)); @@ -384,7 +385,7 @@ #endif nbytes -= bufflen; if(SCpnt->use_sg){ -#ifndef SPEEDY +#ifdef CLEAR memcpy(buff+128, bh, sizeof(struct buffer_head)); #endif block += bufflen >> 9; diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/scsi_obsolete.c linux/drivers/scsi/scsi_obsolete.c --- v2.1.125/linux/drivers/scsi/scsi_obsolete.c Fri Oct 9 13:27:11 1998 +++ linux/drivers/scsi/scsi_obsolete.c Wed Oct 14 11:43:13 1998 @@ -658,8 +658,7 @@ host_active = NULL; /* For block devices "wake_up" is done in end_scsi_request */ - if (MAJOR(SCpnt->request.rq_dev) != SCSI_DISK_MAJOR && - MAJOR(SCpnt->request.rq_dev) != SCSI_CDROM_MAJOR) { + if (!SCSI_BLK_MAJOR(SCpnt->request.rq_dev)) { struct Scsi_Host * next; for (next = host->block; next != host; next = next->block) diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c --- v2.1.125/linux/drivers/scsi/sd.c Mon Oct 5 13:13:40 1998 +++ linux/drivers/scsi/sd.c Wed Oct 14 11:43:13 1998 @@ -14,8 +14,11 @@ * * Modified by Eric Youngdale eric@aib.com to support loadable * low-level scsi drivers. + * + * Modified by Jirka Hanika geo@ff.cuni.cz to support more + * scsi disks using eight major numbers. */ - + #include #ifdef MODULE /* @@ -41,7 +44,7 @@ #include #include -#define MAJOR_NR SCSI_DISK_MAJOR +#define MAJOR_NR SCSI_DISK0_MAJOR #include #include "scsi.h" #include "hosts.h" @@ -54,6 +57,15 @@ /* * static const char RCSid[] = "$Header:"; */ + +#define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i)) + +#define SCSI_DISKS_PER_MAJOR 16 +#define SD_MAJOR_NUMBER(i) SD_MAJOR((i) >> 8) +#define SD_MINOR_NUMBER(i) ((i) & 255) +#define MKDEV_SD_PARTITION(i) MKDEV(SD_MAJOR_NUMBER(i), (i) & 255) +#define MKDEV_SD(index) MKDEV_SD_PARTITION((index) << 4) +#define N_USED_SD_MAJORS ((sd_template.dev_max + SCSI_DISKS_PER_MAJOR - 1) / SCSI_DISKS_PER_MAJOR) #define MAX_RETRIES 5 @@ -91,12 +103,9 @@ static void sd_devname(unsigned int disknum, char * buffer) { - if( disknum <= 26 ) - { + if( disknum < 26 ) sprintf(buffer, "sd%c", 'a' + disknum); - } - else - { + else { unsigned int min1; unsigned int min2; /* @@ -105,13 +114,13 @@ */ min1 = disknum / 26; min2 = disknum % 26; - sprintf(buffer, "sd%c%c", 'a' + min1, 'a' + min2); + sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2); } } struct Scsi_Device_Template sd_template = { NULL, "disk", "sd", NULL, TYPE_DISK, - SCSI_DISK_MAJOR, 0, 0, 0, 1, + SCSI_DISK0_MAJOR, 0, 0, 0, 1, sd_detect, sd_init, sd_finish, sd_attach, sd_detach }; @@ -175,7 +184,7 @@ * See if we are requesting a non-existent partition. Do this * after checking for disk change. */ - if(sd_sizes[MINOR(inode->i_rdev)] == 0) + if(sd_sizes[SD_PARTITION(inode->i_rdev)] == 0) return -ENXIO; if(rscsi_disks[target].device->removable) @@ -230,8 +239,13 @@ fop_revalidate_scsidisk /* revalidate */ }; +/* + * If we need more than one SCSI disk major (i.e. more than + * 16 SCSI disks), we'll have to kmalloc() more gendisks later. + */ + static struct gendisk sd_gendisk = { - MAJOR_NR, /* Major number */ + SCSI_DISK0_MAJOR, /* Major number */ "sd", /* Major name */ 4, /* Bits to shift to get real from partition */ 1 << 4, /* Number of partitions per real */ @@ -242,7 +256,12 @@ 0, /* number */ NULL, /* internal */ NULL /* next */ -}; +}; + +static struct gendisk *sd_gendisks = &sd_gendisk; + +#define SD_GENDISK(i) sd_gendisks[(i) / SCSI_DISKS_PER_MAJOR] +#define LAST_SD_GENDISK sd_gendisks[N_USED_SD_MAJORS - 1] static void sd_geninit (struct gendisk *ignored) { @@ -251,10 +270,6 @@ for (i = 0; i < sd_template.dev_max; ++i) if(rscsi_disks[i].device) sd[i << 4].nr_sects = rscsi_disks[i].capacity; -#if 0 - /* No longer needed - we keep track of this as we attach/detach */ - sd_gendisk.nr_real = sd_template.dev_max; -#endif } /* @@ -271,7 +286,7 @@ int good_sectors = (result == 0 ? this_count : 0); int block_sectors = 1; - sd_devname(MINOR(SCpnt->request.rq_dev) >> 4, nbuff); + sd_devname(DEVICE_NR(SCpnt->request.rq_dev), nbuff); SCSI_LOG_HLCOMPLETE(1,printk("%s : rw_intr(%d, %x [%x %x])\n", nbuff, SCpnt->host->host_no, @@ -309,7 +324,7 @@ } else if (sector_size == 256) error_sector >>= 1; - error_sector -= sd[MINOR(SCpnt->request.rq_dev)].start_sect; + error_sector -= sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect; error_sector &= ~ (block_sectors - 1); good_sectors = error_sector - SCpnt->request.sector; if (good_sectors < 0 || good_sectors >= this_count) @@ -524,7 +539,7 @@ } INIT_SCSI_REQUEST; - SDev = rscsi_disks[DEVICE_NR(CURRENT->rq_dev)].device; + SDev = rscsi_disks[CURRENT_DEV].device; /* * If the host for this device is in error recovery mode, don't @@ -578,7 +593,7 @@ if (flag++ == 0) SCpnt = scsi_allocate_device(&CURRENT, - rscsi_disks[DEVICE_NR(CURRENT->rq_dev)].device, 0); + rscsi_disks[CURRENT_DEV].device, 0); else SCpnt = NULL; /* @@ -643,7 +658,7 @@ return; } - devm = MINOR(SCpnt->request.rq_dev); + devm = SD_PARTITION(SCpnt->request.rq_dev); dev = DEVICE_NR(SCpnt->request.rq_dev); block = SCpnt->request.sector; @@ -1329,7 +1344,7 @@ printk ("scsi : deleting disk entry.\n"); rscsi_disks[i].device = NULL; sd_template.nr_dev--; - sd_gendisk.nr_real--; + SD_GENDISK(i).nr_real--; /* Wake up a process waiting for device */ wake_up(&SCpnt->device->device_wait); @@ -1463,67 +1478,99 @@ if (sd_template.dev_noticed == 0) return 0; + if (!rscsi_disks) + sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS; + + /* 128 disks is our current limit (8 majors, 16 disks per major) */ + if(sd_template.dev_max > 128) + sd_template.dev_max = 128; + if(!sd_registered) { - if (register_blkdev(MAJOR_NR,"sd",&sd_fops)) { - printk("Unable to get major %d for SCSI disk\n",MAJOR_NR); - return 1; - } - sd_registered++; - } + for (i=0; i <= sd_template.dev_max / SCSI_DISKS_PER_MAJOR; i++) { + if (register_blkdev(SD_MAJOR(i),"sd",&sd_fops)) { + printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i)); + return 1; + } + } + sd_registered++; + } /* We do not support attaching loadable devices yet. */ if(rscsi_disks) return 0; - sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS; - rscsi_disks = (Scsi_Disk *) scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC); memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk)); - - sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * - sizeof(int), GFP_ATOMIC); + + /* for every (necessary) major: */ + sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int)); - sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * - sizeof(int), GFP_ATOMIC); - - sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * - sizeof(int), GFP_ATOMIC); + sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); + sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(int), GFP_ATOMIC); - for(i=0;i<(sd_template.dev_max << 4);i++) - { - sd_blocksizes[i] = 1024; - sd_hardsizes[i] = 512; - } + for(i=0; i < sd_template.dev_max << 4; i++) { + sd_blocksizes[i] = 1024; + sd_hardsizes[i] = 512; + } - blksize_size[MAJOR_NR] = sd_blocksizes; - hardsect_size[MAJOR_NR] = sd_hardsizes; + for (i=0; i < N_USED_SD_MAJORS; i++) { + blksize_size[SD_MAJOR(i)] = sd_blocksizes + i * (SCSI_DISKS_PER_MAJOR << 4); + hardsect_size[SD_MAJOR(i)] = sd_hardsizes + i * (SCSI_DISKS_PER_MAJOR << 4); + } sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) * sizeof(struct hd_struct), GFP_ATOMIC); - - sd_gendisk.max_nr = sd_template.dev_max; - sd_gendisk.part = sd; - sd_gendisk.sizes = sd_sizes; - sd_gendisk.real_devices = (void *) rscsi_disks; + if (N_USED_SD_MAJORS > 1) + sd_gendisks = (struct gendisk *) + kmalloc(N_USED_SD_MAJORS * sizeof(struct gendisk), GFP_ATOMIC); + for (i=0; i < N_USED_SD_MAJORS; i++) { + sd_gendisks[i].major = SD_MAJOR(i); + sd_gendisks[i].major_name = "sd"; + sd_gendisks[i].minor_shift = 4; + sd_gendisks[i].max_p = 1 << 4; + sd_gendisks[i].max_nr = SCSI_DISKS_PER_MAJOR; + sd_gendisks[i].init = sd_geninit; + sd_gendisks[i].part = sd + (i * SCSI_DISKS_PER_MAJOR << 4); + sd_gendisks[i].sizes = sd_sizes + (i * SCSI_DISKS_PER_MAJOR << 4); + sd_gendisks[i].nr_real = 0; + sd_gendisks[i].next = sd_gendisks + i + 1; + sd_gendisks[i].real_devices = + (void *) (rscsi_disks + i * SCSI_DISKS_PER_MAJOR); + } + LAST_SD_GENDISK.max_nr = + sd_template.dev_max % SCSI_DISKS_PER_MAJOR; + LAST_SD_GENDISK.next = NULL; return 0; } +/* + * sd_get_queue() returns the queue which corresponds to a given device. + */ +static struct request **sd_get_queue (kdev_t dev) +{ + return &blk_dev[MAJOR_NR].current_request; +} + static void sd_finish() { struct gendisk *gendisk; int i; - blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; + for (i=0; i <= sd_template.dev_max / SCSI_DISKS_PER_MAJOR; i++) { + /* FIXME: After 2.2 we should implement multiple sd queues */ + blk_dev[SD_MAJOR(i)].request_fn = DEVICE_REQUEST; + if (i) blk_dev[SD_MAJOR(i)].queue = sd_get_queue; + } for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next) - if (gendisk == &sd_gendisk) + if (gendisk == sd_gendisks) break; if (gendisk == NULL) { - sd_gendisk.next = gendisk_head; - gendisk_head = &sd_gendisk; + LAST_SD_GENDISK.next = gendisk_head; + gendisk_head = sd_gendisks; } for (i = 0; i < sd_template.dev_max; ++i) @@ -1534,7 +1581,7 @@ && !rscsi_disks[i].has_part_table) { sd_sizes[i << 4] = rscsi_disks[i].capacity; /* revalidate does sd_init_onedisk via MAYBE_REINIT*/ - revalidate_scsidisk(MKDEV(MAJOR_NR, i << 4), 0); + revalidate_scsidisk(MKDEV_SD(i), 0); } else i=sd_init_onedisk(i); @@ -1542,13 +1589,17 @@ } /* If our host adapter is capable of scatter-gather, then we increase - * the read-ahead to 16 blocks (32 sectors). If not, we use - * a two block (4 sector) read ahead. + * the read-ahead to 60 blocks (120 sectors). If not, we use + * a two block (4 sector) read ahead. We can only respect this with the + * granularity of every 16 disks (one device major). */ - if(rscsi_disks[0].device && rscsi_disks[0].device->host->sg_tablesize) - read_ahead[MAJOR_NR] = 120; /* 120 sector read-ahead */ - else - read_ahead[MAJOR_NR] = 4; /* 4 sector read-ahead */ + for (i=0; i < N_USED_SD_MAJORS; i++) { + read_ahead[SD_MAJOR(i)] = + (rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device + && rscsi_disks[i * SCSI_DISKS_PER_MAJOR].device->host->sg_tablesize) + ? 120 /* 120 sector read-ahead */ + : 4; /* 4 sector read-ahead */ + } return; } @@ -1586,7 +1637,7 @@ rscsi_disks[i].device = SDp; rscsi_disks[i].has_part_table = 0; sd_template.nr_dev++; - sd_gendisk.nr_real++; + SD_GENDISK(i).nr_real++; return 0; } @@ -1594,7 +1645,6 @@ #define USAGE rscsi_disks[target].device->access_count #define CAPACITY rscsi_disks[target].capacity #define MAYBE_REINIT sd_init_onedisk(target) -#define GENDISK_STRUCT sd_gendisk /* This routine is called to flush all partitions and partition tables * for a changed scsi disk, and then re-read the new partition table. @@ -1603,15 +1653,13 @@ * usage == 1 (we need an open channel to use an ioctl :-), so this * is our limit. */ -int revalidate_scsidisk(kdev_t dev, int maxusage){ +int revalidate_scsidisk(kdev_t dev, int maxusage) { int target; - struct gendisk * gdev; int max_p; int start; int i; target = DEVICE_NR(dev); - gdev = &GENDISK_STRUCT; if (DEVICE_BUSY || USAGE > maxusage) { printk("Device busy for revalidation (usage=%d)\n", USAGE); @@ -1619,37 +1667,38 @@ } DEVICE_BUSY = 1; - max_p = gdev->max_p; - start = target << gdev->minor_shift; + max_p = sd_gendisks->max_p; + start = target << sd_gendisks->minor_shift; for (i=max_p - 1; i >=0 ; i--) { - int minor = start+i; - kdev_t devi = MKDEV(MAJOR_NR, minor); + int index = start+i; + kdev_t devi = MKDEV_SD_PARTITION(index); struct super_block *sb = get_super(devi); sync_dev(devi); if (sb) invalidate_inodes(sb); invalidate_buffers(devi); - gdev->part[minor].start_sect = 0; - gdev->part[minor].nr_sects = 0; + sd_gendisks->part[index].start_sect = 0; + sd_gendisks->part[index].nr_sects = 0; /* * Reset the blocksize for everything so that we can read * the partition table. Technically we will determine the * correct block size when we revalidate, but we do this just * to make sure that everything remains consistent. */ - blksize_size[MAJOR_NR][minor] = 1024; + sd_blocksizes[index] = 1024; if( rscsi_disks[target].sector_size == 2048 ) - blksize_size[MAJOR_NR][minor] = 2048; + sd_blocksizes[index] = 2048; else - blksize_size[MAJOR_NR][minor] = 1024; + sd_blocksizes[index] = 1024; } #ifdef MAYBE_REINIT MAYBE_REINIT; #endif - gdev->part[start].nr_sects = CAPACITY; - resetup_one_dev(gdev, target); + sd_gendisks->part[start].nr_sects = CAPACITY; + resetup_one_dev(&SD_GENDISK(target), + target % SCSI_DISKS_PER_MAJOR); DEVICE_BUSY = 0; return 0; @@ -1676,15 +1725,15 @@ start = i << sd_gendisk.minor_shift; for (i=max_p - 1; i >=0 ; i--) { - int minor = start+i; - kdev_t devi = MKDEV(MAJOR_NR, minor); + int index = start+i; + kdev_t devi = MKDEV_SD_PARTITION(index); struct super_block *sb = get_super(devi); sync_dev(devi); if (sb) invalidate_inodes(sb); invalidate_buffers(devi); - sd_gendisk.part[minor].start_sect = 0; - sd_gendisk.part[minor].nr_sects = 0; - sd_sizes[minor] = 0; + sd_gendisks->part[index].start_sect = 0; + sd_gendisks->part[index].nr_sects = 0; + sd_sizes[index] = 0; } dpnt->has_part_table = 0; @@ -1693,7 +1742,7 @@ SDp->attached--; sd_template.dev_noticed--; sd_template.nr_dev--; - sd_gendisk.nr_real--; + SD_GENDISK(start).nr_real--; return; } return; @@ -1710,48 +1759,48 @@ { struct gendisk * prev_sdgd; struct gendisk * sdgd; + int i; + int removed = 0; scsi_unregister_module(MODULE_SCSI_DEV, &sd_template); - unregister_blkdev(SCSI_DISK_MAJOR, "sd"); + + for (i=0; i <= sd_template.dev_max / SCSI_DISKS_PER_MAJOR; i++) + unregister_blkdev(SD_MAJOR(i),"sd"); + sd_registered--; if( rscsi_disks != NULL ) { - scsi_init_free((char *) rscsi_disks, - (sd_template.dev_noticed + SD_EXTRA_DEVS) - * sizeof(Scsi_Disk)); - + scsi_init_free((char *) rscsi_disks, + sd_template.dev_max * sizeof(Scsi_Disk)); scsi_init_free((char *) sd_sizes, sd_template.dev_max * sizeof(int)); scsi_init_free((char *) sd_blocksizes, sd_template.dev_max * sizeof(int)); scsi_init_free((char *) sd_hardsizes, sd_template.dev_max * sizeof(int)); scsi_init_free((char *) sd, (sd_template.dev_max << 4) * sizeof(struct hd_struct)); /* - * Now remove sd_gendisk from the linked list + * Now remove sd_gendisks from the linked list */ - sdgd = gendisk_head; - prev_sdgd = NULL; - while(sdgd != &sd_gendisk) - { - prev_sdgd = sdgd; - sdgd = sdgd->next; - } - if(sdgd != &sd_gendisk) - printk("sd_gendisk not in disk chain.\n"); - else { - if(prev_sdgd != NULL) - prev_sdgd->next = sdgd->next; - else - gendisk_head = sdgd->next; - } + for (sdgd = gendisk_head; sdgd; sdgd = sdgd->next) + { + if (sdgd->next >= sd_gendisks && sdgd->next <= LAST_SD_GENDISK) + removed++, sdgd->next = sdgd->next->next; + else sdgd = sdgd->next; + } + if (removed != N_USED_SCSI_DISKS) + printk("%s %d sd_gendisks in disk chain", + removed > N_USED_SCSI_DISKS ? "total" : "just", removed); + } - blksize_size[MAJOR_NR] = NULL; - blk_dev[MAJOR_NR].request_fn = NULL; - blk_size[MAJOR_NR] = NULL; - hardsect_size[MAJOR_NR] = NULL; - read_ahead[MAJOR_NR] = 0; + for (i=0; i <= sd_template.dev_max / SCSI_DISKS_PER_MAJOR; i++) { + blk_dev[SD_MAJOR(i)].request_fn = NULL; + blk_size[SD_MAJOR(i)] = NULL; + hardsect_size[SD_MAJOR(i)] = NULL; + read_ahead[SD_MAJOR(i)] = 0; + } sd_template.dev_max = 0; + if (sd_gendisks != &sd_gendisk) kfree(sd_gendisks); } #endif /* MODULE */ diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/sd.h linux/drivers/scsi/sd.h --- v2.1.125/linux/drivers/scsi/sd.h Fri Jul 31 17:07:58 1998 +++ linux/drivers/scsi/sd.h Fri Oct 23 10:16:03 1998 @@ -42,6 +42,11 @@ extern int revalidate_scsidisk(kdev_t dev, int maxusage); +#define N_SD_MAJORS 8 + +#define SD_MAJOR_MASK (N_SD_MAJORS - 1) +#define SD_PARTITION(i) (((MAJOR(i) & SD_MAJOR_MASK) << 8) | (MINOR(i) & 255)) + #endif /* diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/sd_ioctl.c linux/drivers/scsi/sd_ioctl.c --- v2.1.125/linux/drivers/scsi/sd_ioctl.c Thu May 7 22:51:51 1998 +++ linux/drivers/scsi/sd_ioctl.c Wed Oct 14 11:43:14 1998 @@ -13,6 +13,7 @@ #include +#define MAJOR_NR SCSI_DISK0_MAJOR #include #include "scsi.h" #include @@ -29,7 +30,7 @@ int diskinfo[4]; struct hd_geometry *loc = (struct hd_geometry *) arg; - SDev = rscsi_disks[MINOR(dev) >> 4].device; + SDev = rscsi_disks[DEVICE_NR(dev)].device; /* * If we are in the middle of error recovery, don't let anyone * else try and use this device. Also, if error recovery fails, it @@ -47,34 +48,34 @@ error = verify_area(VERIFY_WRITE, loc, sizeof(*loc)); if (error) return error; - host = rscsi_disks[MINOR(dev) >> 4].device->host; + host = rscsi_disks[DEVICE_NR(dev)].device->host; /* default to most commonly used values */ diskinfo[0] = 0x40; diskinfo[1] = 0x20; - diskinfo[2] = rscsi_disks[MINOR(dev) >> 4].capacity >> 11; + diskinfo[2] = rscsi_disks[DEVICE_NR(dev)].capacity >> 11; /* override with calculated, extended default, or driver values */ if(host->hostt->bios_param != NULL) - host->hostt->bios_param(&rscsi_disks[MINOR(dev) >> 4], + host->hostt->bios_param(&rscsi_disks[DEVICE_NR(dev)], dev, &diskinfo[0]); - else scsicam_bios_param(&rscsi_disks[MINOR(dev) >> 4], + else scsicam_bios_param(&rscsi_disks[DEVICE_NR(dev)], dev, &diskinfo[0]); put_user(diskinfo[0], &loc->heads); put_user(diskinfo[1], &loc->sectors); put_user(diskinfo[2], &loc->cylinders); - put_user(sd[MINOR(inode->i_rdev)].start_sect, &loc->start); + put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start); return 0; case BLKGETSIZE: /* Return device size */ if (!arg) return -EINVAL; error = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long)); if (error) return error; - put_user(sd[MINOR(inode->i_rdev)].nr_sects, + put_user(sd[SD_PARTITION(inode->i_rdev)].nr_sects, (long *) arg); return 0; @@ -110,7 +111,7 @@ RO_IOCTLS(dev, arg); default: - return scsi_ioctl(rscsi_disks[MINOR(dev) >> 4].device , cmd, (void *) arg); + return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device , cmd, (void *) arg); } } diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c --- v2.1.125/linux/drivers/scsi/u14-34f.c Tue Jul 28 14:21:08 1998 +++ linux/drivers/scsi/u14-34f.c Fri Oct 9 11:56:59 1998 @@ -844,12 +844,17 @@ bus_type = "VESA"; } else { + unsigned long flags; sh[j]->wish_block = TRUE; sh[j]->unchecked_isa_dma = TRUE; + + flags=claim_dma_lock(); disable_dma(dma_channel); clear_dma_ff(dma_channel); set_dma_mode(dma_channel, DMA_MODE_CASCADE); enable_dma(dma_channel); + release_dma_lock(flags); + sh[j]->dma_channel = dma_channel; sprintf(BN(j), "U14F%d", j); bus_type = "ISA"; diff -u --recursive --new-file v2.1.125/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c --- v2.1.125/linux/drivers/scsi/wd7000.c Wed Sep 9 14:51:09 1998 +++ linux/drivers/scsi/wd7000.c Fri Oct 9 11:56:59 1998 @@ -772,10 +772,15 @@ static inline void wd7000_enable_dma (Adapter *host) { + unsigned long flags; host->control |= DMA_EN; outb (host->control, host->iobase + ASC_CONTROL); + + flags = claim_dma_lock(); set_dma_mode (host->dma, DMA_MODE_CASCADE); enable_dma (host->dma); + release_dma_lock(flags); + } diff -u --recursive --new-file v2.1.125/linux/drivers/sound/Config.in linux/drivers/sound/Config.in --- v2.1.125/linux/drivers/sound/Config.in Thu Sep 17 17:53:37 1998 +++ linux/drivers/sound/Config.in Sat Oct 17 15:33:45 1998 @@ -11,6 +11,9 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then dep_tristate 'Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND + if [ "$CONFIG_SOUND_ES1370" = "y" ]; then + bool 'Joystick support at boot time' CONFIG_SOUND_ES1370_JOYPORT_BOOT + fi dep_tristate 'Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND dep_tristate 'S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND fi @@ -20,11 +23,11 @@ if [ "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then comment 'Compiled-in MSND Classic support requires firmware during compilation.' define_bool CONFIG_MSNDCLAS_HAVE_BOOT y - string ' Full pathname of MSNDINIT.BIN firmware file' CONFIG_MSNDCLAS_INIT_FILE "/etc/sound/msndinit.bin" - string ' Full pathname of MSNDPERM.BIN firmware file' CONFIG_MSNDCLAS_PERM_FILE "/etc/sound/msndperm.bin" else define_bool CONFIG_MSNDCLAS_HAVE_BOOT n fi + string ' Full pathname of MSNDINIT.BIN firmware file' CONFIG_MSNDCLAS_INIT_FILE "/etc/sound/msndinit.bin" + string ' Full pathname of MSNDPERM.BIN firmware file' CONFIG_MSNDCLAS_PERM_FILE "/etc/sound/msndperm.bin" fi if [ "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then int 'MSND Classic IRQ 5,7,9,10,11,12' CONFIG_MSNDCLAS_IRQ 5 @@ -36,29 +39,29 @@ if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDPIN" = "m" ]; then if [ "$CONFIG_SOUND_MSNDPIN" = "y" ]; then comment 'Compiled-in MSND Pinnacle support requires firmware during compilation.' - string ' Full pathname of PNDSPINI.BIN firmware file' CONFIG_MSNDPIN_INIT_FILE "/etc/sound/pndspini.bin" - string ' Full pathname of PNDSPERM.BIN firmware file' CONFIG_MSNDPIN_PERM_FILE "/etc/sound/pndsperm.bin" define_bool CONFIG_MSNDPIN_HAVE_BOOT y else define_bool CONFIG_MSNDPIN_HAVE_BOOT n fi + string ' Full pathname of PNDSPINI.BIN firmware file' CONFIG_MSNDPIN_INIT_FILE "/etc/sound/pndspini.bin" + string ' Full pathname of PNDSPERM.BIN firmware file' CONFIG_MSNDPIN_PERM_FILE "/etc/sound/pndsperm.bin" fi if [ "$CONFIG_SOUND_MSNDPIN" = "y" ]; then int 'MSND Pinnacle IRQ 5,7,9,10,11,12' CONFIG_MSNDPIN_IRQ 5 hex 'MSND Pinnacle memory B0000,C8000,D0000,D8000,E0000,E8000' CONFIG_MSNDPIN_MEM D0000 hex 'MSND Pinnacle I/O 210,220,230,240,250,260,290,3E0' CONFIG_MSNDPIN_IO 290 bool 'MSND Pinnacle has S/PDIF I/O' CONFIG_MSNDPIN_DIGITAL - bool 'MSND Pinnacle Non-PnP Mode' CONFIG_MSNDPIN_NONPNP + bool 'MSND Pinnacle non-PnP Mode' CONFIG_MSNDPIN_NONPNP if [ "$CONFIG_MSNDPIN_NONPNP" = "y" ]; then comment 'MSND Pinnacle DSP section will be configured to above parameters.' - hex 'MSDN Pinnacle config port 250,260,270' CONFIG_MSNDPIN_CFG 250 + hex 'MSND Pinnacle config port 250,260,270' CONFIG_MSNDPIN_CFG 250 comment 'Pinnacle-specific Device Configuration (0 disables)' hex 'MSND Pinnacle MPU I/O (e.g. 330)' CONFIG_MSNDPIN_MPU_IO 0 int 'MSND Pinnacle MPU IRQ (e.g. 9)' CONFIG_MSNDPIN_MPU_IRQ 0 hex 'MSND Pinnacle IDE I/O 0 (e.g. 170)' CONFIG_MSNDPIN_IDE_IO0 0 hex 'MSND Pinnacle IDE I/O 1 (e.g. 376)' CONFIG_MSNDPIN_IDE_IO1 0 int 'MSND Pinnacle IDE IRQ (e.g. 15)' CONFIG_MSNDPIN_IDE_IRQ 0 - hex 'MSDN Pinnacle joystick I/O (e.g. 200)' CONFIG_MSNDPIN_JOYSTICK_IO 0 + hex 'MSND Pinnacle joystick I/O (e.g. 200)' CONFIG_MSNDPIN_JOYSTICK_IO 0 fi fi if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then @@ -190,6 +193,16 @@ int 'CS4232 second (duplex) DMA 0, 1 or 3' CONFIG_CS4232_DMA2 3 hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_CS4232_MPU_BASE 330 int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_MPU_IRQ 9 + fi + + dep_tristate 'Support for Yamaha OPL3-SA[2,3,x] based (PnP) cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS + if [ "$CONFIG_SOUND_OPL3SA2" = "y" ]; then + hex 'OPL3SA2 audio I/O base 530, 604, E80 or F40' CONFIG_OPL3SA2_BASE 530 + int 'OPL3SA2 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_IRQ 11 + int 'OPL3SA2 audio DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA 0 + int 'OPL3SA2 second (duplex) DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA2 1 + hex 'OPL3SA2 MIDI I/O base 330, 370, 3B0 or 3F0' CONFIG_OPL3SA2_MPU_BASE 330 + int 'OPL3SA2 MIDI IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_MPU_IRQ 9 fi dep_tristate 'Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_SOUND_MAUI $CONFIG_SOUND_OSS diff -u --recursive --new-file v2.1.125/linux/drivers/sound/Makefile linux/drivers/sound/Makefile --- v2.1.125/linux/drivers/sound/Makefile Thu Sep 17 17:53:37 1998 +++ linux/drivers/sound/Makefile Fri Oct 9 11:56:59 1998 @@ -72,6 +72,7 @@ obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o obj-$(CONFIG_SOUND_MSS) += ad1848.o obj-$(CONFIG_SOUND_OPL3SA1) += opl3sa.o ad1848.o uart401.o +obj-$(CONFIG_SOUND_OPL3SA2) += opl3sa2.o ad1848.o uart401.o mpu401.o obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o uart401.o obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o obj-$(CONFIG_SOUND_SB) += sb.o uart401.o @@ -219,7 +220,7 @@ ifeq ($(CONFIG_MAUI_HAVE_BOOT),y) maui_boot.h: $(patsubst "%", %, $(CONFIG_MAUI_BOOT_FILE)) bin2hex - bin2hex -i maui_os < $(CONFIG_MAUI_BOOT_FILE) > $@ + ./bin2hex -i maui_os < $(CONFIG_MAUI_BOOT_FILE) > $@ else maui_boot.h: ( \ diff -u --recursive --new-file v2.1.125/linux/drivers/sound/Readme linux/drivers/sound/Readme --- v2.1.125/linux/drivers/sound/Readme Thu Jul 16 18:09:26 1998 +++ linux/drivers/sound/Readme Fri Oct 9 11:56:59 1998 @@ -168,7 +168,7 @@ with impossible parameters. Check that the application is for sound driver version 2.X or later. -In general the printout of of /dev/sndstat should tell what is the problem. +In general the printout of /dev/sndstat should tell what is the problem. It's possible that there are bugs in the sound driver but 99% of the problems reported to me are caused by somehow incorrect setup during "make config". diff -u --recursive --new-file v2.1.125/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c --- v2.1.125/linux/drivers/sound/ad1848.c Thu Sep 17 17:53:37 1998 +++ linux/drivers/sound/ad1848.c Fri Oct 9 11:56:59 1998 @@ -206,7 +206,7 @@ return; timeout = 80000; - while (timeout > 0 && ad_read(devc, 11) & 0x20) + while (timeout > 0 && (ad_read(devc, 11) & 0x20)) timeout--; if (ad_read(devc, 11) & 0x20) if (devc->model != MD_1845) @@ -916,7 +916,7 @@ cnt >>= 1; cnt--; - if (devc->audio_mode & PCM_ENABLE_OUTPUT && audio_devs[dev]->flags & DMA_AUTOMODE && + if ((devc->audio_mode & PCM_ENABLE_OUTPUT) && (audio_devs[dev]->flags & DMA_AUTOMODE) && intrflag && cnt == devc->xfer_count) { @@ -958,7 +958,7 @@ cnt >>= 1; cnt--; - if (devc->audio_mode & PCM_ENABLE_INPUT && audio_devs[dev]->flags & DMA_AUTOMODE && + if ((devc->audio_mode & PCM_ENABLE_INPUT) && (audio_devs[dev]->flags & DMA_AUTOMODE) && intrflag && cnt == devc->xfer_count) { @@ -1182,10 +1182,10 @@ unsigned char bits = ad_read(devc, 9); - if (bits & 0x01 && portc->open_mode & OPEN_WRITE) + if (bits & 0x01 && (portc->open_mode & OPEN_WRITE)) ad1848_halt_output(dev); - if (bits & 0x02 && portc->open_mode & OPEN_READ) + if (bits & 0x02 && (portc->open_mode & OPEN_READ)) ad1848_halt_input(dev); devc->audio_mode = 0; } @@ -1308,7 +1308,7 @@ 0x00, 0x0c, 0x02, 0x00, 0x8a, 0x01, 0x00, 0x00, /* Positions 16 to 31 just for CS4231/2 and ad1845 */ - 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -1997,16 +1997,16 @@ ad_write(devc, 24, ad_read(devc, 24) & ~alt_stat); /* Selective ack */ } - if (devc->open_mode & OPEN_READ && devc->audio_mode & PCM_ENABLE_INPUT && alt_stat & 0x20) + if ((devc->open_mode & OPEN_READ) && (devc->audio_mode & PCM_ENABLE_INPUT) && (alt_stat & 0x20)) { DMAbuf_inputintr(devc->record_dev); } - if (devc->open_mode & OPEN_WRITE && devc->audio_mode & PCM_ENABLE_OUTPUT && - alt_stat & 0x10) + if ((devc->open_mode & OPEN_WRITE) && (devc->audio_mode & PCM_ENABLE_OUTPUT) && + (alt_stat & 0x10)) { DMAbuf_outputintr(devc->playback_dev, 1); } - if (devc->model != MD_1848 && alt_stat & 0x40) /* Timer interrupt */ + if (devc->model != MD_1848 && (alt_stat & 0x40)) /* Timer interrupt */ { devc->timer_ticks++; #if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS) diff -u --recursive --new-file v2.1.125/linux/drivers/sound/ad1848_mixer.h linux/drivers/sound/ad1848_mixer.h --- v2.1.125/linux/drivers/sound/ad1848_mixer.h Thu Jul 16 18:09:26 1998 +++ linux/drivers/sound/ad1848_mixer.h Fri Oct 9 11:56:59 1998 @@ -17,7 +17,7 @@ * The AD1848 codec has generic input lines called Line, Aux1 and Aux2. * Sound card manufacturers have connected actual inputs (CD, synth, line, * etc) to these inputs in different order. Therefore it's difficult - * to assign mixer channels to to these inputs correctly. The following + * to assign mixer channels to these inputs correctly. The following * contains two alternative mappings. The first one is for GUS MAX and * the second is just a generic one (line1, line2 and line3). * (Actually this is not a mapping but rather some kind of interleaving diff -u --recursive --new-file v2.1.125/linux/drivers/sound/audio.c linux/drivers/sound/audio.c --- v2.1.125/linux/drivers/sound/audio.c Sat Sep 5 16:46:41 1998 +++ linux/drivers/sound/audio.c Sat Oct 17 15:33:46 1998 @@ -18,6 +18,8 @@ * lifetime as the rest in there and dynamic allocation saves * 12k or so * Thomas Sailer : use more logical O_NONBLOCK semantics + * Daniel Rodriksson: reworked the use of the device specific copy_user + * still generic */ #include @@ -155,10 +157,21 @@ dev = dev >> 4; + /* + * We do this in DMAbuf_release(). Why are we doing it + * here? Why don't we test the file mode before setting + * both flags? DMAbuf_release() does. + * ...pester...pester...pester... + */ audio_devs[dev]->dmap_out->closing = 1; audio_devs[dev]->dmap_in->closing = 1; - sync_output(dev); + /* + * We need to make sure we allocated the dmap_out buffer + * before we go mucking around with it in sync_output(). + */ + if (mode & OPEN_WRITE) + sync_output(dev); if (audio_devs[dev]->coproc) audio_devs[dev]->coproc->close(audio_devs[dev]->coproc->devc, COPR_PCM); @@ -178,7 +191,7 @@ int audio_write(int dev, struct file *file, const char *buf, int count) { - int c, p, l, buf_size; + int c, p, l, buf_size, used, returned; int err; char *dma_buf; @@ -215,6 +228,8 @@ if (l > buf_size) l = buf_size; + returned = l; + used = l; if (!audio_devs[dev]->d->copy_user) { if ((dma_buf + l) > @@ -231,7 +246,13 @@ if(copy_from_user(dma_buf, &(buf)[p], l)) return -EFAULT; } - else audio_devs[dev]->d->copy_user(dev, dma_buf, 0, buf, p, l); + else audio_devs[dev]->d->copy_user ( dev, + dma_buf, 0, + buf, p, + c, buf_size, + &used, &returned, + l); + l = returned; if (audio_devs[dev]->local_conversion & CNV_MU_LAW) { @@ -241,8 +262,8 @@ sti(); translate_bytes(ulaw_dsp, (unsigned char *) dma_buf, l); } - c -= l; - p += l; + c -= used; + p += used; DMAbuf_move_wrpointer(dev, l); } @@ -279,7 +300,7 @@ * Nonblocking mode handling. Return current # of bytes */ - if (file->f_flags & O_NONBLOCK && buf_no == -EAGAIN) + if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN) return p; if (p > 0) /* Avoid throwing away data */ diff -u --recursive --new-file v2.1.125/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h --- v2.1.125/linux/drivers/sound/dev_table.h Sat Sep 5 16:46:41 1998 +++ linux/drivers/sound/dev_table.h Sat Oct 17 15:33:46 1998 @@ -31,6 +31,8 @@ #define SNDCARD_SOFTOSS 36 #define SNDCARD_VMIDI 37 #define SNDCARD_WAVEFRONT 41 +#define SNDCARD_OPL3SA2 42 +#define SNDCARD_OPL3SA2_MPU 43 void attach_opl3sa_wss (struct address_info *hw_config); int probe_opl3sa_wss (struct address_info *hw_config); @@ -186,8 +188,12 @@ int (*prepare_for_output) (int dev, int bufsize, int nbufs); void (*halt_io) (int dev); int (*local_qlen)(int dev); - void (*copy_user)(int dev, char *localbuf, int localoffs, - const char *userbuf, int useroffs, int len); + void (*copy_user)(int dev, + char *localbuf, int localoffs, + const char *userbuf, int useroffs, + int max_in, int max_out, + int *used, int *returned, + int len); void (*halt_input) (int dev); void (*halt_output) (int dev); void (*trigger) (int dev, int bits); @@ -412,6 +418,11 @@ {"CS4232MPU", 0, SNDCARD_CS4232_MPU, "CS4232 MIDI", attach_cs4232_mpu, probe_cs4232_mpu, unload_cs4232_mpu}, #endif +#ifdef CONFIG_SOUND_OPL3SA2 + {"OPL3SA2", 0, SNDCARD_OPL3SA2, "OPL3SA2", attach_opl3sa2, probe_opl3sa2, unload_opl3sa2}, + {"OPL3SA2MPU", 0, SNDCARD_OPL3SA2_MPU, "OPL3SA2 MIDI", attach_opl3sa2_mpu, probe_opl3sa2_mpu, unload_opl3sa2_mpu}, +#endif + #ifdef CONFIG_SGALAXY {"SGALAXY", 0, SNDCARD_SGALAXY, "Sound Galaxy WSS", attach_sgalaxy, probe_sgalaxy, unload_sgalaxy}, #endif @@ -558,6 +569,16 @@ {SNDCARD_CS4232_MPU, {CONFIG_CS4232_MPU_BASE, CONFIG_CS4232_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE}, #endif {SNDCARD_CS4232, {CONFIG_CS4232_BASE, CONFIG_CS4232_IRQ, CONFIG_CS4232_DMA, CONFIG_CS4232_DMA2}, SND_DEFAULT_ENABLE}, +#endif + +#ifdef CONFIG_SOUND_OPL3SA2 +#ifndef CONFIG_OPL3SA2_DMA2 +#define CONFIG_OPL3SA2_DMA2 CONFIG_OPL3SA2_DMA +#endif +#ifdef CONFIG_OPL3SA2_MPU_BASE + {SNDCARD_OPL3SA2_MPU, {CONFIG_OPL3SA2_MPU_BASE, CONFIG_OPL3SA2_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE}, +#endif + {SNDCARD_OPL3SA2, {CONFIG_OPL3SA2_BASE, CONFIG_OPL3SA2_IRQ, CONFIG_OPL3SA2_DMA, CONFIG_OPL3SA2_DMA2}, SND_DEFAULT_ENABLE}, #endif #ifdef CONFIG_SGALAXY diff -u --recursive --new-file v2.1.125/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c --- v2.1.125/linux/drivers/sound/dmabuf.c Sat Sep 5 16:46:41 1998 +++ linux/drivers/sound/dmabuf.c Fri Oct 9 11:56:59 1998 @@ -138,15 +138,15 @@ int chan = dmap->dma; /* printk( "Start DMA%d %d, %d\n", chan, (int)(physaddr-dmap->raw_buf_phys), count); */ - save_flags(flags); - cli(); + + flags = claim_dma_lock(); disable_dma(chan); clear_dma_ff(chan); set_dma_mode(chan, dma_mode); set_dma_addr(chan, physaddr); set_dma_count(chan, count); enable_dma(chan); - restore_flags(flags); + release_dma_lock(flags); return 0; } @@ -201,11 +201,17 @@ static void close_dmap(struct audio_operations *adev, struct dma_buffparms *dmap) { + unsigned long flags; + sound_close_dma(dmap->dma); if (dmap->flags & DMA_BUSY) dmap->dma_mode = DMODE_NONE; dmap->flags &= ~DMA_BUSY; + + flags=claim_dma_lock(); disable_dma(dmap->dma); + release_dma_lock(flags); + sound_free_dmap(dmap); } @@ -279,7 +285,7 @@ } adev->enable_bits = mode; - if (mode == OPEN_READ || (mode != OPEN_WRITE && adev->flags & DMA_DUPLEX)) { + if (mode == OPEN_READ || (mode != OPEN_WRITE && (adev->flags & DMA_DUPLEX))) { if ((retval = open_dmap(adev, mode, dmap_in)) < 0) { adev->d->close(dev); if (mode & OPEN_WRITE) @@ -311,7 +317,7 @@ static void dma_reset_output(int dev) { struct audio_operations *adev = audio_devs[dev]; - unsigned long flags; + unsigned long flags,f ; struct dma_buffparms *dmap = adev->dmap_out; if (!(dmap->flags & DMA_STARTED)) /* DMA is not active */ @@ -341,8 +347,12 @@ else adev->d->halt_output(dev); adev->dmap_out->flags &= ~DMA_STARTED; + + f=claim_dma_lock(); clear_dma_ff(dmap->dma); disable_dma(dmap->dma); + release_dma_lock(f); + restore_flags(flags); dmap->byte_counter = 0; reorganize_buffers(dev, adev->dmap_out, 0); @@ -377,7 +387,7 @@ return; /* Don't start DMA yet */ dmap->dma_mode = DMODE_OUTPUT; - if (!(dmap->flags & DMA_ACTIVE) || !(adev->flags & DMA_AUTOMODE) || dmap->flags & DMA_NODMA) { + if (!(dmap->flags & DMA_ACTIVE) || !(adev->flags & DMA_AUTOMODE) || (dmap->flags & DMA_NODMA)) { if (!(dmap->flags & DMA_STARTED)) { reorganize_buffers(dev, dmap, 0); if (adev->d->prepare_for_output(dev, dmap->fragment_size, dmap->nbufs)) @@ -404,7 +414,7 @@ int n = 0; struct dma_buffparms *dmap; - if (!adev->go && (!adev->enable_bits & PCM_ENABLE_OUTPUT)) + if (!adev->go && !(adev->enable_bits & PCM_ENABLE_OUTPUT)) return 0; if (adev->dmap_out->dma_mode == DMODE_OUTPUT) { @@ -476,7 +486,7 @@ if (adev->open_mode == OPEN_READ || (adev->open_mode != OPEN_WRITE && - adev->flags & DMA_DUPLEX)) + (adev->flags & DMA_DUPLEX))) close_dmap(adev, adev->dmap_in); adev->open_mode = 0; restore_flags(flags); @@ -606,6 +616,7 @@ int pos; unsigned long flags; + unsigned long f; save_flags(flags); cli(); @@ -613,9 +624,12 @@ pos = 0; else { int chan = dmap->dma; + + f=claim_dma_lock(); clear_dma_ff(chan); disable_dma(dmap->dma); pos = get_dma_residue(chan); + pos = dmap->bytes_in_use - pos; if (!(dmap->mapping_flags & DMA_MAP_MAPPED)) { @@ -634,6 +648,7 @@ if (pos >= dmap->bytes_in_use) pos = 0; enable_dma(dmap->dma); + release_dma_lock(f); } restore_flags(flags); /* printk( "%04x ", pos); */ @@ -961,10 +976,16 @@ } if (!(adev->flags & DMA_AUTOMODE)) dmap->flags &= ~DMA_ACTIVE; - while (dmap->qlen <= 0) { + + /* + * This is dmap->qlen <= 0 except when closing when + * dmap->qlen < 0 + */ + + while (dmap->qlen <= -dmap->closing) { dmap->underrun_count++; dmap->qlen++; - if (dmap->flags & DMA_DIRTY && dmap->applic_profile != APF_CPUINTENS) { + if ((dmap->flags & DMA_DIRTY) && dmap->applic_profile != APF_CPUINTENS) { dmap->flags &= ~DMA_DIRTY; memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte, adev->dmap_out->buffsize); @@ -988,10 +1009,15 @@ cli(); if (!(dmap->flags & DMA_NODMA)) { int chan = dmap->dma, pos, n; + unsigned long f; + + f=claim_dma_lock(); clear_dma_ff(chan); disable_dma(dmap->dma); pos = dmap->bytes_in_use - get_dma_residue(chan); enable_dma(dmap->dma); + release_dma_lock(f); + pos = pos / dmap->fragment_size; /* Actual qhead */ if (pos < 0 || pos >= dmap->nbufs) pos = 0; @@ -1056,7 +1082,7 @@ } } } - if (!(adev->flags & DMA_AUTOMODE) || dmap->flags & DMA_NODMA) { + if (!(adev->flags & DMA_AUTOMODE) || (dmap->flags & DMA_NODMA)) { local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use, DMA_MODE_READ); adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size, dmap->fragment_size, 1); if (adev->d->trigger) @@ -1078,10 +1104,14 @@ if (!(dmap->flags & DMA_NODMA)) { int chan = dmap->dma, pos, n; + unsigned long f; + + f=claim_dma_lock(); clear_dma_ff(chan); disable_dma(dmap->dma); pos = dmap->bytes_in_use - get_dma_residue(chan); enable_dma(dmap->dma); + release_dma_lock(f); pos = pos / dmap->fragment_size; /* Actual qhead */ if (pos < 0 || pos >= dmap->nbufs) @@ -1112,11 +1142,10 @@ if (adev->dmap_out->dma >= 0) { unsigned long flags; - save_flags(flags); - cli(); + flags=claim_dma_lock(); clear_dma_ff(adev->dmap_out->dma); disable_dma(adev->dmap_out->dma); - restore_flags(flags); + release_dma_lock(flags); } return 0; } diff -u --recursive --new-file v2.1.125/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c --- v2.1.125/linux/drivers/sound/es1370.c Sat Sep 5 16:46:41 1998 +++ linux/drivers/sound/es1370.c Sat Oct 17 15:33:46 1998 @@ -24,9 +24,10 @@ * * Module command line parameters: * joystick if 1 enables the joystick interface on the card; but it still - * needs a separate joystick driver (presumably PC standard, although - * the chip doc doesn't say anything and it looks slightly fishy from - * the PCI standpoint...) + * needs a driver for joysticks connected to a standard IBM-PC + * joyport. It is tested with the joy-analog driver. This + * module must be loaded before the joystick driver. Kmod will + * not ensure that. * lineout if 1 the LINE jack is used as an output instead of an input. * LINE then contains the unmixed dsp output. This can be used * to make the card a four channel one: use dsp to output two @@ -76,6 +77,8 @@ * 22.08.98 0.12 Mixer registers actually have 5 instead of 4 bits * pointed out by Itai Nahshon * 31.08.98 0.13 Fix realplayer problems - dac.count issues + * 08.10.98 0.14 Joystick support fixed + * -- Oliver Neukum * * some important things missing in Ensoniq documentation: * @@ -2242,8 +2245,11 @@ /* maximum number of devices */ #define NR_DEVICE 5 - +#ifdef CONFIG_SOUND_ES1370_JOYPORT_BOOT +static int joystick[NR_DEVICE] = { 1, 0, }; +#else static int joystick[NR_DEVICE] = { 0, }; +#endif static int lineout[NR_DEVICE] = { 0, }; static int micz[NR_DEVICE] = { 0, }; @@ -2337,8 +2343,6 @@ goto err_dev3; if ((s->dev_midi = register_sound_midi(&es1370_midi_fops)) < 0) goto err_dev4; - if (s->ctrl & CTRL_JYSTK_EN) - request_region(0x200, JOY_EXTENT, "es1370"); /* initialize the chips */ outl(s->ctrl, s->io+ES1370_REG_CONTROL); outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); diff -u --recursive --new-file v2.1.125/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c --- v2.1.125/linux/drivers/sound/gus_wave.c Thu Aug 20 17:05:16 1998 +++ linux/drivers/sound/gus_wave.c Sat Oct 17 15:33:46 1998 @@ -863,7 +863,7 @@ int bank, chunk, addr, total = 0; int bank_sizes[4]; - int i, j, bits = -1, nbanks = 0; + int i, j, bits = -1, testbits = -1, nbanks = 0; /* * This routine determines what kind of RAM is installed in each of the four @@ -974,28 +974,26 @@ } } /* - * The last resort is to search for a combination where the last bank is - * smaller than the actual SIMM. This leaves some memory in the last bank - * unused but doesn't leave holes in the DRAM address space. - */ - if (bits == -1) /* No luck yet */ - { - for (i = 0; bits == -1 && i < 13; i++) - { - bits = i; - - for (j = 0; bits != -1 && j < nbanks - 1; j++) - if (mem_decode[i][j] != bank_sizes[j]) - bits = -1; /* No hit */ - } - if (bits != -1) - { + * The last resort is to search for a combination where the banks are + * smaller than the actual SIMMs. This leaves some memory in the banks + * unused but doesn't leave holes in the DRAM address space. + */ + if (bits == -1) /* No luck yet */ + { + for (i = 0; i < 13; i++) + { + testbits = i; + for (j = 0; testbits != -1 && j < nbanks - 1; j++) + if (mem_decode[i][j] > bank_sizes[j]) { + testbits = -1; + } + if(testbits > bits) bits = testbits; + } + if (bits != -1) + { printk(KERN_INFO "Interwave: Can't use all installed RAM.\n"); printk(KERN_INFO "Interwave: Try reordering SIMMS.\n"); } - } - if (bits == -1) - { printk(KERN_INFO "Interwave: Can't find working DRAM encoding.\n"); printk(KERN_INFO "Interwave: Defaulting to 256k. Try reordering SIMMS.\n"); bits = 0; diff -u --recursive --new-file v2.1.125/linux/drivers/sound/legacy.h linux/drivers/sound/legacy.h --- v2.1.125/linux/drivers/sound/legacy.h Thu May 14 19:47:42 1998 +++ linux/drivers/sound/legacy.h Fri Oct 9 11:56:59 1998 @@ -27,6 +27,7 @@ #define CONFIG_MPU401 #define CONFIG_MSS #define CONFIG_OPL3SA1 +#define CONFIG_OPL3SA2 #define CONFIG_PAS #define CONFIG_PSS #define CONFIG_SB diff -u --recursive --new-file v2.1.125/linux/drivers/sound/msnd.h linux/drivers/sound/msnd.h --- v2.1.125/linux/drivers/sound/msnd.h Thu Sep 17 17:53:37 1998 +++ linux/drivers/sound/msnd.h Sat Oct 17 15:33:46 1998 @@ -24,13 +24,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: msnd.h,v 1.31 1998/09/10 14:02:58 andrewtv Exp $ + * $Id: msnd.h,v 1.32 1998/10/09 19:54:39 andrewtv Exp $ * ********************************************************************/ #ifndef __MSND_H #define __MSND_H -#define VERSION "0.8.2" +#define VERSION "0.8.2.1" #define DEFSAMPLERATE DSP_DEFAULT_SPEED #define DEFSAMPLESIZE AFMT_U8 @@ -230,6 +230,7 @@ #define F_READBLOCK 8 #define F_EXT_MIDI_INUSE 9 #define F_INT_MIDI_INUSE 10 +#define F_DISABLE_WRITE_NDELAY 11 struct wait_queue *writeblock, *readblock; struct wait_queue *writeflush; #ifndef LINUX20 diff -u --recursive --new-file v2.1.125/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c --- v2.1.125/linux/drivers/sound/msnd_pinnacle.c Thu Sep 17 17:53:37 1998 +++ linux/drivers/sound/msnd_pinnacle.c Sat Oct 17 15:33:46 1998 @@ -29,7 +29,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: msnd_pinnacle.c,v 1.63 1998/09/10 18:37:19 andrewtv Exp $ + * $Id: msnd_pinnacle.c,v 1.66 1998/10/09 19:54:39 andrewtv Exp $ * ********************************************************************/ @@ -66,6 +66,10 @@ # define LOGNAME "msnd_pinnacle" #endif +#ifndef CONFIG_MSND_WRITE_NDELAY +# define CONFIG_MSND_WRITE_NDELAY 0 +#endif + #define get_play_delay_jiffies(size) ((size) * HZ * \ dev.play_sample_size / 8 / \ dev.play_sample_rate / \ @@ -281,7 +285,8 @@ return 0; case SNDCTL_DSP_NONBLOCK: - if (file->f_mode & FMODE_WRITE) + if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags) && + file->f_mode & FMODE_WRITE) dev.play_ndelay = 1; if (file->f_mode & FMODE_READ) dev.rec_ndelay = 1; @@ -742,11 +747,14 @@ dev.nresets = 0; if (file->f_mode & FMODE_WRITE) { set_default_play_audio_parameters(); - dev.play_ndelay = (file->f_mode & O_NDELAY) ? 1 : 0; + if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags)) + dev.play_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0; + else + dev.play_ndelay = 0; } if (file->f_mode & FMODE_READ) { set_default_rec_audio_parameters(); - dev.rec_ndelay = (file->f_mode & O_NDELAY) ? 1 : 0; + dev.rec_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0; } } } @@ -820,7 +828,7 @@ if ((n = msnd_fifo_write( &dev.DARF, (char *)(dev.base + bank * DAR_BUFF_SIZE), - size, 0)) < 0) { + size, 0)) <= 0) { outb(HPBLKSEL_0, dev.io + HP_BLKS); return n; } @@ -1099,7 +1107,9 @@ dev_ioctl, /* ioctl */ NULL, /* mmap */ dev_open, /* open */ +#ifndef LINUX20 NULL, /* flush */ +#endif dev_release, /* release */ NULL, /* fsync */ NULL, /* fasync */ @@ -1631,6 +1641,7 @@ MODULE_PARM (io, "i"); MODULE_PARM (irq, "i"); MODULE_PARM (mem, "i"); +MODULE_PARM (write_ndelay, "i"); MODULE_PARM (major, "i"); MODULE_PARM (fifosize, "i"); MODULE_PARM (calibrate_signal, "i"); @@ -1649,6 +1660,7 @@ static int io __initdata = -1; static int irq __initdata = -1; static int mem __initdata = -1; +static int write_ndelay __initdata = -1; #ifndef MSND_CLASSIC /* Pinnacle/Fiji non-PnP Config Port */ @@ -1676,6 +1688,8 @@ #else /* not a module */ +static int write_ndelay __initdata = -1; + #ifdef MSND_CLASSIC static int io __initdata = CONFIG_MSNDCLAS_IO; static int irq __initdata = CONFIG_MSNDCLAS_IRQ; @@ -1888,6 +1902,12 @@ dev.recsrc = 0; dev.inc_ref = mod_inc_ref; dev.dec_ref = mod_dec_ref; + if (write_ndelay == -1) + write_ndelay = CONFIG_MSND_WRITE_NDELAY; + if (write_ndelay) + clear_bit(F_DISABLE_WRITE_NDELAY, &dev.flags); + else + set_bit(F_DISABLE_WRITE_NDELAY, &dev.flags); #ifndef MSND_CLASSIC if (digital) { diff -u --recursive --new-file v2.1.125/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c --- v2.1.125/linux/drivers/sound/opl3sa2.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/sound/opl3sa2.c Fri Oct 9 11:56:59 1998 @@ -0,0 +1,241 @@ +/* + * sound/opl3sa2.c + * + * A low level driver for Yamaha OPL3-SA[2,3,x] based cards. + * + * Scott Murray, Jun 14, 1998 + * + */ + +/* Based on the CS4232 driver: + * + * Copyright (C) by Hannu Savolainen 1993-1997 + * + * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) + * Version 2 (June 1991). See the "COPYING" file distributed with this software + * for more info. + */ + +#include +#include + +#include "sound_config.h" +#include "soundmodule.h" + +#ifdef CONFIG_OPL3SA2 + +int probe_opl3sa2_mpu(struct address_info *hw_config) +{ +#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) + return probe_mpu401(hw_config); +#else + return 0; +#endif +} + + +void attach_opl3sa2_mpu(struct address_info *hw_config) +{ +#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) + attach_mpu401(hw_config); +#endif +} + + +void unload_opl3sa2_mpu(struct address_info *hw_config) +{ +#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) + unload_mpu401(hw_config); +#endif +} + + +int probe_opl3sa2_mss(struct address_info *hw_config) +{ + return probe_ms_sound(hw_config); +} + + +void attach_opl3sa2_mss(struct address_info *hw_config) +{ + printk(KERN_INFO "opl3sa2.c: trying to init WSS\n"); + + attach_ms_sound(hw_config); + + /* request_region(hw_config->io_base, 4, "Yamaha 7xx WSS Config"); */ + + if (hw_config->slots[0] != -1 && + audio_devs[hw_config->slots[0]]->mixer_dev != -1) + { + AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD); + AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH); + /* GSM! test the following: */ + AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE); + } +} + + +void unload_opl3sa2_mss(struct address_info *hw_config) +{ + int mixer; + + /* Find mixer */ + mixer = audio_devs[hw_config->slots[0]]->mixer_dev; + + /* Unload MSS audio codec */ + unload_ms_sound(hw_config); + + sound_unload_audiodev(hw_config->slots[0]); + + /* Unload mixer if there */ + if(mixer >= 0) + { + sound_unload_mixerdev(mixer); + } + + /* Release MSS config ports */ + release_region(hw_config->io_base, 4); +} + + +int probe_opl3sa2(struct address_info *hw_config) +{ + /* + * Verify that the I/O port range is free. + */ + + printk(KERN_INFO "opl3sa2.c: Control using I/O port 0x%03x\n", hw_config->io_base); + + if (check_region(hw_config->io_base, 2)) + { + printk(KERN_ERR "opl3sa2.c: Control I/O port 0x%03x not free\n", hw_config->io_base); + return 0; + } + + /* GSM!: Add some kind of other test here... */ + + return 1; +} + + +void attach_opl3sa2(struct address_info *hw_config) +{ + printk(KERN_INFO "opl3sa2.c: trying to init!\n"); + + request_region(hw_config->io_base, 2, "Yamaha 7xx Control"); + + /* GSM! Mixer stuff should go here... */ +} + + +void unload_opl3sa2(struct address_info *hw_config) +{ + /* Release control ports */ + release_region(hw_config->io_base, 2); + + /* GSM! Mixer stuff should go here... */ +} + + +#ifdef MODULE + +int io = -1; +int mss_io = -1; +int mpu_io = -1; +int irq = -1; +int dma = -1; +int dma2 = -1; + +MODULE_PARM(io,"i"); +MODULE_PARM(mss_io,"i"); +MODULE_PARM(mpu_io,"i"); +MODULE_PARM(irq,"i"); +MODULE_PARM(dma,"i"); +MODULE_PARM(dma2,"i"); + +EXPORT_NO_SYMBOLS; + +struct address_info cfg; +struct address_info mss_cfg; +struct address_info mpu_cfg; + +/* + * Install a OPL3SA2 based card. Need to have ad1848 and mpu401 + * loaded ready. + */ +int init_module(void) +{ + int i; + + if (io == -1 || irq == -1 || dma == -1 || dma2 == -1 || mss_io == -1) + { + printk(KERN_ERR "opl3sa2: io, mss_io, irq, dma, and dma2 must be set.\n"); + return -EINVAL; + } + + /* Our own config: */ + cfg.io_base = io; + cfg.irq = irq; + cfg.dma = dma; + cfg.dma2 = dma2; + + /* The MSS config: */ + mss_cfg.io_base = mss_io; + mss_cfg.irq = irq; + mss_cfg.dma = dma; + mss_cfg.dma2 = dma2; + mss_cfg.card_subtype = 1; /* No IRQ or DMA setup */ + + /* Call me paranoid: */ + for(i = 0; i < 6; i++) + { + cfg.slots[i] = mss_cfg.slots[i] = mpu_cfg.slots[i] = -1; + } + + if (probe_opl3sa2(&cfg) == 0) + { + return -ENODEV; + } + attach_opl3sa2(&cfg); + + if (probe_opl3sa2_mss(&mss_cfg) == 0) + { + return -ENODEV; + } + attach_opl3sa2_mss(&mss_cfg); + +#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) + if(mpu_io != -1) + { + /* MPU config: */ + mpu_cfg.io_base = mpu_io; + mpu_cfg.irq = irq; + mpu_cfg.dma = dma; + mpu_cfg.always_detect = 1; /* It's there, so use shared IRQs */ + + if (probe_opl3sa2_mpu(&mpu_cfg)) + { + attach_opl3sa2_mpu(&mpu_cfg); + } + } +#endif + SOUND_LOCK; + return 0; +} + + +void cleanup_module(void) +{ +#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) + if(mpu_cfg.slots[1] != -1) + { + unload_opl3sa2_mpu(&mpu_cfg); + } +#endif + unload_opl3sa2_mss(&mss_cfg); + unload_opl3sa2(&cfg); + SOUND_LOCK_END; +} + +#endif +#endif diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb.h linux/drivers/sound/sb.h --- v2.1.125/linux/drivers/sound/sb.h Thu Sep 17 17:53:37 1998 +++ linux/drivers/sound/sb.h Sat Oct 17 15:33:46 1998 @@ -87,15 +87,20 @@ /* State variables */ int opened; + /* new audio fields for full duplex support */ + int fullduplex; + int duplex; int speed, bits, channels; volatile int irq_ok; volatile int intr_active, irq_mode; + /* duplicate audio fields for full duplex support */ + volatile int intr_active_2, irq_mode_2; /* Mixer fields */ int *levels; mixer_tab *iomap; - int mixer_caps, recmask, supported_devices; - int supported_rec_devices; + int mixer_caps, recmask, outmask, supported_devices; + int supported_rec_devices, supported_out_devices; int my_mixerdev; int sbmixnum; @@ -105,6 +110,13 @@ int trg_bytes; int trg_intrflag; int trg_restart; + /* duplicate audio fields for full duplex support */ + unsigned long trg_buf_2; + int trigger_bits_2; + int trg_bytes_2; + int trg_intrflag_2; + int trg_restart_2; + unsigned char tconst; int my_dev; diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb_audio.c linux/drivers/sound/sb_audio.c --- v2.1.125/linux/drivers/sound/sb_audio.c Thu Jul 16 18:09:27 1998 +++ linux/drivers/sound/sb_audio.c Sat Oct 17 15:33:46 1998 @@ -15,6 +15,10 @@ * * Status * Mostly working. Weird uart bug causing irq storms + * + * Daniel J. Rodriksson: Changes to make sb16 work full duplex. + * Maybe other 16 bit cards in this code could behave + * the same. */ #include @@ -47,7 +51,7 @@ restore_flags(flags); return -EBUSY; } - if (devc->dma16 != -1 && devc->dma16 != devc->dma8) + if (devc->dma16 != -1 && devc->dma16 != devc->dma8 && !devc->duplex) { if (sound_open_dma(devc->dma16, "Sound Blaster 16 bit")) { @@ -59,6 +63,10 @@ restore_flags(flags); devc->irq_mode = IMODE_NONE; + devc->irq_mode_2 = IMODE_NONE; + devc->intr_active_2 = 0; + devc->fullduplex = devc->duplex && + ((mode & OPEN_READ) && (mode & OPEN_WRITE)); sb_dsp_reset(devc); /* The ALS007 seems to require that the DSP be removed from the output */ @@ -84,9 +92,11 @@ { sb_devc *devc = audio_devs[dev]->devc; - audio_devs[dev]->dmap_in->dma = audio_devs[dev]->dmap_out->dma = devc->dma8; + audio_devs[dev]->dmap_out->dma = devc->dma8; + audio_devs[dev]->dmap_in->dma = ( devc->duplex ) ? + devc->dma16 : devc->dma8; - if (devc->dma16 != -1 && devc->dma16 != devc->dma8) + if (devc->dma16 != -1 && devc->dma16 != devc->dma8 && !devc->duplex) sound_close_dma(devc->dma16); /* For ALS007, turn DSP output back on if closing the device for read */ @@ -104,20 +114,34 @@ { sb_devc *devc = audio_devs[dev]->devc; - devc->trg_buf = buf; - devc->trg_bytes = nr_bytes; - devc->trg_intrflag = intrflag; - devc->irq_mode = IMODE_OUTPUT; + if( !devc->fullduplex || devc->bits == AFMT_S16_LE) { + devc->trg_buf = buf; + devc->trg_bytes = nr_bytes; + devc->trg_intrflag = intrflag; + devc->irq_mode = IMODE_OUTPUT; + } else { + devc->trg_buf_2 = buf; + devc->trg_bytes_2 = nr_bytes; + devc->trg_intrflag_2 = intrflag; + devc->irq_mode_2 = IMODE_OUTPUT; + } } static void sb_set_input_parms(int dev, unsigned long buf, int count, int intrflag) { sb_devc *devc = audio_devs[dev]->devc; - devc->trg_buf = buf; - devc->trg_bytes = count; - devc->trg_intrflag = intrflag; - devc->irq_mode = IMODE_INPUT; + if( !devc->fullduplex || devc->bits != AFMT_S16_LE) { + devc->trg_buf = buf; + devc->trg_bytes = count; + devc->trg_intrflag = intrflag; + devc->irq_mode = IMODE_INPUT; + } else { + devc->trg_buf_2 = buf; + devc->trg_bytes_2 = count; + devc->trg_intrflag_2 = intrflag; + devc->irq_mode_2 = IMODE_INPUT; + } } /* @@ -830,9 +854,17 @@ { sb_devc *devc = audio_devs[dev]->devc; - audio_devs[dev]->dmap_out->dma = - audio_devs[dev]->dmap_in->dma = - devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8; + if( !devc->fullduplex) { + audio_devs[dev]->dmap_out->dma = + audio_devs[dev]->dmap_in->dma = + devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8; + } else if( devc->bits == AFMT_S16_LE) { + audio_devs[dev]->dmap_out->dma = devc->dma8; + audio_devs[dev]->dmap_in->dma = devc->dma16; + } else { + audio_devs[dev]->dmap_out->dma = devc->dma16; + audio_devs[dev]->dmap_in->dma = devc->dma8; + } devc->trigger_bits = 0; return 0; @@ -842,8 +874,17 @@ { sb_devc *devc = audio_devs[dev]->devc; - audio_devs[dev]->dmap_out->dma = audio_devs[dev]->dmap_in->dma = - devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8; + if( !devc->fullduplex) { + audio_devs[dev]->dmap_out->dma = + audio_devs[dev]->dmap_in->dma = + devc->bits == AFMT_S16_LE ? devc->dma16 : devc->dma8; + } else if( devc->bits == AFMT_S16_LE) { + audio_devs[dev]->dmap_out->dma = devc->dma8; + audio_devs[dev]->dmap_in->dma = devc->dma16; + } else { + audio_devs[dev]->dmap_out->dma = devc->dma16; + audio_devs[dev]->dmap_in->dma = devc->dma8; + } devc->trigger_bits = 0; return 0; @@ -854,9 +895,23 @@ { unsigned long flags, cnt; sb_devc *devc = audio_devs[dev]->devc; + unsigned long bits; - devc->irq_mode = IMODE_OUTPUT; - devc->intr_active = 1; + if( !devc->fullduplex || devc->bits == AFMT_S16_LE) { + devc->irq_mode = IMODE_OUTPUT; + devc->intr_active = 1; + } else { + devc->irq_mode_2 = IMODE_OUTPUT; + devc->intr_active_2 = 1; + } + + /* save value */ + save_flags (flags); + cli (); + bits = devc->bits; + if( devc->fullduplex) + devc->bits = (devc->bits == AFMT_S16_LE) ? AFMT_U8 : AFMT_S16_LE; + restore_flags (flags); cnt = count; if (devc->bits == AFMT_S16_LE) @@ -878,6 +933,8 @@ sb_dsp_command(devc, (unsigned char) (cnt & 0xff)); sb_dsp_command(devc, (unsigned char) (cnt >> 8)); + /* restore real value after all programming */ + devc->bits = bits; restore_flags(flags); } @@ -886,8 +943,13 @@ unsigned long flags, cnt; sb_devc *devc = audio_devs[dev]->devc; - devc->irq_mode = IMODE_INPUT; - devc->intr_active = 1; + if( !devc->fullduplex || devc->bits != AFMT_S16_LE) { + devc->irq_mode = IMODE_INPUT; + devc->intr_active = 1; + } else { + devc->irq_mode_2 = IMODE_INPUT; + devc->intr_active_2 = 1; + } cnt = count; if (devc->bits == AFMT_S16_LE) @@ -916,29 +978,125 @@ { sb_devc *devc = audio_devs[dev]->devc; + int bits_2 = bits & devc->irq_mode_2; bits &= devc->irq_mode; if (!bits) sb_dsp_command(devc, 0xd0); /* Halt DMA */ else { - switch (devc->irq_mode) - { - case IMODE_INPUT: - sb16_audio_start_input(dev, devc->trg_buf, devc->trg_bytes, - devc->trg_intrflag); - break; - - case IMODE_OUTPUT: - sb16_audio_output_block(dev, devc->trg_buf, devc->trg_bytes, - devc->trg_intrflag); - break; - } - } - - devc->trigger_bits = bits; + if( bits) { + switch (devc->irq_mode) + { + case IMODE_INPUT: + sb16_audio_start_input(dev, devc->trg_buf, + devc->trg_bytes, + devc->trg_intrflag); + break; + + case IMODE_OUTPUT: + sb16_audio_output_block(dev, devc->trg_buf, + devc->trg_bytes, + devc->trg_intrflag); + break; + } + } + if( bits_2) { + switch (devc->irq_mode_2) + { + case IMODE_INPUT: + sb16_audio_start_input (dev, devc->trg_buf_2, + devc->trg_bytes_2, + devc->trg_intrflag_2); + break; + case IMODE_OUTPUT: + sb16_audio_output_block (dev, devc->trg_buf_2, + devc->trg_bytes_2, + devc->trg_intrflag_2); + break; + } + } + } + + devc->trigger_bits = bits | bits_2; +} + +static unsigned char lbuf8[2048]; +static signed short *lbuf16 = (signed short *)lbuf8; +#define LBUFCOPYSIZE 1024 +static void +sb16_copy_from_user( int dev, + char *localbuf, int localoffs, + const char *userbuf, int useroffs, + int max_in, int max_out, + int *used, int *returned, + int len) +{ + sb_devc *devc = audio_devs[dev]->devc; + int i, c, p, locallen; + unsigned char *buf8; + signed short *buf16; + + /* if not duplex no conversion */ + if( !devc->fullduplex) { + copy_from_user( localbuf + localoffs, userbuf + useroffs, len); + *used = len; + *returned = len; + } else if( devc->bits == AFMT_S16_LE) { + /* 16 -> 8 */ + /* max_in >> 1, max number of samples in ( 16 bits ) */ + /* max_out, max number of samples out ( 8 bits ) */ + /* len, number of samples that will be taken ( 16 bits )*/ + /* c, count of samples remaining in buffer ( 16 bits )*/ + /* p, count of samples already processed ( 16 bits )*/ + len = ( (max_in >> 1) > max_out) ? max_out : (max_in >> 1); + c = len; + p = 0; + buf8 = (unsigned char *)(localbuf + localoffs); + while( c) { + locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c); + /* << 1 in order to get 16 bit samples */ + copy_from_user( lbuf16, + userbuf+useroffs + (p << 1), + locallen << 1); + for( i = 0; i < locallen; i++) { + buf8[p+i] = ~((lbuf16[i] >> 8) & 0xff) ^ 0x80; + } + c -= locallen; p += locallen; + } + /* used = ( samples * 16 bits size ) */ + *used = len << 1; + /* returned = ( samples * 8 bits size ) */ + *returned = len; + } else { + /* 8 -> 16 */ + /* max_in, max number of samples in ( 8 bits ) */ + /* max_out >> 1, max number of samples out ( 16 bits ) */ + /* len, number of samples that will be taken ( 8 bits )*/ + /* c, count of samples remaining in buffer ( 8 bits )*/ + /* p, count of samples already processed ( 8 bits )*/ + len = max_in > (max_out >> 1) ? (max_out >> 1) : max_in; + c = len; + p = 0; + buf16 = (signed short *)(localbuf + localoffs); + while( c) { + locallen = (c >= LBUFCOPYSIZE ? LBUFCOPYSIZE : c); + copy_from_user( lbuf8, + userbuf+useroffs + p, + locallen); + for( i = 0; i < locallen; i++) { + buf16[p+i] = (~lbuf8[i] ^ 0x80) << 8; + } + c -= locallen; p += locallen; + } + /* used = ( samples * 8 bits size ) */ + *used = len; + /* returned = ( samples * 16 bits size ) */ + *returned = len << 1; + } } + static struct audio_driver sb1_audio_driver = /* SB1.x */ { sb_audio_open, @@ -1050,7 +1208,7 @@ sb16_audio_prepare_for_output, sb1_audio_halt_xfer, NULL, /* local_qlen */ - NULL, /* copy_from_user */ + sb16_copy_from_user, /* copy_from_user */ NULL, NULL, sb16_audio_trigger, @@ -1086,6 +1244,7 @@ struct audio_driver *driver = &sb1_audio_driver; + devc->duplex = 0; switch (devc->model) { case MDL_SB1: /* SB1.0 or SB 1.5 */ @@ -1124,6 +1283,10 @@ DDB(printk("Will use SB16 driver\n")); audio_flags = DMA_AUTOMODE; format_mask |= AFMT_S16_LE; + if( devc->dma8 != devc->dma16 && devc->dma16 != -1) { + audio_flags |= DMA_DUPLEX; + devc->duplex = 1; + } driver = &sb16_audio_driver; break; @@ -1136,7 +1299,9 @@ if ((devc->my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, name,driver, sizeof(struct audio_driver), audio_flags, format_mask, devc, - devc->dma8, devc->dma8)) < 0) + devc->dma8, + (devc->dma8 != devc->dma16 && devc->dma16 != -1) + ? devc->dma16 : devc->dma8)) < 0) { printk(KERN_ERR "Sound Blaster: unable to install audio.\n"); return; diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c --- v2.1.125/linux/drivers/sound/sb_common.c Thu Sep 17 17:53:37 1998 +++ linux/drivers/sound/sb_common.c Sat Oct 17 15:33:46 1998 @@ -10,7 +10,10 @@ * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. */ - +/* + * Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts + * for full duplex support ( only sb16 by now ) + */ #include #include #include @@ -140,7 +143,7 @@ if (!(src & 3)) return; /* Not a DSP interrupt */ } - if (devc->intr_active) + if (devc->intr_active && (!devc->fullduplex || (src & 0x01))) { switch (devc->irq_mode) { @@ -165,7 +168,17 @@ /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */ ; } - } + } else if (devc->intr_active_2 && (src & 0x02)) { + switch (devc->irq_mode_2) + { + case IMODE_OUTPUT: + DMAbuf_outputintr (devc->dev, 1); + break; + case IMODE_INPUT: + DMAbuf_inputintr (devc->dev); + break; + } + } /* * Acknowledge interrupts */ @@ -954,8 +967,7 @@ if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) && devc->irq > 0) { free_irq(devc->irq, devc); - if (devc->my_mixerdev) - sound_unload_mixerdev(devc->my_mixerdev); + sound_unload_mixerdev(devc->my_mixerdev); /* We don't have to do this bit any more the UART401 is its own master -- Krzysztof Halasa */ /* But we have to do it, if UART401 is not detected */ diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c --- v2.1.125/linux/drivers/sound/sb_mixer.c Thu Sep 17 17:53:37 1998 +++ linux/drivers/sound/sb_mixer.c Sat Oct 17 15:33:46 1998 @@ -294,6 +294,39 @@ return devc->recmask; } +static int set_outmask(sb_devc * devc, int mask) +{ + int devmask, i; + unsigned char regimage; + + devmask = mask & devc->supported_out_devices; + + switch (devc->model) + { + case MDL_SB16: + if (devc->submodel == SUBMDL_ALS007) + break; + else + { + regimage = 0; + for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) + { + if ((1 << i) & devmask) + { + regimage |= (sb16_recmasks_L[i] | sb16_recmasks_R[i]); + } + sb_setmixer (devc, SB16_OMASK, regimage); + } + } + break; + default: + break; + } + + devc->outmask = devmask; + return devc->outmask; +} + static int sb_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg) { sb_devc *devc = mixer_devs[dev]->devc; @@ -321,6 +354,10 @@ ret = set_recmask(devc, val); break; + case SOUND_MIXER_OUTSRC: + ret = set_outmask(devc, val); + break; + default: ret = sb_mixer_set(devc, cmd & 0xff, val); } @@ -331,6 +368,10 @@ ret = devc->recmask; break; + case SOUND_MIXER_OUTSRC: + ret = devc->outmask; + break; + case SOUND_MIXER_DEVMASK: ret = devc->supported_devices; break; @@ -348,6 +389,10 @@ ret = devc->supported_rec_devices; break; + case SOUND_MIXER_OUTMASK: + ret = devc->supported_out_devices; + break; + case SOUND_MIXER_CAPS: ret = devc->mixer_caps; break; @@ -435,6 +480,7 @@ case MDL_SB16: devc->mixer_caps = 0; devc->supported_rec_devices = SB16_RECORDING_DEVICES; + devc->supported_out_devices = SB16_OUTFILTER_DEVICES; if (devc->submodel != SUBMDL_ALS007) { devc->supported_devices = SB16_MIXER_DEVICES; diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sb_mixer.h linux/drivers/sound/sb_mixer.h --- v2.1.125/linux/drivers/sound/sb_mixer.h Thu May 14 19:47:42 1998 +++ linux/drivers/sound/sb_mixer.h Sat Oct 17 15:33:46 1998 @@ -41,6 +41,9 @@ #define SB16_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | SOUND_MASK_MIC | \ SOUND_MASK_CD) +#define SB16_OUTFILTER_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | \ + SOUND_MASK_CD) + #define ES688_RECORDING_DEVICES SBPRO_RECORDING_DEVICES #define ES688_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_LINE2|SOUND_MASK_SPEAKER) @@ -99,6 +102,7 @@ /* * Mixer registers of SB16 */ +#define SB16_OMASK 0x3c #define SB16_IMASK_L 0x3d #define SB16_IMASK_R 0x3e diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sgalaxy.c linux/drivers/sound/sgalaxy.c --- v2.1.125/linux/drivers/sound/sgalaxy.c Tue Jun 9 11:57:30 1998 +++ linux/drivers/sound/sgalaxy.c Sat Oct 17 15:33:46 1998 @@ -93,7 +93,7 @@ } if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) ) - return 1; /* The card is already active */ + return probe_ms_sound(ai); /* The card is already active, check irq etc... */ if ( check_region( ai->ai_sgbase, 0x10 ) ) { diff -u --recursive --new-file v2.1.125/linux/drivers/sound/sound_calls.h linux/drivers/sound/sound_calls.h --- v2.1.125/linux/drivers/sound/sound_calls.h Tue Jul 21 00:15:31 1998 +++ linux/drivers/sound/sound_calls.h Fri Oct 9 11:56:59 1998 @@ -251,6 +251,8 @@ void unload_trix_mpu(struct address_info *hw_info); void unload_cs4232(struct address_info *hw_info); void unload_cs4232_mpu(struct address_info *hw_info); +void unload_opl3sa2(struct address_info *hw_info); +void unload_opl3sa2_mpu(struct address_info *hw_info); /* From cs4232.c */ @@ -258,6 +260,12 @@ void attach_cs4232 (struct address_info *hw_config); int probe_cs4232_mpu (struct address_info *hw_config); void attach_cs4232_mpu (struct address_info *hw_config); + +/* From opl3sa2.c */ +int probe_opl3sa2 (struct address_info *hw_config); +void attach_opl3sa2 (struct address_info *hw_config); +int probe_opl3sa2_mpu (struct address_info *hw_config); +void attach_opl3sa2_mpu (struct address_info *hw_config); /* From maui.c */ void attach_maui(struct address_info * hw_config); diff -u --recursive --new-file v2.1.125/linux/drivers/video/Config.in linux/drivers/video/Config.in --- v2.1.125/linux/drivers/video/Config.in Mon Oct 5 13:13:40 1998 +++ linux/drivers/video/Config.in Thu Oct 15 15:24:18 1998 @@ -71,6 +71,14 @@ bool ' Leo (ZX) support' CONFIG_FB_LEO fi fi + if [ "$ARCH" = "sparc" ]; then + if [ "$CONFIG_PCI" != "n" ]; then + bool 'PCI framebuffers' CONFIG_FB_PCI + if [ "$CONFIG_FB_PCI" != "n" ]; then + bool ' IGA 168x display support' CONFIG_FB_IGA + fi + fi + fi if [ "$ARCH" = "sparc64" ]; then if [ "$CONFIG_PCI" != "n" ]; then bool 'PCI framebuffers' CONFIG_FB_PCI @@ -133,7 +141,8 @@ "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ "$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_G364" = "y" -o \ - "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" ]; then + "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ + "$CONFIG_FB_IGA" = "y" ]; then define_bool CONFIG_FBCON_CFB8 y else if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ @@ -143,7 +152,8 @@ "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ "$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_G364" = "m" -o \ - "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" ]; then + "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ + "$CONFIG_FB_IGA" = "y" ]; then define_bool CONFIG_FBCON_CFB8 m fi fi diff -u --recursive --new-file v2.1.125/linux/drivers/video/Makefile linux/drivers/video/Makefile --- v2.1.125/linux/drivers/video/Makefile Mon Oct 5 13:13:40 1998 +++ linux/drivers/video/Makefile Thu Oct 15 15:24:18 1998 @@ -95,6 +95,10 @@ L_OBJS += atyfb.o endif +ifeq ($(CONFIG_FB_IGA),y) +L_OBJS += igafb.o +endif + ifeq ($(CONFIG_FB_CONTROL),y) L_OBJS += controlfb.o endif @@ -447,7 +451,7 @@ include $(TOPDIR)/Rules.make -promcon_tbl.c: prom.uni +promcon_tbl.c: prom.uni ../char/conmakehash ../char/conmakehash prom.uni | \ sed -e '/#include <[^>]*>/p' -e 's/types/init/' \ -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > promcon_tbl.c diff -u --recursive --new-file v2.1.125/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c --- v2.1.125/linux/drivers/video/atyfb.c Mon Oct 5 13:13:41 1998 +++ linux/drivers/video/atyfb.c Thu Oct 15 15:24:18 1998 @@ -1,4 +1,4 @@ -/* $Id: atyfb.c,v 1.77 1998/09/14 08:01:46 jj Exp $ +/* $Id: atyfb.c,v 1.81 1998/10/14 16:45:38 ecd Exp $ * linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64 * * Copyright (C) 1997-1998 Geert Uytterhoeven @@ -28,6 +28,8 @@ - cursor support on all cards and all ramdacs. - cursor parameters controlable via ioctl()s. + - guess PLL and MCLK based on the original PLL register values initialized + by the BIOS or Open Firmware (if they are initialized). (Anyone to help with this?) @@ -60,7 +62,7 @@ #include -#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) +#if defined(CONFIG_PPC) #include #include #include