diff -u --recursive --new-file v2.1.132/linux/CREDITS linux/CREDITS --- v2.1.132/linux/CREDITS Tue Dec 22 14:16:53 1998 +++ linux/CREDITS Wed Dec 23 07:56:01 1998 @@ -84,6 +84,14 @@ S: Cambridge, Massachusetts 02139 S: USA +N: Jens Axboe +E: axboe@image.dk +D: Linux CD-ROM maintainer +D: jiffies wrap fixes + schedule timeouts depending on HZ == 100 +S: Peter Bangs Vej 258, 2TH +S: 2500 Valby +S: Denmark + N: John Aycock E: aycock@cpsc.ucalgary.ca D: Adaptec 274x driver diff -u --recursive --new-file v2.1.132/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.132/linux/Documentation/Configure.help Tue Dec 22 14:16:53 1998 +++ linux/Documentation/Configure.help Sun Dec 27 10:25:51 1998 @@ -21,7 +21,7 @@ # # Information about what a kernel is, what it does, how to patch and # compile it and much more is contained in the Kernel-HOWTO, available -# via FTP (user: anonymous) from sunsite.unc.edu in the directory +# via FTP (user: anonymous) from metalab.unc.edu in the directory # /pub/Linux/docs/HOWTO. Before you start compiling, make sure that # you have the necessary versions of all programs and libraries # required to compile and run this kernel; they are listed in the file @@ -80,6 +80,29 @@ you say Y here, you will be offered the choice of using features or drivers that are currently considered to be in the alpha-test phase. +Symmetric Multi Processing +CONFIG_SMP + This enables support for systems with more than one CPU. If you have a + system with only one CPU, like most personal computers, say N. If you + have a system with more than one CPU, say Y. + + A non-SMP kernel will run on any machine, but will use only one CPU of + a multi-CPU machine. An SMP kernel will run on many, but not all, + single-CPU machines. On a single-CPU machine, a non-SMP kernel + will run faster than an SMP kernel. + + People using multiprocessor machines should also say Y to "Enhanced + Real Time Clock Support", below. The "Advanced Power Management" + code will be disabled in an SMP kernel. + + If you don't know what to do here, say N. + + See also: Documentation/SMP.txt, Documentation/smp.tex, + Documentation/smp.txt, and Documentation/IO-APIC.txt. Also see the + SMP-FAQ on the WWW at http://www.irisa.fr/prive/mentre/smp-faq/ (to + browse the WWW, you need to have access to a machine on the Internet + that has a program like lynx or netscape). + Kernel math emulation CONFIG_MATH_EMULATION Linux can emulate a math coprocessor (used for floating point @@ -97,7 +120,7 @@ loader (lilo or loadlin) about how to pass options to the kernel at boot time. The lilo procedure is also explained in the SCSI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) This means that it is a + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.) This means that it is a good idea to say Y here if you intend to use this kernel on different machines. More information about the internals of Linux math coprocessor emulation can be found in @@ -238,11 +261,11 @@ contained in Documentation/ide.txt. For detailed information about hard drives, consult the Disk-HOWTO and the Multi-Disk-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. To fine-tune IDE drive/interface parameters for improved performance, look for the hdparm package at - ftp://sunsite.unc.edu:/pub/Linux/kernel/patches/diskdrives/ + ftp://metalab.unc.edu:/pub/Linux/kernel/patches/diskdrives/ If you have one or more IDE drives, say Y here. If your system has no IDE drives, or if memory requirements are really tight, you could @@ -264,7 +287,7 @@ If you are unsure, then just choose the Enhanced IDE/MFM/RLL driver instead of this one. For more detailed information, read the Disk-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. People with SCSI-only systems can say N here. @@ -307,7 +330,7 @@ a newer protocol used by IDE CDROM and TAPE drives, similar to the SCSI protocol. Most new CDROM drives use ATAPI, including the NEC-260, Mitsumi FX400, Sony 55E, and just about all non-SCSI - double(2X), quad(4X), and six(6X) speed drives. + double(2X) or better speed drives. If you say Y here, the CDROM drive will be identified at boot time along with other IDE devices, as "hdb" or "hdc", or something @@ -316,11 +339,11 @@ to say Y or M to "ISO 9660 CDROM filesystem support". Read the CDROM-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and the file + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO and the file Documentation/cdrom/ide-cd. Note that older versions of lilo (the Linux boot loader) cannot properly deal with IDE/ATAPI CDROMs, so install lilo-16 or higher, available from - ftp://sunsite.unc.edu/pub/Linux/system/Linux-boot/lilo. + ftp://metalab.unc.edu/pub/Linux/system/Linux-boot/lilo. If you want to compile the driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -402,7 +425,7 @@ bootparam" or see the documentation of your boot loader about how to pass options to the kernel. The lilo procedure is also explained in the SCSI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.) The CMD640 chip is also used on add-in cards by Acculogic, and on the "CSA-6400E PCI to IDE controller" that some people have. For @@ -448,7 +471,7 @@ for these drives, but you can change that by saying Y to the following question "Use DMA by default when available". You can get the latest version of the hdparm utility via anonymous FTP from - ftp://sunsite.unc.edu/pub/Linux/system/hardware/. + ftp://metalab.unc.edu/pub/Linux/system/hardware/. Read the comments at the beginning of drivers/block/idedma.c and the file Documentation/ide.txt for more information. @@ -872,7 +895,7 @@ More information about Software RAID on Linux is contained in the Software-RAID mini-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also learn where to get the supporting user space utilities raidtools. If unsure, say N. @@ -900,7 +923,7 @@ Information about Software RAID on Linux is contained in the Software-RAID mini-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also learn where to get the supporting user space utilities raidtools. If you want to compile this as a module ( = code which can be @@ -922,7 +945,7 @@ Information about Software RAID on Linux is contained in the Software-RAID mini-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also learn where to get the supporting user space utilities raidtools. If you want to use such a RAID-1 set, say Y. This code is also @@ -945,7 +968,7 @@ Information about Software RAID on Linux is contained in the Software-RAID mini-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also learn where to get the supporting user space utilities raidtools. If you want to use such a RAID-4/RAID-5 set, say Y. This code is @@ -1044,7 +1067,7 @@ address they listen on (e.g. "multihosting" or "virtual domains" or "virtual hosting services" on the web server apache and the ftp server wuftpd -- read the Virtual-Services-HOWTO, available via FTP - (user: anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO) + (user: anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO) or for connecting to different logical networks through the same physical interface (most commonly an Ethernet networking card). See Documentation/networking/alias.txt for more info. @@ -1150,7 +1173,7 @@ http://www.azstarnet.com/~axplinux/ (to browse the WWW, you need to have access to a machine on the Internet that has a program like lynx or netscape) and also the Alpha-HOWTO, available via FTP (user: - anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. For this + anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. For this question, it suffices to give a unique prefix of the option you want to choose. The choices: ** Avanti: This is for Mustang (AS200), M3 (AS250), Avanti (AS400) @@ -1232,7 +1255,7 @@ standard COM 1/2/3/4 ports. This may happen if you have an AST FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini), or other custom + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini), or other custom serial port hardware which acts similar to standard serial port hardware. If you only use the standard COM 1/2/3/4 ports, you can say N here to save some memory. You can also say Y if you have an @@ -1285,7 +1308,7 @@ your box. Other bus systems are ISA, EISA, Microchannel (MCA) or VESA. If you have PCI, say Y, otherwise N. The PCI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, contains valuable + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, contains valuable information about which PCI hardware does work under Linux and which doesn't. @@ -1348,8 +1371,7 @@ MicroChannel Architecture is found in some IBM PS/2 machines and laptops. It is a bus system similar to PCI or ISA. See Documentation/mca.txt (and especially the web page given there) - before attempting to build an MCA bus kernel. Note that this is - still experimental code. + before attempting to build an MCA bus kernel. System V IPC CONFIG_SYSVIPC @@ -1359,13 +1381,13 @@ thing, and some programs won't run unless you say Y here. In particular, if you want to run the DOS emulator dosemu under Linux (read the DOSEMU-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO), you'll need to say Y + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO), you'll need to say Y here. You can find documentation about IPC with "info ipc" and also in section 6.4 of the Linux Programmer's Guide, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide. + ftp://metalab.unc.edu/pub/Linux/docs/LDP/programmers-guide. Saying Y here enlarges your kernel by about 7 KB. Just say Y. @@ -1410,7 +1432,7 @@ want to say Y here. Information about ELF is contained in the ELF HOWTO available via - FTP (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + FTP (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you find that after upgrading from Linux kernel 1.2 and saying Y here, you still can't run any ELF binaries (they just crash), then @@ -1455,7 +1477,7 @@ If you want to execute JAVA binaries, read the Java on Linux HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You will then need to + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You will then need to install the run time system contained in the Java Developers Kit (JDK) as described in the HOWTO. This is completely independent of the Linux kernel and you do NOT need to say Y here for this to work. @@ -1499,7 +1521,7 @@ programs that need an interpreter to run like Java, Python or Emacs-Lisp. It's also useful if you often run DOS executables under the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO). Once you have + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO). Once you have registered such a binary class with the kernel, you can start one of those programs simply by typing in its name at a shell prompt; Linux will automatically feed it to the correct interpreter. @@ -1553,24 +1575,6 @@ In rare cases, it can make sense to specify "Pentium" even if running on a 486: the kernel will be smaller but slower. - If you have a single processor machine, make sure that the line - "SMP=1" at the top of the toplevel kernel Makefile is commented out; - if you have a multi processor machine and want Linux to use all the - processors in parallel (Symmetric Multi Processing), make sure that - the line "SMP=1" is not commented out and read Documentation/smp and - Documentation/IO-APIC.txt and the SMP-FAQ on the WWW at - http://www.irisa.fr/prive/mentre/smp-faq/ (to browse the WWW, you - need to have access to a machine on the Internet that has a program - like lynx or netscape). People using multiprocessor machines should - also say Y to "Enhanced Real Time Clock Support", below. - - If you want to compile a kernel that works on both single processor - and multi processor machines, it is possible to set SMP=1. The - "Advanced Power Management" code (see configuration option below) - will not work in that scenario, though. In addition, the kernel will - be slower on single processor machines, and other problems may - appear, so this is not recommended. - If you don't know what to do, choose "386". VGA text console @@ -1581,7 +1585,7 @@ The program SVGATextMode can be used to utilize SVGA video cards to their full potential in text mode. Download it via FTP (user: - anonymous) from ftp://sunsite.unc.edu/pub/Linux/utils/console. + anonymous) from ftp://metalab.unc.edu/pub/Linux/utils/console. Say Y. @@ -1596,7 +1600,7 @@ "man bootparam" or see the documentation of your boot loader about how to pass options to the kernel. The lilo procedure is also explained in the SCSI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Read + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Read Documentation/svga.txt for more information about the Video mode selection support. If unsure, say N. @@ -2232,10 +2236,10 @@ If you want to configure your Linux box as a packet filter firewall for a local TCP/IP based network, say Y here. You may want to read the FIREWALL-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Also, you will need the ipchains tool (available on the WWW at - http://www.adelaide.net.au/~rustcorp/) to allow selective blocking + http://www.rustcorp.com/linux/ipchains/) to allow selective blocking of Internet traffic based on type, origin and destination. Note that the Linux firewall code has changed and the old program called ipfwadm won't work anymore. @@ -2336,9 +2340,7 @@ Saying Y to this option will produce two modules ( = code which can be inserted in and removed from the running kernel whenever you - want), one encapsulator called tunnel.o and one decapsulator called - ipip.o. You can read details in drivers/net/README.tunnel. Most - people won't need this and can say N. + want). Most people won't need this and can say N. IP: GRE tunnels over IP CONFIG_NET_IPGRE @@ -2387,7 +2389,7 @@ Linux box to the Internet using SLiRP [SLiRP is a SLIP/PPP emulator that works if you have a regular dial up shell account on some UNIX computer; get it via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/system/network/serial/ ].) + ftp://metalab.unc.edu/pub/Linux/system/network/serial/ ].) The IP masquerading code will only work if IP forwarding is enabled in your kernel; you can do this by saying Y to "/proc @@ -2400,7 +2402,7 @@ Details on how to set things up are contained in the IP Masquerade mini-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini; there's also some + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini; there's also some information on the WWW at http://www.tor.shaw.wave.ca/~ambrose/kernel21.html. @@ -2427,7 +2429,7 @@ IP: masquerading special modules support CONFIG_IP_MASQUERADE_MOD This provides support for special modules that can modify the - rewriting rules used when masquerading. Please not that this feature + rewriting rules used when masquerading. Please note that this feature adds a little overhead in the input packet processing chain. Examples of such modules are ipautofw (allowing the masquerading of @@ -2437,7 +2439,7 @@ You will need the user space program "ipmasqadm" to use these additional modules; you can download it from - http://juanjox.home.ml.org/ + http://juanjox.linuxhq.com/ All this additional code is still under development and so is currently marked EXPERIMENTAL. @@ -2452,7 +2454,7 @@ ftp://ftp.netis.com/pub/members/rlynch/ You will also need the ipmasqadm tool available from - http://juanjox.home.ml.org . + http://juanjox.linuxhq.com/ . The ipautofw code is still under development and so is currently marked EXPERIMENTAL. If you want to try it, say Y. @@ -2483,7 +2485,7 @@ see ftp://ftp.compsoc.net/users/steve/ipportfw/linux21/ You will need the user space program "ipmasqadm" which can be - downloaded from http://juanjox.home.ml.org/ + downloaded from http://juanjox.linuxhq.com/ The portfw code is still under development and so is currently marked EXPERIMENTAL. If you want to try it, say Y. @@ -2494,12 +2496,12 @@ it as a module, say M here and read Documentation/modules.txt. IP: ipmarkfw masquerade support -CONFIG_IP_MASQUERADE_IPMARKFW - This provides functionality equivalent to port forwarding, the - difference is that Mark Forwarding uses "firewalling mark" to select - which packets must forward (see ipchains(8), "-m" argument). +CONFIG_IP_MASQUERADE_MFW + This provides functionality similar to port forwarding, the + difference is that Firewall Mark Forwarding uses "firewalling mark" + to select which packets must forward (see ipchains(8), "-m" argument). - The markfw code is still under development and so is currently + The ip_masq_mfw code is still under development and so is currently marked EXPERIMENTAL. If you want to try it, say Y. This code is also available as a module ( = code which can be @@ -2538,7 +2540,7 @@ need to have access to a machine on the Internet that has a program like lynx or netscape) and also in the Virtual-Hosting-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Another scenario would be that there are two logical networks living on your local Ethernet and you want to access them both with the @@ -2605,7 +2607,7 @@ If you actually want to use a diskless Sun 3 machine as an X terminal to Linux, say Y here and fetch Linux-Xkernel from - ftp://sunsite.unc.edu/pub/Linux/system/network/boot.net/. + ftp://metalab.unc.edu/pub/Linux/system/network/boot.net/. Superior solutions to the problem of booting and configuring machines over a net connection are given by the protocol BOOTP and @@ -2756,9 +2758,9 @@ used for local networks of Windows machines. You need it if you want to access Novell NetWare file or print servers using the Linux Novell client ncpfs (available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/system/filesystems/) or from within + ftp://metalab.unc.edu/pub/Linux/system/filesystems/) or from within the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO). In order to do the + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO). In order to do the former, you'll also have to say Y to "NCP filesystem support", below. @@ -2768,9 +2770,9 @@ To turn your Linux box into a fully featured NetWare file server and IPX router, say Y here and fetch either lwared from - ftp://sunsite.unc.edu/pub/Linux/system/network/daemons/ or mars_nwe + ftp://metalab.unc.edu/pub/Linux/system/network/daemons/ or mars_nwe from ftp://ftp.gwdg.de/pub/linux/misc/ncpfs. For more information, - read the IPX-HOWTO in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + read the IPX-HOWTO in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. General information about how to connect Linux, Windows machines and Macs is on the WWW at http://www.eats.com/linux_mac_win.html (to @@ -2793,7 +2795,7 @@ same address). The way this is done is to create a virtual internal "network" inside your box and to assign an IPX address to this network. Say Y here if you want to do this; read the IPX-HOWTO at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO for details. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO for details. The full internal IPX network enables you to allocate sockets on different virtual nodes of the internal network. This is done by @@ -2823,7 +2825,7 @@ space programs lwared or mars_nwe for the server side). Say Y here if you have use for SPX; read the IPX-HOWTO at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO for details. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO for details. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -2844,7 +2846,7 @@ slower LocalTalk is AppleTalk over a proprietary apple network using serial links. EtherTalk and LocalTalk are fully supported by Linux. The NET-2-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO contains valuable + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO contains valuable information as well. General information about how to connect Linux, Windows machines and @@ -2928,7 +2930,7 @@ (to browse the WWW, you need to have access to a machine on the Internet that has a program like lynx or netscape) and the HAM-HOWTO and the AX25-HOWTO, both available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the answer to this question won't directly affect the kernel: saying N will just cause this configure script to skip all @@ -2952,7 +2954,7 @@ Information about where to get supporting software for Linux amateur radio as well as information about how to configure an AX.25 port is contained in the AX25-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You might also want to + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You might also want to check out the file Documentation/networking/ax25.txt in the kernel source. More information about digital amateur radio in general is on the WWW at http://www.tapr.org/tapr/html/pkthome.html. (To browse @@ -2990,7 +2992,7 @@ A comprehensive listing of all the software for Linux amateur radio users as well as information about how to configure an AX.25 port is contained in the AX25-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You also might want to + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You also might want to check out the file Documentation/networking/ax25.txt. More information about digital amateur radio in general is on the WWW at http://www.tapr.org/tapr/html/pkthome.html (to browse the WWW, you @@ -3011,7 +3013,7 @@ A comprehensive listing of all the software for Linux amateur radio users as well as information about how to configure an AX.25 port is contained in the AX25-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You also might want to + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You also might want to check out the file Documentation/networking/ax25.txt. More information about digital amateur radio in general is on the WWW at http://www.tapr.org/tapr/html/pkthome.html (to browse the WWW, you @@ -3079,7 +3081,7 @@ (http://www.paccomm.com/gracilis.html) boards. They are detected automatically. If you have one of these cards, say Y here and read the AX25-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/. This driver can operate multiple boards simultaneously. If you compile it as a module (by saying M instead of Y), it will be called @@ -3105,7 +3107,7 @@ in order to communicate with other computers. If you want to use this, read Documentation/networking/z8530drv.txt and the AX25-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Also make sure to say Y + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Also make sure to say Y to "Amateur Radio AX.25 Level 2" support. If you want to compile this as a module ( = code which can be @@ -3364,7 +3366,7 @@ probably contains several Ethernet devices, but the kernel is not able to recognize more than one at boot time without help; for details read the Ethernet-HOWTO, available via FTP (user: anonymous) - in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. The Bridging code is + in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. The Bridging code is still in test. If unsure, say N. Packet socket @@ -3419,7 +3421,7 @@ port version of the 100 MB IOMEGA ZIP drive. Please read the SCSI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. The + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. The SCSI-Programming-HOWTO contains information about how to add or remove an SCSI device from a running Linux machine without rebooting. @@ -3437,7 +3439,7 @@ If you want to use a SCSI hard disk or the SCSI or parallel port version of the IOMEGA ZIP drive under Linux, say Y and read the SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available via - FTP (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + FTP (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This is NOT for SCSI CDROMs. This driver is also available as a module ( = code which can be @@ -3453,7 +3455,7 @@ CONFIG_CHR_DEV_ST If you want to use a SCSI tape drive under Linux, say Y and read the SCSI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO and drivers/scsi/README.st in the kernel source. This is NOT for SCSI CDROMs. @@ -3467,7 +3469,7 @@ CONFIG_BLK_DEV_SR If you want to use a SCSI CDROM under Linux, say Y and read the SCSI-HOWTO and the CDROM-HOWTO from - ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO. Also make sure to say Y + ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO. Also make sure to say Y or M to "ISO 9660 CDROM filesystem support" later. This driver is also available as a module ( = code which can be @@ -3491,11 +3493,11 @@ directly, so you need some additional software which knows how to talk to these devices using the SCSI protocol. For CD-writers, you would need the program cdwrite, available via FTP (user: anonymous) - from ftp://sunsite.unc.edu/pub/Linux/utils/disk-management; for + from ftp://metalab.unc.edu/pub/Linux/utils/disk-management; for other devices, it's possible that you'll have to write the driver software yourself, so have a look at the SCSI-HOWTO and at the SCSI-Programming-HOWTO, both available via FTP (user: anonymous) in - ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -3558,7 +3560,7 @@ This is support for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825 SCSI host adapters. It is explained in section 3.3 of the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You might also want to + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You might also want to read the comments at the top of drivers/scsi/aha152x.c. This driver is also available as a module ( = code which can be @@ -3570,7 +3572,7 @@ CONFIG_SCSI_AHA1542 This is support for a SCSI host adapter. It is explained in section 3.4 of the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that Trantor was + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that Trantor was recently purchased by Adaptec, and some former Trantor products are being sold under the Adaptec name. If it doesn't work out of the box, you may have to change some settings in drivers/scsi/aha1542.h. @@ -3584,7 +3586,7 @@ CONFIG_SCSI_AHA1740 This is support for a SCSI host adapter. It is explained in section 3.5 of the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out of the box, you may have to change some settings in drivers/scsi/aha1740.h. @@ -3603,7 +3605,7 @@ found by checking the help file for each of the available configuration options. You also want to read drivers/scsi/README.aic7xxx and the SCSI-HOWTO, available via FTP - (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the AHA2920 SCSI host adapter is *not* supported by this driver; choose "Future Domain 16xx SCSI support" instead if you have one of those. @@ -3680,7 +3682,7 @@ CONFIG_SCSI_BUSLOGIC This is support for BusLogic MultiMaster and FlashPoint SCSI Host Adapters. Consult the SCSI-HOWTO, available via anonymous FTP from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, and the files + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, and the files README.BusLogic and README.FlashPoint in drivers/scsi for more information. If this driver does not work correctly without modification, please contact the author, Leonard N. Zubkoff, by @@ -3703,7 +3705,7 @@ CONFIG_SCSI_DTC3280 This is support for DTC 3180/3280 SCSI Host Adapters. Please read the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and the file + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO and the file drivers/scsi/README.dtc3x80. This driver is also available as a module ( = code which can be @@ -3711,15 +3713,18 @@ The module will be called dtc.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support +EATA-DMA [Obsolete] (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support CONFIG_SCSI_EATA_DMA + This driver is obsolete. You should normally be using the generic EATA + driver for this hardware. + This is support for the EATA-DMA protocol compliant SCSI Host Adapters like the SmartCache III/IV, SmartRAID controller families and the DPT PM2011B and PM2012B controllers. Note that there is also another driver for the same hardware: "EATA ISA/EISA/PCI support". You should only say Y to one of them. Please read the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -3734,7 +3739,7 @@ doing so, since this driver only supports hard disks and lacks numerous features. You might want to have a look at the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -3748,7 +3753,7 @@ this hardware. If the driver doesn't work out of the box, you may have to change some settings in drivers/scsi/u14-34f.c. Read the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that there is also + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that there is also another driver for the same hardware: "UltraStor SCSI support", below. You should say Y to both only if you want 24F support as well. @@ -3778,7 +3783,7 @@ other adapters based on the Future Domain chipsets (Quantum ISA-200S, ISA-250MG; Adaptec AHA-2920; and at least one IBM board). It is explained in section 3.7 of the SCSI-HOWTO, available via FTP - (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -3797,7 +3802,7 @@ This is the generic NCR family of SCSI controllers, not to be confused with the NCR 53c7 or 8xx controllers. It is explained in section 3.8 of the SCSI-HOWTO, available via FTP (user: anonymous) - at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work + at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out of the box, you may have to change some settings in drivers/scsi/g_NCR5380.h. @@ -3826,7 +3831,7 @@ This is the 53c7 and 8xx NCR family of SCSI controllers, not to be confused with the NCR 5380 controllers. It is explained in section 3.8 of the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out of the box, you may have to change some settings in drivers/scsi/53c7,8xx.h. @@ -4011,7 +4016,7 @@ bootparam" or see the documentation of your boot loader about how to pass options to the kernel. The lilo procedure is also explained in the SCSI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -4062,6 +4067,17 @@ you know that one of your older devices needs it; N is the safe answer. +NCR 53C9x MCA support +CONFIG_SCSI_MCA_53C9X + Some Microchannel machines, notably the NCR 35xx line, use a SCSI + controller based on the NCR 53C94. This driver will allow use of + the controller on the 3550, and very possibly others. + + If you want to compile this as a module (= code which can be inserted + and removed from the running kernel whenever you want), + say M here and read Documentation/modules.txt. The module will be + called mca_53c9x.o. + Always IN2000 SCSI support CONFIG_SCSI_IN2000 This is support for an ISA bus SCSI host adapter. You'll find more @@ -4078,7 +4094,7 @@ CONFIG_SCSI_PAS16 This is support for a SCSI host adapter. It is explained in section 3.10 of the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out of the box, you may have to change some settings in drivers/scsi/pas16.h. @@ -4091,7 +4107,7 @@ CONFIG_SCSI_PCI2000 This is support for the PCI2000I EIDE interface card which acts as a SCSI host adapter. Please read the SCSI-HOWTO, available via FTP - (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module called pci2000.o ( = code which can be inserted in and removed from the running kernel @@ -4102,7 +4118,7 @@ CONFIG_SCSI_PCI2220I This is support for the PCI2220i EIDE interface card which acts as a SCSI host adapter. Please read the SCSI-HOWTO, available via FTP - (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module called pci2220i.o ( = code which can be inserted in and removed from the running kernel @@ -4113,7 +4129,7 @@ CONFIG_SCSI_PSI240I This is support for the PSI240i EIDE interface card which acts as a SCSI host adapter. Please read the SCSI-HOWTO, available via FTP - (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module called psi240i.o ( = code which can be inserted in and removed from the running kernel @@ -4129,7 +4145,7 @@ the Qlogic ISP driver though. Information about this driver is contained in drivers/scsi/README.qlogicfas. You should also read the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -4146,7 +4162,7 @@ Please read the file drivers/scsi/README.qlogicisp. You should also read the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -4158,7 +4174,7 @@ These are 8-bit SCSI controllers; the ST-01 is also supported by this driver. It is explained in section 3.9 of the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out of the box, you may have to change some settings in drivers/scsi/seagate.h. @@ -4171,7 +4187,7 @@ CONFIG_SCSI_T128 This is support for a SCSI host adapter. It is explained in section 3.11 of the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out of the box, you may have to change some settings in drivers/scsi/t128.h. Note that Trantor was purchased by Adaptec, and some former Trantor products are being sold under the Adaptec name. @@ -4186,7 +4202,7 @@ This is support for the UltraStor 14F, 24F and 34F SCSI-2 host adapter family. This driver is explained in section 3.12 of the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out of the box, you may have to change some settings in drivers/scsi/ultrastor.h. @@ -4216,7 +4232,7 @@ to "PCI BIOS support", the addresses of all the PCI SCSI controllers reported by BIOS32 are probed as well. You want to read the start of drivers/scsi/eata.c and the SCSI-HOWTO, available via FTP (user: - anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that there is also another driver for the same hardware available: "EATA-DMA support". You should say Y to only one of them. @@ -4252,7 +4268,7 @@ This is support for the NCR53c406a SCSI host adapter. For user configurable parameters, check out drivers/scsi/NCR53c406.c in the kernel source. Also read the SCSI-HOWTO, available via FTP (user: - anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -4296,7 +4312,7 @@ This is support for the AM53/79C974 SCSI host adapters. Please read drivers/scsi/README.AM53C974 for details. Also, the SCSI-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, is for you. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, is for you. Note that there is another driver for AM53C974 based adapters: "Tekram DC390(T) and Am53/79C974 (PCscsi) SCSI support", above. @@ -4324,7 +4340,7 @@ driver and how to use it you should read the file drivers/scsi/README.ppa. You should also read the SCSI-HOWTO, which is available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If you use this driver, + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you use this driver, you will still be able to use the parallel port for other tasks, such as a printer; it is safe to compile both drivers into the kernel. @@ -4441,7 +4457,7 @@ line with a modem either via UUCP (UUCP is a protocol to forward mail and news between unix hosts over telephone lines; read the UUCP-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO) or dialing up a shell + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO) or dialing up a shell account or a BBS, even using term (term is a program which gives you almost full Internet connectivity if you have a regular dial up shell account on some Internet connected Unix computer. Read @@ -4453,7 +4469,7 @@ you want to use under Linux (make sure you know its name because you will be asked for it and read the Ethernet-HOWTO (especially if you plan to use more than one network card under Linux), available from - ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini) or if you want to + ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO/mini) or if you want to use SLIP (Serial Line Internet Protocol is the protocol used to send Internet traffic over telephone lines or null modem cables) or CSLIP (compressed SLIP) or PPP (Point to Point Protocol, a better and @@ -4464,7 +4480,7 @@ Make sure to read the NET-2-HOWTO. Eventually, you will have to read Olaf Kirch's excellent and free book "Network Administrator's - Guide", to be found in ftp://sunsite.unc.edu:/pub/Linux/docs/LDP. If + Guide", to be found in ftp://metalab.unc.edu:/pub/Linux/docs/LDP. If unsure, say Y. Dummy net driver support @@ -4475,7 +4491,7 @@ inactive SLIP address seem like a real address for local programs. If you use SLIP or PPP, you might want to say Y here. Read about it in the Network Administrator's Guide, available via FTP (user: - anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/LDP. Since this + anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/LDP. Since this thing often comes in handy, the default is Y. It won't enlarge your kernel either. What a deal. @@ -4500,11 +4516,11 @@ Normally, your access provider has to support SLIP in order for you to be able to use it, but there is now a SLIP emulator called SLiRP around (available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/system/network/serial/ ) which + ftp://metalab.unc.edu/pub/Linux/system/network/serial/ ) which allows you to use SLIP over a regular dial up shell connection. If you plan to use SLiRP, make sure to say Y to CSLIP, below. The NET-2-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, explains how to + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, explains how to configure SLIP. Note that you don't need this option if you just want to run term (term is a program which gives you almost full Internet connectivity if you have a regular dial up shell account on @@ -4528,10 +4544,10 @@ answer Y, just in case. You will still be able to use plain SLIP. If you plan to use SLiRP, the SLIP emulator (available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/system/network/serial/) which allows + ftp://metalab.unc.edu/pub/Linux/system/network/serial/) which allows you to use SLIP over a regular dial up shell connection, you definitely want to say Y here. The NET-2-HOWTO, available via FTP - (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, + (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, explains how to configure CSLIP. This won't enlarge your kernel. Keepalive and linefill @@ -4559,7 +4575,7 @@ program SLiRP can emulate a PPP line if you just have a regular dial up shell account on some UNIX computer; get it via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/system/network/serial/). Note that + ftp://metalab.unc.edu/pub/Linux/system/network/serial/). Note that you don't need "PPP support" if you just want to run term (term is a program which gives you almost full Internet connectivity if you have a regular dial up shell account on some Internet connected UNIX @@ -4570,7 +4586,7 @@ To use PPP, you need an additional program called pppd as described in Documentation/networking/ppp.txt and in the PPP-HOWTO, available - from ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you upgrade + from ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO. If you upgrade from an older kernel, you might need to upgrade pppd as well. The PPP option enlarges your kernel by about 16 KB. @@ -4637,7 +4653,7 @@ If you want to use an ISA WaveLAN card under Linux, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Some more specific + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Some more specific information is contained in Documentation/networking/wavelan.txt and in the source code drivers/net/wavelan.p.h. @@ -4722,8 +4738,8 @@ If you want to use PLIP, say Y and read the PLIP mini-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini as well as the - NET-2-HOWTO in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini as well as the + NET-2-HOWTO in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the PLIP protocol was changed and this PLIP driver won't work together with the PLIP support in Linux versions 1.0.x. This option enlarges your kernel by about 8 KB. @@ -5078,6 +5094,48 @@ up to 256Kbits. It supports both PPP and Cisco HDLC At this point, the driver can only be compiled as a module. +COSA/SRP sync serial boards support +CONFIG_COSA + This is a driver for COSA and SRP synchronous serial boards. + These boards enable to connect synchronous serial devices (for + example base-band modems, or any other device with the X.21, V.24, + V.35 or V.36 interface) to your Linux box. The cards can work + as the character device, synchronous PPP network device, or the Cisco + HDLC network device. + + To actually use the COSA or SRP board, you will need user-space + utilities for downloading the firmware to the cards and to set + them up. Look at the http://www.fi.muni.cz/~kas/cosa/ for more + information about the cards (including the pointer to the user-space + utilities). You can also read the comment at the top of the + drivers/net/cosa.c for details about the cards and the driver itself. + + The driver will be compiled as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called cosa.o. For general information about + modules read Documentation/modules.txt. + +COSA/SRP sync serial boards support +CONFIG_COSA + This is a driver for COSA and SRP synchronous serial boards. + These boards enable to connect synchronous serial devices (for + example base-band modems, or any other device with the X.21, V.24, + V.35 or V.36 interface) to your Linux box. The cards can work + as the character device, synchronous PPP network device, or the Cisco + HDLC network device. + + To actually use the COSA or SRP board, you will need user-space + utilities for downloading the firmware to the cards and to set + them up. Look at the http://www.fi.muni.cz/~kas/cosa/ for more + information about the cards (including the pointer to the user-space + utilities). You can also read the comment at the top of the + drivers/net/cosa.c for details about the cards and the driver itself. + + The driver will be compiled as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called cosa.o. For general information about + modules read Documentation/modules.txt. + WAN Drivers CONFIG_WAN_DRIVERS Say Y to this option if your Linux box contains a WAN card and you @@ -5160,7 +5218,7 @@ If your Linux machine will be connected to an Ethernet and you have an Ethernet network interface card (NIC) installed in your computer, say Y here and read the Ethernet-HOWTO, available via FTP (user: - anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You will + anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You will then also have to say Y to the driver for your particular NIC. Note that the answer to this question won't directly affect the @@ -5187,7 +5245,7 @@ CONFIG_NET_VENDOR_SMC If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the answer to this question doesn't directly affect the kernel: saying N will just cause this configure script to skip all @@ -5198,7 +5256,7 @@ CONFIG_WD80x3 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5211,7 +5269,7 @@ If you have a network (Ethernet) card of this type and are running an MCA based system (PS/2), say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5223,7 +5281,7 @@ CONFIG_ULTRA If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Important: There have been many reports that, with some motherboards mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible, @@ -5242,7 +5300,7 @@ CONFIG_ULTRA32 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5258,7 +5316,7 @@ into the kernel, and read the file Documentation/networking/smc9.txt and the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you @@ -5272,7 +5330,7 @@ with ISA NE2000 cards (they have their own driver, "NE2000/NE1000 support" below). If you have a PCI NE2000 network (Ethernet) card, say Y and read the Ethernet-HOWTO, available via FTP (user: - anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5285,7 +5343,7 @@ If you have a network (Ethernet) card belonging to this class, such as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the answer to this question doesn't directly affect the kernel: saying N will just cause this configure script to skip all @@ -5296,7 +5354,7 @@ CONFIG_NI5010 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that this is still + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that this is still experimental code. This driver is also available as a module ( = code which can be @@ -5309,7 +5367,7 @@ CONFIG_NI52 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5321,7 +5379,7 @@ CONFIG_NI65 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5334,7 +5392,7 @@ This is a driver for the Fast Ethernet PCI network cards based on the RTL8129 and RTL8139 chips. If you have one of those, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -5373,14 +5431,14 @@ CONFIG_LANCE If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Some LinkSys cards are + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Some LinkSys cards are of this type. 3COM cards CONFIG_NET_VENDOR_3COM If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the answer to this question doesn't directly affect the kernel: saying N will just cause this configure script to skip all @@ -5391,7 +5449,7 @@ CONFIG_EL1 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Also, consider buying a + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Also, consider buying a new card, since the 3c501 is slow, broken, and obsolete: you will have problems. Some people suggest to ping ("man ping") a nearby machine every minute ("man cron") when using this card. @@ -5406,7 +5464,7 @@ CONFIG_EL2 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5419,7 +5477,7 @@ Information about this network (Ethernet) card can be found in Documentation/networking/3c505.txt. If you have a card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: - anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -5431,7 +5489,7 @@ CONFIG_EL16 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5443,7 +5501,7 @@ CONFIG_ELMC If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5456,7 +5514,7 @@ If you have a network (Ethernet) card belonging to the 3Com EtherLinkIII series, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If your card is not working you may need to use the DOS setup disk to disable Plug & Play mode, and to select the default @@ -5473,7 +5531,7 @@ If you have a 3Com "Vortex" (Fast EtherLink 3c590/3c592/3c595/3c597) or "Boomerang" series (EtherLink XL 3c900 or 3c905) network (Ethernet) card, say Y and read the Ethernet-HOWTO, available via - FTP (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + FTP (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. More specific information is in Documentation/networking/vortex.txt and in the comments at the beginning of drivers/net/3c59x.c. @@ -5489,7 +5547,7 @@ of your computer) is ISA (as opposed to EISA, VLB or PCI), say Y. Make sure you know the name of your card. Read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If unsure, say Y. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If unsure, say Y. Note that the answer to this question doesn't directly affect the kernel: saying N will just cause this configure script to skip all @@ -5508,7 +5566,7 @@ You might also want to have a look at the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO (even though ARCnet is + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO (even though ARCnet is not really Ethernet). This driver is also available as a module ( = code which can be @@ -5596,7 +5654,7 @@ CONFIG_E2100 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5609,7 +5667,7 @@ Support for CS89x0 chipset based Ethernet cards. If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO as well as + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO as well as Documentation/networking/cs89x0.txt. If you want to compile this as a module ( = code which can be @@ -5622,7 +5680,7 @@ CONFIG_DEPCA If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO as well as + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO as well as drivers/net/depca.c. If you want to compile this as a module ( = code which can be @@ -5637,7 +5695,7 @@ cards. If this is for you, say Y and read Documentation/networking/ewrk3.txt in the kernel source as well as the Ethernet-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -5649,13 +5707,13 @@ CONFIG_SEEQ8005 This is a driver for the SEEQ 8005 network (Ethernet) card. If this is for you, read the Ethernet-HOWTO, available via FTP (user: - anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. AT1700/1720 support CONFIG_AT1700 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5668,7 +5726,7 @@ CONFIG_FMV18X If you have a Fujitsu FMV-181/182/183/184 network (Ethernet) card, say Y and read the Ethernet-HOWTO, available via FTP (user: - anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you use an FMV-183 or FMV-184 and it is not working, you may need to disable Plug & Play mode of the card. @@ -5684,7 +5742,7 @@ If you have a network (Ethernet) card of this type, say Y. Note however that the EtherExpress PRO/100 Ethernet card has its own separate driver. Please read the Ethernet-HOWTO, available via FTP - (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5696,7 +5754,7 @@ CONFIG_EEXPRESS If you have an EtherExpress16 network (Ethernet) card, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that the Intel + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the Intel EtherExpress16 card used to be regarded as a very poor choice because the driver was very unreliable. We now have a new driver that should do better. @@ -5711,7 +5769,7 @@ CONFIG_HPLAN_PLUS If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5723,7 +5781,7 @@ CONFIG_HPLAN If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5735,7 +5793,7 @@ CONFIG_HP100 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -5747,7 +5805,7 @@ CONFIG_NE2000 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Many Ethernet cards + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Many Ethernet cards without a specific driver are compatible with NE2000. If you have a PCI NE2000 card however, say N here and Y to "PCI @@ -5766,13 +5824,13 @@ CONFIG_SK_G16 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. NE/2 (ne2000 MCA version) support CONFIG_NE2_MCA If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5785,7 +5843,7 @@ This is another class of network cards which attach directly to the bus. If you have one of those, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the answer to this question doesn't directly affect the kernel: saying N will just cause this configure script to skip all @@ -5797,7 +5855,7 @@ CONFIG_PCNET32 If you have a PCnet32 or PCnetPCI based network (Ethernet) card, answer Y here and read the Ethernet-HOWTO, available via FTP (user: - anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5809,7 +5867,7 @@ CONFIG_AC3200 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5821,7 +5879,7 @@ CONFIG_LNE390 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5833,7 +5891,7 @@ CONFIG_NE3210 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that this driver + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that this driver will NOT WORK for NE3200 cards as they are completely different. This driver is also available as a module ( = code which can be @@ -5846,7 +5904,7 @@ CONFIG_APRICOT If you have a network (Ethernet) controller of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -5860,7 +5918,7 @@ These include the DE425, DE434, DE435, DE450 and DE500 models. If you have a network card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. More specific + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. More specific information is contained in Documentation/networking/de4x5.txt. This driver is also available as a module ( = code which can be @@ -5878,7 +5936,7 @@ (smc9332dst), you can also try the driver for "Generic DECchip" cards, above. However, most people with a network card of this type will say Y here.) Do read the Ethernet-HOWTO, available via FTP - (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. More specific information is contained in Documentation/networking/tulip.txt. @@ -5894,7 +5952,7 @@ PCI/EISA Ethernet switch cards. These include the SE-4 and the SE-6 models. If you have a network card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. More specific + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. More specific information is contained in Documentation/networking/dgrs.txt. This driver is also available as a module ( = code which can be @@ -5907,7 +5965,7 @@ CONFIG_EEXPRESS_PRO100 If you have an Intel EtherExpress PRO/100 PCI network (Ethernet) card, say Y and read the Ethernet-HOWTO, available via FTP (user: - anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5919,7 +5977,7 @@ CONFIG_ETH16I If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5932,7 +5990,7 @@ If you have a PCI Ethernet network card based on the ThunderLAN chip which is supported by this driver, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Devices currently supported by this driver are Compaq Netelligent, Compaq NetFlex and Olicom cards. Please read the file @@ -5961,7 +6019,7 @@ CONFIG_ES3210 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5974,7 +6032,7 @@ If you have an SMC EtherPower II 9432 PCI Ethernet network card which is based on the SMC83c170, say Y and read the Ethernet-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -5993,14 +6051,14 @@ (Ethernet) card, and this is the Linux driver for it. Note that the IBM Thinkpad 300 is compatible with the Z-Note and is also supported by this driver. Read the Ethernet-HOWTO, available via FTP (user: - anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Pocket and portable adapters CONFIG_NET_POCKET Cute little network (Ethernet) devices which attach to the parallel port ("pocket adapters"), commonly used with laptops. If you have one of those, say Y and read the Ethernet-HOWTO, available via FTP - (user: anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + (user: anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to plug a network card into the PCMCIA slot of your laptop instead (PCMCIA is the standard for credit card size @@ -6023,7 +6081,7 @@ This is a network (Ethernet) device which attaches to your parallel port. Read drivers/net/atp.c as well as the Ethernet-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO if you want to use this. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO if you want to use this. If you intend to use this driver, you should have said N to the Parallel Printer support, because the two drivers don't like each other. @@ -6033,7 +6091,7 @@ This is a network (Ethernet) device which attaches to your parallel port. Read Documentation/networking/DLINK.txt as well as the Ethernet-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO if you want to use this. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO if you want to use this. It is possible to have several devices share a single parallel port and it is safe to compile the corresponding drivers into the kernel. @@ -6047,7 +6105,7 @@ This is a network (Ethernet) device which attaches to your parallel port. Read Documentation/networking/DLINK.txt as well as the Ethernet-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO if you want to use this. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO if you want to use this. It is possible to have several devices share a single parallel port and it is safe to compile the corresponding drivers into the kernel. @@ -6065,7 +6123,7 @@ Ring card under Linux, say Y here and to the driver for your particular card below and read the Token-Ring mini-HOWTO, available via FTP (user:anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Most people can say N + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Most people can say N here. IBM Tropic chipset based adapter support @@ -6073,7 +6131,7 @@ This is support for all IBM Token Ring cards that don't use DMA. If you have such a beast, say Y and read the Token-Ring mini-HOWTO, available via FTP (user:anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Warning: this driver will almost definitely fail if more than one active Token Ring card is present. @@ -6091,7 +6149,7 @@ If you have such an adapter and would like to use it, say Y or M and read the Token-Ring mini-HOWTO, available via FTP (user: anonymous) - from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Also read the file linux/Documentation/networking/sktr.txt or check the Linux-SNA WWW site for the latest information at @@ -6181,7 +6239,7 @@ should say Y to this option if you wish to use it with Linux. EBSA-110 Ethernet interface -CONFIG_AM79C961A +CONFIG_ARM_AM79C961A If you wish to compile a kernel for the EBSA-110, then you should always answer Y to this. @@ -6189,7 +6247,7 @@ CONFIG_CD_NO_IDESCSI If you have a CDROM drive that is neither SCSI nor IDE/ATAPI, say Y here, otherwise N. Read the CDROM-HOWTO, available via FTP (user: - anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the answer to this question doesn't directly affect the kernel: saying N will just cause this configure script to skip all @@ -6446,7 +6504,7 @@ ext2 filesystem. You need additional software in order to use quota support; for details, read the Quota mini-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. Probably the quota + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. Probably the quota support is only useful for multi user systems. If unsure, say N. Minix fs support @@ -6487,7 +6545,7 @@ by about 41 kB. The Ext2fs-Undeletion mini-HOWTO, available via FTP (user: - anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini, + anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini, gives information about how to retrieve deleted files on ext2fs filesystems. @@ -6497,9 +6555,9 @@ Ext2fs partitions can be read from within DOS using the ext2tool command line tool package (available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/system/filesystems/ext2) and from + ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2) and from within Windows NT using the ext2nt command line tool package from - ftp://sunsite.unc.edu/pub/Linux/utils/dos. Explore2fs is a graphical + ftp://metalab.unc.edu/pub/Linux/utils/dos. Explore2fs is a graphical explorer for ext2fs partitions which runs on Windows 95 and Windows NT and includes experimental write support; it is available from http://jnewbigin-pc.it.swin.edu.au/Linux/Explore2fs.htm. @@ -6522,7 +6580,7 @@ listen to audio CDs and watch its LEDs, say Y (and read Documentation/filesystems/isofs.txt and the CDROM-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO), thereby enlarging your + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO), thereby enlarging your kernel by about 27 kB; otherwise say N. If you want to compile this as a module ( = code which can be @@ -6583,8 +6641,8 @@ they are compressed; to access compressed MSDOS partitions under Linux, you can either use the DOS emulator DOSEMU, described in the DOSEMU-HOWTO, available via FTP (user: anonymous) at - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, or try dmsdosfs in - ftp://sunsite.unc.edu/pub/Linux/system/filesystems/dosfs. If you + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, or try dmsdosfs in + ftp://metalab.unc.edu/pub/Linux/system/filesystems/dosfs. If you intend to use dosemu with a non-compressed MSDOS partition, say Y here) and MSDOS floppies. This means that file access becomes transparent, i.e. the MSDOS files look and behave just like all @@ -6683,7 +6741,7 @@ programs nfsd and mountd (but does not need to have NFS filesystem support enabled in its kernel). NFS is explained in the Network Administrator's Guide, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/LDP, on its man page: "man + ftp://metalab.unc.edu/pub/Linux/docs/LDP, on its man page: "man nfs", and in the NFS-HOWTO. A superior but less widely used alternative to NFS is provided by @@ -6703,7 +6761,7 @@ cannot compile this driver as a module in this case. There are two packages designed for booting diskless machines over the net: netboot and etherboot, both available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/system/boot/ethernet/ . + ftp://metalab.unc.edu/pub/Linux/system/boot/ethernet/ . If you don't know what all this is about, say N. @@ -6731,7 +6789,7 @@ You will need the support software from the linux-nfs package available at ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/. Please read the NFS-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO. The NFS server is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -6994,6 +7052,24 @@ whenever you want). If you want to compile it as a module, say M here and read Documentation/modules.txt. +Unixware slices support (EXPERIMENTAL) +CONFIG_UNIXWARE_DISKLABEL + Like some systems, Unixware uses, except DOS-like partition table, + its own slice table inside a partition (VTOC - Virtual Table of + Contents). Its format is incompatible with all other OSes. Saying Y + here allows you to read VTOC and further mount Unixware partitions + read-only from within Linux if you have also said Y to "UFS + filesystem support" or "System V and Coherent filesystem support", + above. + + This is mainly used to carry data from a Unixware box to your + Linux box via a removable medium like magneto-optical, ZIP or + removable IDE drives. Note, however, that a good portable way to + transport files and directories between unixes (and even other + operating systems) is given by the tar program ("man tar" or + preferably "info tar"). If you don't know what all this is about, + say N. + Macintosh partition map support CONFIG_MAC_PARTITION Say Y here if you want your Linux system to be able to read the @@ -7011,13 +7087,13 @@ transport protocol, and not NetBEUI. For details, read Documentation/filesystems/smbfs.txt and the SMB-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note: if you just want your box to act as an SMB *server* and make files and printing services available to Windows clients (which need to have a TCP/IP stack), you don't need to say Y here; you can use the program samba (available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/system/network/samba) for that. + ftp://metalab.unc.edu/pub/Linux/system/network/samba) for that. General information about how to connect Linux, Windows machines and Macs is on the WWW at http://www.eats.com/linux_mac_win.html (to @@ -7067,7 +7143,7 @@ mount NetWare file server volumes and to access them just like any other Unix directory. For details, please read the file Documentation/filesystems/ncpfs.txt in the kernel source and the - IPX-HOWTO on ftp://sunsite.unc.edu:/pub/Linux/docs/howto. + IPX-HOWTO on ftp://metalab.unc.edu:/pub/Linux/docs/howto. You do not have to say Y here if you want your Linux box to act as a file *server* for Novell NetWare clients. @@ -7489,7 +7565,7 @@ loadlin) about how to pass options to the kernel at boot time. The lilo procedure is also explained in the SCSI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.) If unsure, say Y. @@ -7553,7 +7629,7 @@ your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time. The lilo procedure is also explained in the SCSI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.) If you don't have a VGA card installed and you say Y here, the kernel will automatically use the first serial line, /dev/ttyS0, as @@ -7739,7 +7815,7 @@ box (as opposed to using a serial printer; if the connector at the printer has 9 or 25 holes ["female"], then it's serial), say Y. Also read the Printing-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. It is possible to share one parallel port among several devices (e.g. printer and ZIP drive) and it is safe to compile the @@ -7754,7 +7830,7 @@ of your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time. The lilo procedure is also explained in the SCSI-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) The standard base + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.) The standard base addresses as well as the syntax of the "lp" command line option can be found in drivers/char/lp.c. @@ -7774,7 +7850,7 @@ Microsoft mouse (made by Logitech) that plugs into a COM port (rectangular with 9 or 25 pins). These people say N here. If you have something else, read the Busmouse-HOWTO, available via FTP - (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and + (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO and say Y here. If you have a laptop, you either have to check the documentation or @@ -7792,7 +7868,7 @@ made by Logitech don't use the Logitech protocol anymore; for those, you don't need this option. You want to read the Busmouse-HOWTO, available via FTP (user: anonymous) in - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -7812,20 +7888,20 @@ Although PS/2 mice are not technically bus mice, they are explained in detail in the Busmouse-HOWTO, available via FTP (user: anonymous) - in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. When using a PS/2 mouse, you can get problems if you want to use the mouse both on the Linux console and under X. Using the "-R" option of the Linux mouse managing program gpm (available from - ftp://sunsite.unc.edu:/pub/Linux/system/Daemons) solves this - problem, or you can get the "mconv" utility also from sunsite. + ftp://metalab.unc.edu:/pub/Linux/system/Daemons) solves this + problem, or you can get the "mconv" utility also from metalab. C&T 82C710 mouse port support (as on TI Travelmate) CONFIG_82C710_MOUSE This is a certain kind of PS/2 mouse used on the TI Travelmate. If you are unsure, try first to say N here and come back if the mouse doesn't work. Read the Busmouse-HOWTO, available via FTP (user: - anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. PC110 digitizer pad support CONFIG_PC110_PAD @@ -7845,7 +7921,7 @@ These animals (also called Inport mice) are connected to an expansion board using a round connector with 9 pins. If this is what you have, say Y and read the Busmouse-HOWTO, available via FTP - (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you are unsure, say N and read the HOWTO nevertheless: it will tell you what you have. Also be aware that several vendors talk @@ -7862,7 +7938,7 @@ This is a rare type of busmouse that is connected to the back of an ATI video card. Note that most ATI mice are actually Microsoft busmice. Read the Busmouse-HOWTO, available via FTP (user: - anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. + anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -8204,11 +8280,8 @@ set the MTRRs for the boot CPU and not the secondary CPUs. This can lead to all sorts of problems. - In general you should compile this into the kernel, rather than as a - loadable module, because the BIOS fix needs to be done early in the - boot sequence. If you compile this as a module, the BIOS fix will be - delayed until when you load the module. You do this at your own - risk. + You can safely say Y even if your machine doesn't have MTRRs, you'll + just add about 3k to your kernel. See Documentation/mtrr.txt for more information. @@ -8234,7 +8307,7 @@ Supporting software is available; for more information, read the Battery Powered Linux mini-HOWTO, available via FTP (user: - anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. + anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. This driver does not spin down disk drives (see the hdparm(8) manpage ("man 8 hdparm") for that), and it doesn't turn off @@ -8328,7 +8401,7 @@ is halted. You will need software (e.g., a suitable version of the halt(8) command ("man 8 halt")) to cause the computer to power down. Recent versions of the sysvinit package available from - ftp://sunsite.unc.edu/pub/Linux/system/daemons/init/ (user: + ftp://metalab.unc.edu/pub/Linux/system/daemons/init/ (user: anonymous) contain support for this ("halt -p" shuts down Linux and powers off the computer, if executed from runlevel 0). As with the other APM options, this option may not work reliably with some APM @@ -8461,13 +8534,8 @@ 24 hour alarm. It reports status information via the file /proc/rtc and its behaviour is set by various ioctls on /dev/rtc. - People running SMP (multiprocessor) versions of Linux should say Y - here to read and set the RTC clock in a SMP compatible - fashion. (They should also read Documentation/smp and - Documentation/IO-APIC.txt and the SMP-FAQ on the WWW at - http://www.irisa.fr/prive/mentre/smp-faq/ (to browse the WWW, you - need to have access to a machine on the Internet that has a program - like lynx or netscape).) + If you enabled CONFIG_SMP, you should say Y here to read and set the + RTC clock in an SMP compatible fashion. If you think you have a use for such a device (such as periodic data sampling), then say Y here, and read Documentation/rtc.txt for @@ -8491,7 +8559,11 @@ and "NVRAM" on Ataris. /dev/nvram may be used to view settings there, or to change them (with some utility). It could also be used to frequently save a few bits of very important data that may not be - lost over power-off and for which writing to disk is too insecure. + lost over power-off and for which writing to disk is too insecure. Note + however that most NVRAM space in a PC belongs to the BIOS and you should + NEVER idly tamper with it. See Ralf Browns interrupt list for a guide to + the use of CMOS bytes by your BIOS. + On Atari machines, /dev/nvram is always configured and does not need to be selected. @@ -8610,7 +8682,7 @@ about your sound card and its configuration down (I/O port, interrupt and DMA channel), because you will be asked for it. You want to read the Sound-HOWTO, available via FTP (user: anonymous) - from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. There is also some + from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. There is also some information in various README files in drivers/sound, esp. in Readme.cards which you should read first to find out whether your card is supported by Linux, and, if yes, which driver to use. @@ -8645,6 +8717,14 @@ cards from Aztech. It supports the Waverider Pro 32 - 3D and the Galaxy Washington 16. +Support for AD1816(A) based cards (EXPERIMENTAL) +CONFIG_SOUND_AD1816 + Say M here if you have a soundcard based on the Analog Devices + AD1816(A) chip. + + NOTE: This driver is still EXPERIMENTAL. + See Documentation/sound/AD1816 for further information. + Yamaha OPL3-SA1 audio controller CONFIG_SOUND_OPL3SA1 Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is @@ -8852,9 +8932,11 @@ See Documentation/sound/CS4232 for more information on configuring this card. -Support for Yamaha OPL3-SA[2,3,x] based (PnP) cards +Support for Yamaha OPL3-SA2, SA3, and SAx based PnP cards CONFIG_SOUND_OPL3SA2 - Say Y or M here if you have such a sound card. + Say Y or M if you have a card based on one of these Yamaha + sound chipsets. Read Documentation/sound/OPL3-SA2 for more + information on configuring these cards. Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers CONFIG_SOUND_MAUI @@ -8975,16 +9057,16 @@ affect the kernel; saying Y will simply cause this configure script to present you with more options. If unsure, say Y. -ACI mixer (miroPCM12) +ACI mixer (miroPCM12/PCM20) CONFIG_ACI_MIXER Audio Command Interface (ACI) driver. ACI is a protocol used to communicate with the microcontroller on some sound cards produced by miro, e.g. the miroSOUND PCM12 and PCM20. The main function of the ACI is to control the mixer and to get a product identification. This Voxware ACI driver currently only supports the ACI functions on - the miroSOUND PCM12 card. On the PCM20, ACI also controls the radio - tuner on this card, however this is not yet supported in this - software. + the miroSOUND PCM12 and PCM20 cards. On the PCM20, ACI also controls + the radio tuner. This is supported in the video4linux radio-miropcm20 + driver. SB32/AWE support CONFIG_AWE32_SYNTH @@ -8992,7 +9074,7 @@ similar sound card. See drivers/sound/lowlevel/README.awe, Documentation/sound/AWE32 and the Soundblaster-AWE mini-HOWTO, available via FTP (user: anonymous) from - ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini for more info. + ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini for more info. Gallant's Audio Excel DSP 16 support (SC-6000 and SC-6600) CONFIG_AEDSP16 @@ -9013,17 +9095,11 @@ Documentation/sound/AudioExcelDSP16 to get more information about this driver and its configuration. -SC-6600 based audio cards (new Audio Excel DSP 16) -CONFIG_SC6600 - The SC6600 is the new version of DSP mounted on the Audio Excel DSP - 16 cards. Find in the manual the FCC ID of your audio card and - answer Y if you have an SC6600 DSP. - -Audio Excel DSP 16 (MSS emulation) -CONFIG_AEDSP16_MSS - Answer Y if you want your audio card to emulate Microsoft Sound - System. You should then say Y to "Microsoft Sound System support" - and say N to "Audio Excel DSP 16 (SBPro emulation)". +I/O base for Audio Excel DSP 16 +CONFIG_AEDSP16_BASE + This is the base I/O address of the Audio Excel DSP 16 card. It must + be 220 or 240. If you compiled aedsp16.o as a module you can specify + this parameter as 'io=0xNNN'. Audio Excel DSP 16 (SBPro emulation) CONFIG_AEDSP16_SBPRO @@ -9032,6 +9108,68 @@ (SB16/32/64, ESS, Jazz16) support" and N to "Audio Excel DSP 16 (MSS emulation)". +Audio Excel DSP 16 IRQ +CONFIG_AEDSP16_SB_IRQ + This is the IRQ of the Audio Excel DSP 16 card. It must be 5, 7, 9, + 10 or 11. If you compiled aedsp16.o as a module you can specify + this parameter as 'irq=NN'. + +Audio Excel DSP 16 DMA +CONFIG_AEDSP16_SB_DMA + This is the IRQ of the Audio Excel DSP 16 card. It must be 0, 1 or 3. + If you compiled aedsp16.o as a module you can specify this parameter + as 'dma=NN'. + +Audio Excel DSP 16 (MSS emulation) +CONFIG_AEDSP16_MSS + Answer Y if you want your audio card to emulate Microsoft Sound + System. You should then say Y to "Microsoft Sound System support" + and say N to "Audio Excel DSP 16 (SBPro emulation)". + +Audio Excel DSP 16 IRQ +CONFIG_AEDSP16_MSS_IRQ + This is the IRQ of the Audio Excel DSP 16 card. It must be 5, 7, 9, + 10 or 11. If you compiled aedsp16.o as a module you can specify + this parameter as 'irq=NN'. + +Audio Excel DSP 16 DMA +CONFIG_AEDSP16_MSS_DMA + This is the IRQ of the Audio Excel DSP 16 card. It must be 0, 1 or 3. + If you compiled aedsp16.o as a module you can specify this parameter + as 'dma=NN'. + +SC-6600 based audio cards (new Audio Excel DSP 16) +CONFIG_SC6600 + The SC6600 is the new version of DSP mounted on the Audio Excel DSP + 16 cards. Find in the manual the FCC ID of your audio card and + answer Y if you have an SC6600 DSP. + +SC-6600 Joystick Interface +CONFIG_SC6600_JOY + This option activate the Joystick interface of Audio Excel DSP 16 card. + +SC-6600 CDROM Interface +CONFIG_SC6600_CDROM + This option activate the CDROM interface of Audio Excel DSP 16 card. + Required parameter can be: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for + no CDROM present. + +Audio Excel DSP 16 (MPU401 emulation) +CONFIG_AEDSP16_MPU401 + Answer Y if you want your audio card to emulate the MPU-401 midi + interface. You should then say Y to "MPU-401 support". + You have to hote that the I/O base for MPU-401 support of aedsp16 is + the same you have selected for "MPU-401 support". If you are using + this driver as a module you have to specify the MPU I/O base address + with the parameter 'mpu_base=0xNNN'. + +MPU401 IRQ for Audio Excel DSP 16 +CONFIG_AEDSP16_MPU_IRQ + This is the IRQ of the MPU-401 emulation of Audio Excel DSP 16 card. + It must be 5, 7, 9, 10 or 0 (to disable MPU-401 interface). If you + compiled aedsp16.o as a module you can specify this parameter as + 'mpu_irq=NN'. + Ensoniq ES1370 based PCI sound cards CONFIG_SOUND_ES1370 Say Y or M if you have a PCI sound card utilizing the Ensoniq @@ -9057,6 +9195,15 @@ models are either ES1370 or ES1371 based. This driver differs slightly from OSS/Free, so PLEASE READ Documentation/sound/es1371. +Gameport I/O-range selection +CONFIG_SOUND_ES1371_GAMEPORT + Select the I/O-range of the gameport on a ES1371 based soundcard. + The card uses 8 ioports and the gameport is available at all eight + ioports. Legal hexadecimal values are 200, 208, 210 and 218. + The joystick driver will by default use 0x201. + Leave the default 200 unless you have a joystick not attached + to your soundcard. + S3 SonicVibes based PCI sound cards CONFIG_SOUND_SONICVIBES Say Y or M if you have a PCI sound card utilizing the S3 @@ -9489,6 +9636,13 @@ Say N unless you're willing to code the remaining necessary support. ;) +HP9000/300 support +CONFIG_HP300 + This option enables support for the HP9000/300 series of workstations. + Support for these machines is still very experimental. If you plan to + try to use the kernel on such a machine say Y here. Everybody else + says N. + # CONFIG_APOLLO, etc. coming soon (?) 68020 support @@ -9932,6 +10086,21 @@ want). If you want to compile it as a module, say M here and read Documentation/modules.txt. +HP DCA serial support +CONFIG_HPDCA + If you want to use the internal "DCA" serial ports on an HP300 + machine, say Y here. + +HP on-board LANCE support +CONFIG_HPLANCE + If you want to use the builtin "LANCE" Ethernet controller on an HP300 + machine, say Y here. + +DIO bus support +CONFIG_DIO + Say Y here to enable support for the "DIO" expansion bus used in HP300 + machines. If you are using such a system you almost certainly want this. + MSDOS partition support CONFIG_MSDOS_PARTITION This option enables support for using hard disks that were @@ -10139,8 +10308,9 @@ Miro PCM20 Radio CONFIG_RADIO_MIROPCM20 - Choose Y here if you have one of these FM radio cards, and then fill - in the port address below. + Choose Y here if you have this FM radio card. You also need the + PCM12/PCM20 ACI mixer in additional low level sound drivers for this + to work. In order to control your radio card, you will need to use programs that are compatible with the Video for Linux API. Information on @@ -10154,6 +10324,28 @@ say M here and read Documentation/modules.txt. The module will be called radio-miropcm20.o +GemTek Radio Card +CONFIG_RADIO_GEMTEK + Choose Y here if you have this FM radio card, and then fill in the + port address below. + + In order to control your radio card, you will need to use programs + that are compatible with the Video for Linux API. Information on + this API and pointers to "v4l" programs may be found on the WWW at + http://roadrunner.swansea.uk.linux.org/v4l.shtml; to browse the WWW, + you need to have access to a machine on the Internet that has a + program like lynx or netscape. + + If you want to compile this driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read Documentation/modules.txt. The module will be + called radio-gemtek.o. + +GemTek i/o port +CONFIG_RADIO_GEMTEK_PORT + Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is + 0x34c, if you haven't changed the jumper setting on the card. + BT848 Video For Linux CONFIG_VIDEO_BT848 Support for BT848 based frame grabber/overlay boards. This includes @@ -10216,6 +10408,19 @@ to set this option to, please consult any information supplied with your system. +Include support for CATS boards +CONFIG_CATS + Say Y here if you wish to include support for the extra hardware found + in Chalice CATS machines. The resulting kernel will still run on an + EBSA-285 but will be slightly larger. If in doubt say N. + +Debug kernel errors +CONFIG_DEBUG_ERRORS + This option controls verbose debugging information which can be printed + when the kernel detects an internal error. Verbose debugging information + is useful when tracking down kernel problems, but it will be meaning less + for non-kernel hackers. It's safe for everyone to say Y. + Build Tools Selection CONFIG_BINUTILS_NEW Say Y here if and only if you're using GCC 2.8.1/EGCS with a @@ -10228,6 +10433,261 @@ it will give useful debugging/error results. If you don't debug the kernel, you can say N. +Initial kernel command line +CONFIG_CMDLINE + On some architectures (EBSA285, EBSA110 and Corel Netwinder), there is + currently no way for the boot loader to pass arguments to the kernel. + For these architectures, you should supply some command-line options + at build time by entering them here. As a minimum, you should specify + the memory size and the root device (eg, mem=64M root=/dev/nfs) + +IrDA Protocols +CONFIG_IRDA + Say Y here if you want to build support for the IrDA (TM) + protocols. The Infrared Data Associations (tm) specifies standards + for wireless infrared communication and is supported by most laptops + and PDA's If you want to compile it as a module, say M here and read + Documentation/modules.txt. + + To use Linux support for the IrDA (tm) protocols, you will also need + some user-space utilities like the irmanager and probably irattach + as well. For more information, visit + http://www.cs.uit.no/~dagb/irda/ + +IrDA Cache last LSAP +CONFIG_IRDA_CACHE_LAST_LSAP + Say Y here if you want IrLMP to cache the last LSAP used. This makes + sense since most frames will be sent/received on the same connection. + Enabling this option will save a hash-lookup per frame. + + If unsure, say Y. + +IrDA Fast RR's +CONFIG_IRDA_FAST_RR + Say Y here is you want IrLAP to send fast RR (Receive Ready) frames + when acting as a primary station. This will make IrLAP send out a RR + frame immediately when receiving a frame if its own transmit queue is + currently empty. This will give a lot of speed improvement when + receiving much data since the secondary station will not have to + wait the max. turn around time before it is allowed to transmit the + next time. If the transmit queue of the secondary is also empty the + primary will back off waiting longer for sending out the RR frame + until the timeout reaches the normal value. Enabling this option + will make the IR-diode burn more power and thus reduce your battery + life. + + If unsure, say N. + +IrDA Recycle RR's +CONFIG_IRDA_RECYCLE_RR + In the normal life of the IrLAP protocol, it sends a lot of small RR + (Receive Ready) frames over the link (at least when it has nothing + else to do). Saying Y to this option will make IrLAP recycle these + frames thus avoiding many alloc_skb's and kfree_skb's. To do this it + will only buffer one of these frame which is enough for the normal + case. + + If unsure, say Y. + +IrLAP Compression support +CONFIG_IRDA_COMPRESSION + Compression is _not_ part of the IrDA(tm) protocol specification, + but its working great! Linux is the first to try out compresson + support at the IrLAP layer. This means that you will only benefit + from compression if you are running a Linux <-> Linux configuration + +IrLAP Deflate Compression Protocol +CONFIG_IRDA_DEFLATE + Say Y here if you want to build support for the Deflate compression + protocol. If you want to compile it as a module, say M here and read + Documentation/modules.txt. The deflate compression (GZIP) is exactly + the same as used by the PPP protocol. Enabling this option will + build a module called irda_deflate.o + +IrLAN Protocol +CONFIG_IRLAN + Say Y here if you want to build support for the IrLAN protocol. If + you want to compile it as a module, say M here and read + Documentation/modules.txt. IrLAN emulates an Ethernet and makes it + possible to put up an wireless LAN using infrared beams. + +IrLAN Client Protocol +CONFIG_IRLAN_CLIENT + Say Y here if you want to build support for the IrLAN client + protocol. If you want to compile it as a module, say M here and read + Documentation/modules.txt. The IrLAN client protocol can be used to + talk with infrared access points like the HP NetbeamIR, or the ESI + JetEye NET. You can also connect to another Linux machine running + the IrLAN server protocol for ac-hoc networking! + +IrLAN Server Protocol +CONFIG_IRLAN_SERVER + Say Y here if you want to build support for infrared LAN access. If + you want to compile it as a module, say M here and read + Documentation/modules.txt. The IrLAN server protocol makes it + possible to set up a wireless LAN with a machine running the IrLAN + client protocol. Notice that the IrLAN server protocol currently + only emulates an access point and does not implement the ad-hoc + specification of IrLAN, but this will not be noticeable for the + user. + +IrOBEX Protocol +CONFIG_IROBEX + Say Y here if you want to build support for the IrOBEX protocol. If + you want to compile it as a module, say M here and read + Documentation/modules.txt. The module does not actually implement + the IrOBEX protocol since that protocol lives in userspace, but it + contains the necessary functions to interface the user-space stuff + with the kernel. So you will need to have the user-space library and + programs that can use this library installed as well to be able to + use the IrOBEX protocol. This module will hopefully be replaced by + IrDA sockets in the future. + +IrCOMM Protocol +CONFIG_IRCOMM + Say Y here if you want to build support for the IrCOMM protocol. If + you want to compile it as a module, say M here and read + Documentation/modules.txt. IrCOMM implements serial port emulation, + and makes it possible to use all existing applications that + understands TTY's with an infrared link. Thus you should be able to + use application like PPP, minicom and others. Enabling this option + will create two modules called ircomm and ircomm_tty. For more + information go to http://www.pluto.dti.ne.jp/~thiguchi/irda/ + +IrTTY IrDA Device Driver +CONFIG_IRTTY_SIR + Say Y here if you want to build support for the IrTTY line + discipline. If you want to compile it as a module, say M here and + read Documentation/modules.txt. IrTTY makes it possible to use + Linux's own serial driver for all IrDA ports that are 16550 + compatible. Most IrDA chips are 16550 compatible so you should + probably say Y to this option. Using IrTTY will however limit the + speed of the connection to 115200 bps (IrDA SIR mode) + + If unsure, say Y. + +Winbond W83977AF IrDA Device Driver +CONFIG_WINBOND_FIR + Say Y here if you want to build IrDA support for the Winbond W83977AF + super-io chipset. If you want to compile it as a module, say M here + and read Documentation/modules.txt. This driver should be used for + the IrDA chipset in the Corel NetWinder. The driver supports SIR, + MIR and FIR (4Mbps) speeds. + +NSC PC87108 IrDA Device Driver +CONFIG_NSC_FIR + Say Y here if you want to build support for the NSC PC87108 IrDA + chipset. If you want to compile it as a module, say M here and + read Documentation/modules.txt. This drivers currently only supports + the ACTiSYS IR2000B ISA card and supports SIR, MIR and FIR (4Mbps) + speeds. + +ESI JetEye PC Dongle +CONFIG_ESI_DONGLE + Say Y here if you want to build support for the Extended Systems + JetEye PC dongle. If you want to compile it as a module, say M here + and read Documentation/modules.txt. The ESI dongle attaches to the + normal 9-pin serial port connector, and can currently only be used + by IrTTY. To activate support for ESI dongles you will have to + insert "irattach -d esi" in the /etc/irda/drivers script. + +ACTiSYS IR-220L and IR220L+ dongle +CONFIG_ACTISYS_DONGLE + Say Y here if you want to build support for the ACTiSYS + IR-220L and IR220L+ dongles. If you want to compile it as a module, + say M here and read Documentation/modules.txt. The ACTiSYS dongles + attaches to the normal 9-pin serial port connector, and can + currently only be used by IrTTY. To activate support for ACTiSYS + dongles you will have to insert "irattach -d actisys" or + "irattach -d actisys_plus" in the/etc/irda/drivers script. + +Tekram IrMate 210B dongle +CONFIG_TEKRAM_DONGLE + Say Y here if you want to build support for the Tekram IrMate 210B + dongle. If you want to compile it as a module, say M here + and read Documentation/modules.txt. The Tekram dongle attaches to + the normal 9-pin serial port connector, and can currently only be + used by IrTTY. To activate support for Tekram dongles you will have + to insert "irattach -d tekram" in the /etc/irda/drivers script. + +VME (Motorola and BVM) support +CONFIG_VME + Say Y here if you want to build a kernel for a 680x0 based VME + board. Boards currently supported include Motorola boards MVME162, + MVME166, MVME167, MVME172, and MVME177. BVME4000 and BVME6000 + boards from BVM Ltd are also supported. + +MVME162, 166 and 167 support +CONFIG_MVME16x + Say Y to include support for Motorola VME boards. This will build a + kernel which can run on MVME162, MVME166, MVME167, MVME172, and + MVME177 boards. If you select this option you will have to select + the appropriate drivers for SCSI, Ethernet and serial ports later + on. + +BVME4000 and BVME6000 support +CONFIG_BVME6000 + Say Y to include support for VME boards from BVM Ltd. This will + build a kernel which can run on BVME4000 and BVME6000 boards. If + you select this option you will have to select the appropriate + drivers for SCSI, Ethernet and serial ports later on. + +Use write-through caching for 68060 supervisor accesses +CONFIG_060_WRITETHROUGH + The 68060 generally uses copyback caching of recently accessed data. + Copyback caching means that memory writes will be held in an on-chip + cache and only written back to memory some time later. Saying Y + here will force supervisor (kernel) accesses to use writethrough + caching. Writethrough caching means that data is written to memory + straight away, so that cache and memory data always agree. + Writethrough caching is less efficient, but is needed for some + drivers on 68060 based systems where the 68060 bus snooping signal + is hardwired on. The 53c710 SCSI driver is known to suffer from + this problem. + +NCR53C710 SCSI driver for MVME16x +CONFIG_MVME16x_SCSI + The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710 + SCSI controller chip. Almost everyone using one of these boards + will want to say Y to this question. + +NCR53C710 SCSI driver for BVME6000 +CONFIG_BVME6000_SCSI + The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710 + SCSI controller chip. Almost everyone using one of these boards + will want to say Y to this question. + +MVME16x Ethernet support +CONFIG_MVME16x_NET + This is the driver for the Ethernet interface on the Motorola + MVME162, 166, 167, 172 and 177 boards. Say Y here to include the + driver for this chip in your kernel. If you want to compile it as + a module, say M here and read Documentation/modules.txt. + +BVME6000 Ethernet support +CONFIG_BVME6000_NET + This is the driver for the Ethernet interface on BVME4000 and + BVME6000 VME boards. Say Y here to include the driver for this chip + in your kernel. If you want to compile it as a module, say M here + and read Documentation/modules.txt. + +CD2401 support for MVME166/7 serial ports +CONFIG_SERIAL167 + This is the driver for the serial ports on the Motorola MVME166, + 167, and 172 boards. Everyone using one of these boards should say + Y here. + +SCC support for MVME162 serial ports +CONFIG_MVME162_SCC + This is the driver for the serial ports on the Motorola MVME162 and + 172 boards. Everyone using one of these boards should say Y here. + +SCC support for BVME6000 serial ports +CONFIG_BVME6000_SCC + This is the driver for the serial ports on the BVME4000 and BVME6000 + boards from BVM Ltd. Everyone using one of these boards should say + Y here. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DMA, FTP, Internet, Intel, IRQ, @@ -10237,7 +10697,7 @@ # # This is used by Emacs' spell checker ispell.el: # -# LocalWords: CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp sunsite +# LocalWords: CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp metalab # LocalWords: unc edu docs emu README kB BLK DEV FD Thinkpad fd MFM RLL IDE gz # LocalWords: cdrom diskless netboot nfs xzvf ATAPI MB ide pavia rubini pl pd # LocalWords: HD CDROMs IDECD NEC MITSUMI filesystem XT XD PCI BIOS cezar ATEN diff -u --recursive --new-file v2.1.132/linux/MAINTAINERS linux/MAINTAINERS --- v2.1.132/linux/MAINTAINERS Thu Nov 19 09:56:27 1998 +++ linux/MAINTAINERS Sun Dec 27 10:26:11 1998 @@ -94,9 +94,12 @@ S: Maintained W: http://rsphy1.anu.edu.au/~gpg109/ne2000.html -AEDSP16 DRIVER -P: Riccardo Facchetti -M: fizban@tin.it +AD1816 SOUND DRIVER +P: Thorsten Knabe +M: Thorsten Knabe +M: Thorsten Knabe +W: http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html +W: http://www.tu-darmstadt.de/~tek01/projects/linux.html S: Maintained ADVANSYS SCSI DRIVER @@ -105,6 +108,11 @@ W: http://www.advansys.com/linux S: Maintained +AEDSP16 DRIVER +P: Riccardo Facchetti +M: fizban@tin.it +S: Maintained + AHA152X SCSI DRIVER P: Juergen E. Fischer M: Juergen Fischer @@ -167,14 +175,26 @@ M: boldt@math.ucsb.edu S: Maintained +COSA/SRP SYNC SERIAL DRIVER +P: Jan "Yenya" Kasprzak +M: kas@fi.muni.cz +W: http://www.fi.muni.cz/~kas/cosa/ +S: Maintained + +COSA/SRP SYNC SERIAL DRIVER +P: Jan "Yenya" Kasprzak +M: kas@fi.muni.cz +W: http://www.fi.muni.cz/~kas/cosa/ +S: Maintained + CREDITS FILE P: John A. Martin M: jam@acm.org S: Maintained CYCLADES ASYNC MUX DRIVER -P: Marcio Saito -M: Marcio Saito +P: Ivan Passos +M: Ivan Passos W: http://www.cyclades.com/ S: Supported @@ -188,13 +208,15 @@ DC390/AM53C974 SCSI driver P: Kurt Garloff -M: K.Garloff@ping.de -W: ftp://student.physik.uni-dortmund.de/pub/linux/kernel/dc390/ +M: kurt@garloff.de +W: http://www.garloff.de/kurt/linux/dc390/ S: Maintained DECnet NETWORK LAYER P: Steven Whitehouse M: SteveW@ACM.org +W: http://www.sucs.swan.ac.uk/~rohan/ +W: http://www-sigproc.eng.cam.ac.uk/~sjw44/ L: netdev@roxanne.nuclecu.unam.mx S: Maintained @@ -350,7 +372,7 @@ IP FIREWALL P: Paul Russell M: Paul.Russell@rustcorp.com.au -W: http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html +W: http://www.rustcorp.com/linux/ipchains S: Supported IPX/SPX NETWORK LAYER @@ -359,6 +381,13 @@ L: linux-net@vger.rutgers.edu S: Maintained +IRDA SUBSYSTEM +P: Dag Brattli +M: Dag Brattli +L: linux-irda@list.uit.no +W: http://www.cs.uit.no/~dagb/irda/ +S: Maintained + ISDN SUBSYSTEM P: Fritz Elfert M: fritz@wuemaus.franken.de @@ -448,6 +477,13 @@ L: linux-kernel@vger.rutgers.edu S: Maintained +MTRR AND SIMILAR SUPPORT [i386] +P: Richard Gooch +M: rgooch@atnf.csiro.au +L: linux-kernel@vger.rutgers.edu +W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html +S: Maintained + MULTISOUND SOUND DRIVER P: Andrew Veliath M: andrewtv@usa.net @@ -457,7 +493,7 @@ P: Petr Vandrovec M: vandrove@vc.cvut.cz P: Volker Lendecke -M: lendecke@Math.Uni-Goettingen.de +M: vl@kki.org L: linware@sh.cvut.cz S: Maintained @@ -502,6 +538,12 @@ L: linux-kernel@vger.rutgers.edu S: Maintained +OPL3-SA2, SA3, and SAx DRIVER +P: Scott Murray +M: scottm@interlog.com +L: linux-sound@vger.rutgers.edu +S: Maintained + PARALLEL PORT SUPPORT P: Phil Blundell M: Philip.Blundell@pobox.com @@ -596,7 +638,7 @@ SMB FILESYSTEM P: Volker Lendecke -M: lendecke@Math.Uni-Goettingen.de +M: vl@kki.org L: samba@listproc.anu.edu.au S: Maintained diff -u --recursive --new-file v2.1.132/linux/Makefile linux/Makefile --- v2.1.132/linux/Makefile Tue Dec 22 14:16:53 1998 +++ linux/Makefile Mon Dec 28 14:09:00 1998 @@ -1,6 +1,7 @@ VERSION = 2 -PATCHLEVEL = 1 -SUBLEVEL = 132 +PATCHLEVEL = 2 +SUBLEVEL = 0 +EXTRAVERSION =-pre1 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) @@ -58,6 +59,8 @@ ROOT_DEV = CURRENT +KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) + # # INSTALL_PATH specifies where to place the updated kernel and system map # images. Uncomment if you want to place them anywhere other than root. @@ -278,7 +281,7 @@ @mv -f .ver $@ include/linux/version.h: ./Makefile - @echo \#define UTS_RELEASE \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)\" > .ver + @echo \#define UTS_RELEASE \"$(KERNELRELEASE)\" > .ver @echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver @echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver @mv -f .ver $@ @@ -305,7 +308,7 @@ modules_install: @( \ - MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(VERSION).$(PATCHLEVEL).$(SUBLEVEL); \ + MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE); \ cd modules; \ MODULES=""; \ inst_mod() { These="`cat $$1`"; MODULES="$$MODULES $$These"; \ diff -u --recursive --new-file v2.1.132/linux/arch/alpha/defconfig linux/arch/alpha/defconfig --- v2.1.132/linux/arch/alpha/defconfig Sun Nov 8 14:02:41 1998 +++ linux/arch/alpha/defconfig Wed Dec 23 07:34:11 1998 @@ -42,6 +42,7 @@ # CONFIG_ALPHA_SX164 is not set # CONFIG_ALPHA_SABLE is not set # CONFIG_ALPHA_TAKARA is not set +# CONFIG_SMP is not set CONFIG_PCI=y CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y # CONFIG_PCI_QUIRKS is not set diff -u --recursive --new-file v2.1.132/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c --- v2.1.132/linux/arch/alpha/kernel/irq.c Tue Dec 22 14:16:53 1998 +++ linux/arch/alpha/kernel/irq.c Sun Dec 27 15:21:50 1998 @@ -38,13 +38,6 @@ unsigned int local_bh_count[NR_CPUS]; unsigned long hardirq_no[NR_CPUS]; -#define RTC_IRQ 8 -#ifdef CONFIG_RTC -#define TIMER_IRQ 0 /* timer is the pit */ -#else -#define TIMER_IRQ RTC_IRQ /* the timer is, in fact, the rtc */ -#endif - #if NR_IRQS > 64 # error Unable to handle more than 64 irq levels. #endif @@ -824,7 +817,7 @@ * Wait about 100ms for spurious interrupts to mask themselves * out again... */ - for (delay = jiffies + HZ/10; delay > jiffies; ) + for (delay = jiffies + HZ/10; time_before(jiffies, delay); ) barrier(); /* Now filter out any obviously spurious interrupts. */ diff -u --recursive --new-file v2.1.132/linux/arch/alpha/kernel/irq.h linux/arch/alpha/kernel/irq.h --- v2.1.132/linux/arch/alpha/kernel/irq.h Fri Oct 23 22:01:19 1998 +++ linux/arch/alpha/kernel/irq.h Sun Dec 27 15:21:50 1998 @@ -21,3 +21,11 @@ extern void srm_device_interrupt(unsigned long vector, struct pt_regs * regs); extern void handle_irq(int irq, int ack, struct pt_regs * regs); + +#define RTC_IRQ 8 +#ifdef CONFIG_RTC +#define TIMER_IRQ 0 /* timer is the pit */ +#else +#define TIMER_IRQ RTC_IRQ /* timer is the rtc */ +#endif + diff -u --recursive --new-file v2.1.132/linux/arch/alpha/kernel/sys_ruffian.c linux/arch/alpha/kernel/sys_ruffian.c --- v2.1.132/linux/arch/alpha/kernel/sys_ruffian.c Fri Nov 27 13:09:22 1998 +++ linux/arch/alpha/kernel/sys_ruffian.c Sun Dec 27 15:21:50 1998 @@ -92,6 +92,12 @@ i = ffz(~pld); pld &= pld - 1; /* clear least bit set */ if (i == 7) { /* if ISA int */ + /* Ruffian does not have the RTC connected to + the CPU timer interrupt. Instead, it uses the + PIT connected to IRQ 0. So we must detect that + and route that specifically to where we expected + to find the timer interrupt come in. */ + /* Copy this code from isa_device_interrupt because we need to hook into int 0 for the timer. I refuse to soil device_interrupt with ifdefs. */ @@ -107,7 +113,7 @@ if (j == 7 && !(inb(0x20) & 0x80)) { /* It's only a passive release... */ } else if (j == 0) { - handle_irq(8, -1, regs); /* fake it */ + handle_irq(TIMER_IRQ, -1, regs); ruffian_ack_irq(0); } else { handle_irq(j, j, regs); diff -u --recursive --new-file v2.1.132/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c --- v2.1.132/linux/arch/alpha/kernel/time.c Wed Dec 16 10:32:54 1998 +++ linux/arch/alpha/kernel/time.c Sun Dec 27 15:21:50 1998 @@ -35,12 +35,7 @@ #include #include "proto.h" - -#ifdef CONFIG_RTC -#define TIMER_IRQ 0 /* using pit for timer */ -#else -#define TIMER_IRQ 8 /* using rtc for timer */ -#endif +#include "irq.h" static int set_rtc_mmss(unsigned long); diff -u --recursive --new-file v2.1.132/linux/arch/arm/kernel/ecard.c linux/arch/arm/kernel/ecard.c --- v2.1.132/linux/arch/arm/kernel/ecard.c Tue Dec 22 14:16:53 1998 +++ linux/arch/arm/kernel/ecard.c Mon Dec 28 11:04:21 1998 @@ -215,7 +215,7 @@ } else lockup = 0; - if (!last || last + 500 < jiffies) { + if (!last || time_after(jiffies, last + 5*HZ)) { last = jiffies; printk(KERN_ERR "\nUnrecognised interrupt from backplane\n"); } diff -u --recursive --new-file v2.1.132/linux/arch/arm/kernel/hw-ebsa285.c linux/arch/arm/kernel/hw-ebsa285.c --- v2.1.132/linux/arch/arm/kernel/hw-ebsa285.c Tue Dec 22 14:16:53 1998 +++ linux/arch/arm/kernel/hw-ebsa285.c Wed Dec 23 09:44:40 1998 @@ -123,7 +123,7 @@ err = "system"; break; } - if (next_warn[idx] <= jiffies) { + if (time_after_eq(jiffies, next_warn[idx])) { next_warn[idx] = jiffies + 3 * HZ / 100; printk(KERN_ERR "PCI %s error detected\n", err); } diff -u --recursive --new-file v2.1.132/linux/arch/arm/kernel/irq.c linux/arch/arm/kernel/irq.c --- v2.1.132/linux/arch/arm/kernel/irq.c Tue Dec 22 14:16:53 1998 +++ linux/arch/arm/kernel/irq.c Wed Dec 23 09:44:40 1998 @@ -356,7 +356,7 @@ /* * wait for spurious interrupts to mask themselves out again */ - for (delay = jiffies + HZ/10; delay > jiffies; ) + for (delay = jiffies + HZ/10; time_before(jiffies, delay); ) /* min 100ms delay */; /* diff -u --recursive --new-file v2.1.132/linux/arch/i386/config.in linux/arch/i386/config.in --- v2.1.132/linux/arch/i386/config.in Tue Dec 22 14:16:53 1998 +++ linux/arch/i386/config.in Sun Dec 27 10:48:46 1998 @@ -17,9 +17,7 @@ Pentium/K5/5x86/6x86 CONFIG_M586 \ PPro/K6/6x86MX CONFIG_M686" Pentium bool 'Math emulation' CONFIG_MATH_EMULATION -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR -fi +bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR bool 'Symmetric multi-processing support' CONFIG_SMP endmenu @@ -38,10 +36,16 @@ bool 'Networking support' CONFIG_NET bool 'PCI support' CONFIG_PCI if [ "$CONFIG_PCI" = "y" ]; then - bool ' PCI BIOS support' CONFIG_PCI_BIOS - bool ' PCI direct access support' CONFIG_PCI_DIRECT - if [ "$CONFIG_PCI_BIOS" = "n" -a "$CONFIG_PCI_DIRECT" = "n" ]; then - define_bool CONFIG_PCI_BIOS "y" + unset CONFIG_PCI_BIOS CONFIG_PCI_DIRECT + choice 'PCI access mode' \ + "BIOS CONFIG_PCI_GOBIOS \ + Direct CONFIG_PCI_GODIRECT \ + Any CONFIG_PCI_GOANY" Any + if [ -n "$CONFIG_PCI_GOBIOS" -o -n "$CONFIG_PCI_GOANY" ]; then + define_bool CONFIG_PCI_BIOS y + fi + if [ -n "$CONFIG_PCI_GODIRECT" -o -n "$CONFIG_PCI_GOANY" ]; then + define_bool CONFIG_PCI_DIRECT y fi bool ' PCI quirks' CONFIG_PCI_QUIRKS if [ "$CONFIG_PCI_QUIRKS" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then diff -u --recursive --new-file v2.1.132/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.1.132/linux/arch/i386/defconfig Tue Dec 22 14:16:53 1998 +++ linux/arch/i386/defconfig Sun Dec 27 11:56:34 1998 @@ -15,6 +15,7 @@ CONFIG_M586=y # CONFIG_M686 is not set # CONFIG_MATH_EMULATION is not set +# CONFIG_MTRR is not set CONFIG_SMP=y # @@ -29,6 +30,9 @@ # CONFIG_NET=y CONFIG_PCI=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +CONFIG_PCI_GOANY=y CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y CONFIG_PCI_QUIRKS=y @@ -211,6 +215,7 @@ # CONFIG_NET_RADIO is not set # CONFIG_TR is not set # CONFIG_HOSTESS_SV11 is not set +# CONFIG_COSA is not set # CONFIG_WAN_DRIVERS is not set # CONFIG_LAPBETHER is not set # CONFIG_X25_ASY is not set @@ -242,6 +247,10 @@ CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 CONFIG_MOUSE=y + +# +# Mice +# # CONFIG_ATIXL_BUSMOUSE is not set # CONFIG_BUSMOUSE is not set # CONFIG_MS_BUSMOUSE is not set @@ -250,9 +259,17 @@ # CONFIG_PC110_PAD is not set # CONFIG_QIC02_TAPE is not set # CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set # CONFIG_RTC is not set + +# +# Video For Linux +# # CONFIG_VIDEO_DEV is not set -# CONFIG_NVRAM is not set + +# +# Joystick support +# # CONFIG_JOYSTICK is not set # @@ -264,36 +281,44 @@ # Filesystems # # CONFIG_QUOTA is not set -# CONFIG_MINIX_FS is not set -CONFIG_EXT2_FS=y -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y +CONFIG_DEVPTS_FS=y +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set 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 # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_AUTOFS_FS=y -# CONFIG_UFS_FS is not set + +# +# Partition Types +# # CONFIG_BSD_DISKLABEL is not set +# CONFIG_MAC_PARTITION is not set # CONFIG_SMD_DISKLABEL is not set # CONFIG_SOLARIS_X86_PARTITION is not set -CONFIG_DEVPTS_FS=y -# CONFIG_MAC_PARTITION is not set # CONFIG_NLS is not set # diff -u --recursive --new-file v2.1.132/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- v2.1.132/linux/arch/i386/kernel/entry.S Tue Dec 22 14:16:53 1998 +++ linux/arch/i386/kernel/entry.S Sun Dec 27 22:45:13 1998 @@ -153,10 +153,10 @@ ALIGN .globl ret_from_fork ret_from_fork: - GET_CURRENT(%ebx) #ifdef __SMP__ - lock ; btrl $0, SYMBOL_NAME(scheduler_lock) + call SYMBOL_NAME(schedule_tail) #endif /* __SMP__ */ + GET_CURRENT(%ebx) jmp ret_from_sys_call /* diff -u --recursive --new-file v2.1.132/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.1.132/linux/arch/i386/kernel/i386_ksyms.c Fri Nov 27 13:09:22 1998 +++ linux/arch/i386/kernel/i386_ksyms.c Sun Dec 27 22:45:13 1998 @@ -83,7 +83,6 @@ EXPORT_SYMBOL(__global_sti); EXPORT_SYMBOL(__global_save_flags); EXPORT_SYMBOL(__global_restore_flags); -EXPORT_SYMBOL(smp_message_pass); EXPORT_SYMBOL(mtrr_hook); #endif diff -u --recursive --new-file v2.1.132/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c --- v2.1.132/linux/arch/i386/kernel/io_apic.c Tue Dec 22 14:16:53 1998 +++ linux/arch/i386/kernel/io_apic.c Mon Dec 28 10:52:01 1998 @@ -682,7 +682,8 @@ printk(".... register #01: %08X\n", *(int *)®_01); printk("....... : max redirection entries: %04X\n", reg_01.entries); if ( (reg_01.entries != 0x0f) && /* ISA-only Neptune boards */ - (reg_01.entries != 0x17) /* ISA+PCI boards */ + (reg_01.entries != 0x17) && /* ISA+PCI boards */ + (reg_01.entries != 0x3F) /* Xeon boards */ ) UNEXPECTED_IO_APIC(); if (reg_01.entries == 0x0f) @@ -690,7 +691,8 @@ printk("....... : IO APIC version: %04X\n", reg_01.version); if ( (reg_01.version != 0x10) && /* oldest IO-APICs */ - (reg_01.version != 0x11) /* my IO-APIC */ + (reg_01.version != 0x11) && /* Pentium/Pro IO-APICs */ + (reg_01.version != 0x13) /* Xeon IO-APICs */ ) UNEXPECTED_IO_APIC(); if (reg_01.__reserved_1 || reg_01.__reserved_2) @@ -953,7 +955,7 @@ if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { desc->status = status | IRQ_REPLAY; - send_IPI(APIC_DEST_SELF, IO_APIC_VECTOR(irq)); + send_IPI_self(IO_APIC_VECTOR(irq)); } } diff -u --recursive --new-file v2.1.132/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.1.132/linux/arch/i386/kernel/irq.c Tue Dec 22 14:16:53 1998 +++ linux/arch/i386/kernel/irq.c Sun Dec 27 22:45:13 1998 @@ -189,7 +189,7 @@ /* * The following vectors are part of the Linux architecture, there * is no hardware IRQ pin equivalent for them, they are triggered - * through the ICC by us (IPIs), via smp_message_pass(): + * through the ICC by us (IPIs) */ BUILD_SMP_INTERRUPT(reschedule_interrupt) BUILD_SMP_INTERRUPT(invalidate_interrupt) @@ -297,7 +297,7 @@ } p += sprintf(p, "NMI: %10u\n", atomic_read(&nmi_counter)); #ifdef __SMP__ - p += sprintf(p, "IPI: %10lu\n", ipi_count); + p += sprintf(p, "ERR: %10lu\n", ipi_count); #endif return p - buf; } @@ -709,7 +709,7 @@ spin_lock_irqsave(&irq_controller_lock, flags); switch (irq_desc[irq].depth) { case 1: - irq_desc[irq].status &= ~IRQ_DISABLED; + irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS); irq_desc[irq].handler->enable(irq); /* fall throught */ default: @@ -989,22 +989,22 @@ */ /* IPI for rescheduling */ - set_intr_gate(0x30, reschedule_interrupt); + set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); /* IPI for invalidation */ - set_intr_gate(0x31, invalidate_interrupt); + set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); /* IPI for CPU halt */ - set_intr_gate(0x40, stop_cpu_interrupt); + set_intr_gate(STOP_CPU_VECTOR, stop_cpu_interrupt); /* self generated IPI for local APIC timer */ - set_intr_gate(0x41, apic_timer_interrupt); + set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); /* IPI for MTRR control */ - set_intr_gate(0x50, mtrr_interrupt); + set_intr_gate(MTRR_CHANGE_VECTOR, mtrr_interrupt); /* IPI vector for APIC spurious interrupts */ - set_intr_gate(0xff, spurious_interrupt); + set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); #endif request_region(0x20,0x20,"pic1"); request_region(0xa0,0x20,"pic2"); diff -u --recursive --new-file v2.1.132/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h --- v2.1.132/linux/arch/i386/kernel/irq.h Tue Dec 22 14:16:54 1998 +++ linux/arch/i386/kernel/irq.h Mon Dec 28 14:10:43 1998 @@ -40,7 +40,28 @@ unsigned int depth; /* Disable depth for nested irq disables */ } irq_desc_t; -#define IRQ0_TRAP_VECTOR 0x51 +/* + * Special IRQ vectors used by the SMP architecture: + * + * (some of the following vectors are 'rare', they might be merged + * into a single vector to save vector space. TLB, reschedule and + * local APIC vectors are performance-critical.) + */ +#define RESCHEDULE_VECTOR 0x30 +#define INVALIDATE_TLB_VECTOR 0x31 +#define STOP_CPU_VECTOR 0x40 +#define LOCAL_TIMER_VECTOR 0x41 +#define MTRR_CHANGE_VECTOR 0x50 + +/* + * First vector available to drivers: (vectors 0x51-0xfe) + */ +#define IRQ0_TRAP_VECTOR 0x51 + +/* + * This IRQ should never happen, but we print a message nevertheless. + */ +#define SPURIOUS_APIC_VECTOR 0xff extern irq_desc_t irq_desc[NR_IRQS]; extern int irq_vector[NR_IRQS]; @@ -56,17 +77,18 @@ * Interrupt entry/exit code at both C and assembly level */ -void mask_irq(unsigned int irq); -void unmask_irq(unsigned int irq); -void disable_8259A_irq(unsigned int irq); -int i8259A_irq_pending(unsigned int irq); -void ack_APIC_irq(void); -void setup_IO_APIC(void); -int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); -void make_8259A_irq(unsigned int irq); -void send_IPI(int dest, int vector); -void init_pic_mode(void); -void print_IO_APIC(void); +extern void mask_irq(unsigned int irq); +extern void unmask_irq(unsigned int irq); +extern void disable_8259A_irq(unsigned int irq); +extern int i8259A_irq_pending(unsigned int irq); +extern void ack_APIC_irq(void); +extern void setup_IO_APIC(void); +extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); +extern void make_8259A_irq(unsigned int irq); +extern void FASTCALL(send_IPI_self(int vector)); +extern void smp_send_mtrr(void); +extern void init_pic_mode(void); +extern void print_IO_APIC(void); extern unsigned long long io_apic_irqs; diff -u --recursive --new-file v2.1.132/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c --- v2.1.132/linux/arch/i386/kernel/mtrr.c Mon Oct 5 13:13:35 1998 +++ linux/arch/i386/kernel/mtrr.c Sun Dec 27 22:45:13 1998 @@ -164,6 +164,9 @@ #include #include +#include +#include "irq.h" + #define MTRR_VERSION "1.26 (19981001)" #define TRUE 1 @@ -612,10 +615,11 @@ /* Send a message to all other CPUs and wait for them to enter the barrier */ atomic_set (&undone_count, smp_num_cpus - 1); - smp_message_pass (MSG_ALL_BUT_SELF, MSG_MTRR_CHANGE, 0, 0); + smp_send_mtrr(); /* Wait for it to be done */ timeout = jiffies + JIFFIE_TIMEOUT; - while ( (atomic_read (&undone_count) > 0) && (jiffies < timeout) ) + while ( (atomic_read (&undone_count) > 0) && + time_before(jiffies, timeout) ) barrier (); if (atomic_read (&undone_count) > 0) { diff -u --recursive --new-file v2.1.132/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.1.132/linux/arch/i386/kernel/process.c Tue Dec 22 14:16:54 1998 +++ linux/arch/i386/kernel/process.c Sun Dec 27 22:45:13 1998 @@ -140,10 +140,17 @@ current->priority = 0; current->counter = -100; while(1) { - if (current_cpu_data.hlt_works_ok && !hlt_counter && !current->need_resched) + if (current_cpu_data.hlt_works_ok && !hlt_counter && + !current->need_resched) __asm__("hlt"); - schedule(); - check_pgt_cache(); + /* + * although we are an idle CPU, we do not want to + * get into the scheduler unnecessarily. + */ + if (current->need_resched) { + schedule(); + check_pgt_cache(); + } } } diff -u --recursive --new-file v2.1.132/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c --- v2.1.132/linux/arch/i386/kernel/smp.c Tue Dec 22 14:16:54 1998 +++ linux/arch/i386/kernel/smp.c Mon Dec 28 10:52:01 1998 @@ -3,12 +3,14 @@ * hosts. * * (c) 1995 Alan Cox, CymruNET Ltd + * (c) 1998 Ingo Molnar + * * Supported by Caldera http://www.caldera.com. * Much of the core SMP work is based on previous work by Thomas Radke, to * whom a great many thanks are extended. * - * Thanks to Intel for making available several different Pentium and - * Pentium Pro MP machines. + * Thanks to Intel for making available several different Pentium, + * Pentium Pro and Pentium-II/Xeon MP machines. * * This code is released under the GNU public license version 2 or * later. @@ -26,6 +28,7 @@ * Ingo Molnar : Added APIC timers, based on code * from Jose Renau * Alan Cox : Added EBDA scanning + * Ingo Molnar : various cleanups and rewrites */ #include @@ -112,6 +115,12 @@ return b; } +/* + * function prototypes: + */ +static void cache_APIC_registers (void); + + static int smp_b_stepping = 0; /* Set if we find a B stepping CPU */ static int max_cpus = -1; /* Setup configured maximum number of CPUs to activate */ @@ -131,19 +140,13 @@ unsigned char boot_cpu_id = 0; /* Processor that is doing the boot up */ static int smp_activated = 0; /* Tripped once we need to start cross invalidating */ int apic_version[NR_CPUS]; /* APIC version number */ -static volatile int smp_commenced=0; /* Tripped when we start scheduling */ unsigned long apic_retval; /* Just debugging the assembler.. */ -static volatile unsigned char smp_cpu_in_msg[NR_CPUS]; /* True if this processor is sending an IPI */ - volatile unsigned long kernel_counter=0; /* Number of times the processor holds the lock */ volatile unsigned long syscall_count=0; /* Number of times the processor holds the syscall lock */ volatile unsigned long ipi_count; /* Number of IPIs delivered */ -volatile unsigned long smp_proc_in_lock[NR_CPUS] = {0,};/* for computing process time */ -volatile int smp_process_available=0; - const char lk_lockmsg[] = "lock from interrupt context at %p\n"; int mp_bus_id_to_type [MAX_MP_BUSSES] = { -1, }; @@ -245,7 +248,7 @@ if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { - printk("Bad signature [%c%c%c%c].\n", + panic("SMP mptable: bad signature [%c%c%c%c]!\n", mpc->mpc_signature[0], mpc->mpc_signature[1], mpc->mpc_signature[2], @@ -254,7 +257,7 @@ } if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { - printk("Checksum error.\n"); + panic("SMP mptable: checksum error!\n"); return 1; } if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) @@ -629,13 +632,17 @@ * we use to track CPUs as they power up. */ +static atomic_t smp_commenced = ATOMIC_INIT(0); + void __init smp_commence(void) { /* * Lets the callins below out of their loop. */ SMP_PRINTK(("Setting commenced=1, go go go\n")); - smp_commenced=1; + + wmb(); + atomic_set(&smp_commenced,1); } void __init enable_local_APIC(void) @@ -736,8 +743,8 @@ mtrr_init_secondary_cpu (); #endif smp_callin(); - while (!smp_commenced) - barrier(); + while (!atomic_read(&smp_commenced)) + /* nothing */ ; return cpu_idle(NULL); } @@ -760,11 +767,7 @@ /* * We don't actually need to load the full TSS, * basically just the stack pointer and the eip. - * - * Get the scheduler lock, because we're going - * to release it as part of the "reschedule" return. */ - spin_lock(&scheduler_lock); asm volatile( "movl %0,%%esp\n\t" @@ -972,6 +975,27 @@ *((volatile unsigned long *)phys_to_virt(8192)) = 0; } +cycles_t cacheflush_time; +extern unsigned long cpu_hz; + +static void smp_tune_scheduling (void) +{ + /* + * Rough estimation for SMP scheduling, this is the number of + * cycles it takes for a fully memory-limited process to flush + * the SMP-local cache. + * + * (For a P5 this pretty much means we will choose another idle + * CPU almost always at wakeup time (this is due to the small + * L1 cache), on PIIs it's around 50-100 usecs, depending on + * the cache size) + */ + cacheflush_time = cpu_hz/1024*boot_cpu_data.x86_cache_size/5000; + printk("per-CPU timeslice cutoff: %ld.%ld usecs.\n", + (long)cacheflush_time/(cpu_hz/1000000), + ((long)cacheflush_time*100/(cpu_hz/1000000)) % 100); +} + unsigned int prof_multiplier[NR_CPUS]; unsigned int prof_counter[NR_CPUS]; @@ -1004,6 +1028,7 @@ */ smp_store_cpu_info(boot_cpu_id); /* Final full version of the data */ + smp_tune_scheduling(); printk("CPU%d: ", boot_cpu_id); print_cpu_info(&cpu_data[boot_cpu_id]); @@ -1165,6 +1190,7 @@ printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n"); SMP_PRINTK(("Boot done.\n")); + cache_APIC_registers(); /* * Here we can be sure that there is an IO-APIC in the system. Let's * go and set it up: @@ -1175,257 +1201,270 @@ smp_done: } -void send_IPI(int dest, int vector) -{ - unsigned long cfg; - unsigned long flags; - __save_flags(flags); - __cli(); +/* + * the following functions deal with sending IPIs between CPUs. + * + * We use 'broadcast', CPU->CPU IPIs and self-IPIs too. + */ - /* - * prepare target chip field - */ - cfg = apic_read(APIC_ICR2) & 0x00FFFFFF; - apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(dest)); +/* + * Silly serialization to work around CPU bug in P5s. + * We can safely turn it off on a 686. + */ +#if defined(CONFIG_M686) & !defined(SMP_DEBUG) +# define FORCE_APIC_SERIALIZATION 0 +#else +# define FORCE_APIC_SERIALIZATION 1 +#endif - cfg = apic_read(APIC_ICR); - cfg &= ~0xFDFFF; - cfg |= APIC_DEST_FIELD|APIC_DEST_DM_FIXED|vector; - cfg |= dest; - - /* - * Send the IPI. The write to APIC_ICR fires this off. - */ - - apic_write(APIC_ICR, cfg); - __restore_flags(flags); -} +static unsigned int cached_APIC_ICR; +static unsigned int cached_APIC_ICR2; /* - * A non wait message cannot pass data or CPU source info. This current setup - * is only safe because the kernel lock owner is the only person who can send - * a message. + * Caches reserved bits, APIC reads are (mildly) expensive + * and force otherwise unnecessary CPU synchronization. * - * Wrapping this whole block in a spinlock is not the safe answer either. A - * processor may get stuck with IRQs off waiting to send a message and thus - * not replying to the person spinning for a reply. - * - * In the end flush tlb ought to be the NMI and a very short function - * (to avoid the old IDE disk problems), and other messages sent with IRQs - * enabled in a civilised fashion. That will also boost performance. + * (We could cache other APIC registers too, but these are the + * main ones used in RL.) */ +#define slow_ICR (apic_read(APIC_ICR) & ~0xFDFFF) +#define slow_ICR2 (apic_read(APIC_ICR2) & 0x00FFFFFF) -void smp_message_pass(int target, int msg, unsigned long data, int wait) +void cache_APIC_registers (void) { - unsigned long cfg; - unsigned long dest = 0; - unsigned long target_map; - int p=smp_processor_id(); - int irq; - int ct=0; + cached_APIC_ICR = slow_ICR; + cached_APIC_ICR2 = slow_ICR2; + mb(); +} +static inline unsigned int __get_ICR (void) +{ +#if FORCE_APIC_SERIALIZATION /* - * During boot up send no messages + * Wait for the APIC to become ready - this should never occur. It's + * a debugging check really. */ - - if (!smp_activated || !smp_commenced) - return; + int count = 0; + unsigned int cfg; + while (count < 1000) + { + cfg = slow_ICR; + if (!(cfg&(1<<12))) { + if (count) + atomic_add(count, (atomic_t*)&ipi_count); + return cfg; + } + count++; + udelay(10); + } + printk("CPU #%d: previous IPI still not cleared after 10mS\n", + smp_processor_id()); + return cfg; +#else + return cached_APIC_ICR; +#endif +} - /* - * Skip the reschedule if we are waiting to clear a - * message at this time. The reschedule cannot wait - * but is not critical. - */ +static inline unsigned int __get_ICR2 (void) +{ +#if FORCE_APIC_SERIALIZATION + return slow_ICR2; +#else + return cached_APIC_ICR2; +#endif +} - switch (msg) { - case MSG_RESCHEDULE: - irq = 0x30; - if (smp_cpu_in_msg[p]) - return; - break; +static inline int __prepare_ICR (unsigned int shortcut, int vector) +{ + unsigned int cfg; - case MSG_INVALIDATE_TLB: - /* make this a NMI some day */ - irq = 0x31; - break; + cfg = __get_ICR(); + cfg |= APIC_DEST_FIELD|APIC_DEST_DM_FIXED|shortcut|vector; - case MSG_STOP_CPU: - irq = 0x40; - break; + return cfg; +} - case MSG_MTRR_CHANGE: - irq = 0x50; - break; +static inline int __prepare_ICR2 (unsigned int dest) +{ + unsigned int cfg; - default: - printk("Unknown SMP message %d\n", msg); - return; - } + cfg = __get_ICR2(); + cfg |= SET_APIC_DEST_FIELD(dest); - /* - * Sanity check we don't re-enter this across CPUs. Only the kernel - * lock holder may send messages. For a STOP_CPU we are bringing the - * entire box to the fastest halt we can. A reschedule carries - * no data and can occur during a flush. Guess what panic - * I got to notice this bug. - */ - - /* - * We are busy. - */ - - smp_cpu_in_msg[p]++; + return cfg; +} -/* printk("SMP message pass #%d to %d of %d\n", - p, msg, target);*/ +static inline void __send_IPI_shortcut(unsigned int shortcut, int vector) +{ + unsigned int cfg; +/* + * Subtle. In the case of the 'never do double writes' workaround we + * have to lock out interrupts to be safe. Otherwise it's just one + * single atomic write to the APIC, no need for cli/sti. + */ +#if FORCE_APIC_SERIALIZATION + unsigned long flags; - /* - * Wait for the APIC to become ready - this should never occur. It's - * a debugging check really. - */ - - while (ct<1000) - { - cfg=apic_read(APIC_ICR); - if (!(cfg&(1<<12))) - break; - ct++; - udelay(10); - } + __save_flags(flags); + __cli(); +#endif /* - * Just pray... there is nothing more we can do + * No need to touch the target chip field */ - - if (ct==1000) - printk("CPU #%d: previous IPI still not cleared after 10mS\n", p); + + cfg = __prepare_ICR(shortcut, vector); /* - * Set the target requirement + * Send the IPI. The write to APIC_ICR fires this off. */ - - if (target==MSG_ALL_BUT_SELF) - { - dest=APIC_DEST_ALLBUT; - target_map=cpu_present_map; - cpu_callin_map[0]=(1<). * 1998-12-16 Andrea Arcangeli * Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy - * because was not accounting lost_ticks. I also removed some ugly - * not needed global cli() and where needed I used a disable_irq(0). + * because was not accounting lost_ticks. + * 1998-12-24 Copyright (C) 1998 Andrea Arcangeli + * Fixed a xtime SMP race (we need the xtime_lock rw spinlock to + * serialize accesses to xtime/lost_ticks). */ /* What about the "updated NTP code" stuff in 2.0 time.c? It's not in @@ -82,7 +84,9 @@ */ static unsigned long fast_gettimeoffset_quotient=0; -static unsigned long do_fast_gettimeoffset(void) +extern rwlock_t xtime_lock; + +static inline unsigned long do_fast_gettimeoffset(void) { register unsigned long eax asm("ax"); register unsigned long edx asm("dx"); @@ -92,7 +96,6 @@ :"=a" (eax), "=d" (edx)); /* .. relative to previous jiffy (32 bits is enough) */ - edx = 0; eax -= last_tsc_low; /* tsc_low delta */ /* @@ -106,13 +109,20 @@ __asm__("mull %2" :"=a" (eax), "=d" (edx) - :"r" (fast_gettimeoffset_quotient), - "0" (eax), "1" (edx)); + :"g" (fast_gettimeoffset_quotient), + "0" (eax)); /* our adjusted time offset in microseconds */ - return edx + delay_at_last_interrupt; + return delay_at_last_interrupt + edx; } +#define TICK_SIZE tick + +/* + * Older CPU's don't have the rdtsc instruction.. + */ +#if CPU < 586 + /* This function must be called with interrupts disabled * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs * @@ -145,8 +155,6 @@ * comp.protocols.time.ntp! */ -#define TICK_SIZE tick - static unsigned long do_slow_gettimeoffset(void) { int count; @@ -228,6 +236,12 @@ static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset; +#else + +#define do_gettimeoffset() do_fast_gettimeoffset() + +#endif + /* * This version of gettimeofday has microsecond resolution * and better than microsecond precision on fast x86 machines with TSC. @@ -236,22 +250,31 @@ { extern volatile unsigned long lost_ticks; unsigned long flags; + unsigned long usec, sec; - save_flags(flags); cli(); - *tv = xtime; - tv->tv_usec += do_gettimeoffset(); - if (lost_ticks) - tv->tv_usec += lost_ticks * (1000000/HZ); - restore_flags(flags); - while (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; + read_lock_irqsave(&xtime_lock, flags); + usec = do_gettimeoffset(); + { + unsigned long lost = lost_ticks; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += xtime.tv_usec; + read_unlock_irqrestore(&xtime_lock, flags); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; } + + tv->tv_sec = sec; + tv->tv_usec = usec; } void do_settimeofday(struct timeval *tv) { - cli(); + write_lock_irq(&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. @@ -269,7 +292,7 @@ time_state = TIME_BAD; time_maxerror = MAXPHASE; time_esterror = MAXPHASE; - sti(); + write_unlock_irq(&xtime_lock); } /* @@ -344,7 +367,7 @@ * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { do_timer(regs); /* @@ -373,13 +396,6 @@ else last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ } -#if 0 - /* As we return to user mode fire off the other CPU schedulers.. this is - basically because we don't yet share IRQ's around. This message is - rigged to be safe on the 386 - basically it's a hack, so don't look - closely for now.. */ - smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); -#endif #ifdef CONFIG_MCA if( MCA_bus ) { @@ -398,37 +414,56 @@ #endif } +static int use_tsc = 0; + /* * This is the same as the above, except we _also_ save the current * 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) +static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int count; - /* 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 need interrupts disabled locally. - */ - /* - * Interrupts are just disabled locally since the timer irq has the - * SA_INTERRUPT flag set. -arca + * Here we are in the timer irq handler. We just have irqs locally + * disabled but we don't know if the timer_bh is running on the other + * CPU. We need to avoid to SMP race with it. NOTE: we don' t need + * the irq version of write_lock because as just said we have irq + * locally disabled. -arca */ + write_lock(&xtime_lock); + + if (use_tsc) + { + /* + * 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 need interrupts + * disabled locally. + */ + + /* + * Interrupts are just disabled locally since the timer irq + * has the SA_INTERRUPT flag set. -arca + */ - /* read Pentium cycle counter */ - __asm__("rdtsc" : "=a" (last_tsc_low) : : "edx"); + /* read Pentium cycle counter */ + __asm__("rdtsc" : "=a" (last_tsc_low) : : "edx"); - outb_p(0x00, 0x43); /* latch the count ASAP */ + outb_p(0x00, 0x43); /* latch the count ASAP */ - count = inb_p(0x40); /* read the latched count */ - count |= inb(0x40) << 8; + 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; + count = ((LATCH-1) - count) * TICK_SIZE; + delay_at_last_interrupt = (count + LATCH/2) / LATCH; + } - timer_interrupt(irq, NULL, regs); + do_timer_interrupt(irq, NULL, regs); + + write_unlock(&xtime_lock); + } /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. @@ -599,9 +634,11 @@ * smart. See arch/i386/kernel/apm.c. */ if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) { +#ifndef do_gettimeoffset do_gettimeoffset = do_fast_gettimeoffset; +#endif do_get_fast_time = do_gettimeofday; - irq0.handler = pentium_timer_interrupt; + use_tsc = 1; fast_gettimeoffset_quotient = calibrate_tsc(); /* report CPU clock rate in Hz. diff -u --recursive --new-file v2.1.132/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- v2.1.132/linux/arch/i386/kernel/traps.c Thu Nov 12 16:21:18 1998 +++ linux/arch/i386/kernel/traps.c Sun Dec 27 10:32:09 1998 @@ -499,15 +499,18 @@ } #define _set_gate(gate_addr,type,dpl,addr) \ -__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ - "movw %2,%%dx\n\t" \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ + "movw %4,%%dx\n\t" \ "movl %%eax,%0\n\t" \ "movl %%edx,%1" \ :"=m" (*((long *) (gate_addr))), \ - "=m" (*(1+(long *) (gate_addr))) \ + "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ - "d" ((char *) (addr)),"a" (__KERNEL_CS << 16) \ - :"ax","dx") + "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \ +} while (0) + /* * This needs to use 'idt_table' rather than 'idt', and diff -u --recursive --new-file v2.1.132/linux/arch/i386/lib/Makefile linux/arch/i386/lib/Makefile --- v2.1.132/linux/arch/i386/lib/Makefile Tue Jul 28 14:21:07 1998 +++ linux/arch/i386/lib/Makefile Sun Dec 27 10:33:13 1998 @@ -6,6 +6,7 @@ $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o L_TARGET = lib.a -L_OBJS = checksum.o semaphore.o delay.o usercopy.o getuser.o putuser.o +L_OBJS = checksum.o old-checksum.o semaphore.o delay.o \ + usercopy.o getuser.o putuser.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.132/linux/arch/i386/lib/checksum.S linux/arch/i386/lib/checksum.S --- v2.1.132/linux/arch/i386/lib/checksum.S Wed Dec 31 16:00:00 1969 +++ linux/arch/i386/lib/checksum.S Sun Dec 27 10:32:09 1998 @@ -0,0 +1,450 @@ +/* + * 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. + * + * IP/TCP/UDP checksumming routines + * + * Authors: Jorge Cwik, + * Arnt Gulbrandsen, + * Tom May, + * Pentium Pro/II routines: + * Alexander Kjeldaas + * Finn Arne Gangstad + * Lots of code moved from tcp.c and ip.c; see those files + * for more names. + * + * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception + * handling. + * Andi Kleen, add zeroing on error + * converted to pure assembler + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include + +/* + * computes a partial checksum, e.g. for TCP/UDP fragments + */ + +/* +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) + */ + +.text +.align 4 +.globl csum_partial + +#if CPU!=686 + + /* + * Experiments with Ethernet and SLIP connections show that buff + * is aligned on either a 2-byte or 4-byte boundary. We get at + * least a twofold speedup on 486 and Pentium if it is 4-byte aligned. + * Fortunately, it is easy to convert 2-byte alignment to 4-byte + * alignment for the unrolled loop. + */ +csum_partial: + pushl %esi + pushl %ebx + movl 20(%esp),%eax # Function arg: unsigned int sum + movl 16(%esp),%ecx # Function arg: int len + movl 12(%esp),%esi # Function arg: unsigned char *buff + testl $2, %esi # Check alignment. + jz 2f # Jump if alignment is ok. + subl $2, %ecx # Alignment uses up two bytes. + jae 1f # Jump if we had at least two bytes. + addl $2, %ecx # ecx was < 2. Deal with it. + jmp 4f +1: movw (%esi), %bx + addl $2, %esi + addw %bx, %ax + adcl $0, %eax +2: + movl %ecx, %edx + shrl $5, %ecx + jz 2f + testl %esi, %esi +1: movl (%esi), %ebx + adcl %ebx, %eax + movl 4(%esi), %ebx + adcl %ebx, %eax + movl 8(%esi), %ebx + adcl %ebx, %eax + movl 12(%esi), %ebx + adcl %ebx, %eax + movl 16(%esi), %ebx + adcl %ebx, %eax + movl 20(%esi), %ebx + adcl %ebx, %eax + movl 24(%esi), %ebx + adcl %ebx, %eax + movl 28(%esi), %ebx + adcl %ebx, %eax + lea 32(%esi), %esi + dec %ecx + jne 1b + adcl $0, %eax +2: movl %edx, %ecx + andl $0x1c, %edx + je 4f + shrl $2, %edx # This clears CF +3: adcl (%esi), %eax + lea 4(%esi), %esi + dec %edx + jne 3b + adcl $0, %eax +4: andl $3, %ecx + jz 7f + cmpl $2, %ecx + jb 5f + movw (%esi),%cx + leal 2(%esi),%esi + je 6f + shll $16,%ecx +5: movb (%esi),%cl +6: addl %ecx,%eax + adcl $0, %eax +7: + popl %ebx + popl %esi + ret + +#else /* CPU==686 */ + +csum_partial: + movl 12(%esp),%eax # Function arg: unsigned int sum + movl 8(%esp),%ecx # Function arg: int len + movl 4(%esp),%esi # Function arg: const unsigned char *buf + + testl $2, %esi + jnz 30f +10: + movl %ecx, %edx + movl %ecx, %ebx + andl $0x7c, %ebx + shrl $7, %ecx + addl %ebx,%esi + shrl $2, %ebx + negl %ebx + lea 45f(%ebx,%ebx,2), %ebx + testl %esi, %esi + jmp *%ebx + + # Handle 2-byte-aligned regions +20: addw (%esi), %ax + lea 2(%esi), %esi + adcl $0, %eax + jmp 10b + +30: subl $2, %ecx + ja 20b + je 32f + movzbl (%esi),%ebx # csumming 1 byte, 2-aligned + addl %ebx, %eax + adcl $0, %eax + jmp 80f +32: + addw (%esi), %ax # csumming 2 bytes, 2-aligned + adcl $0, %eax + jmp 80f + +40: + addl -128(%esi), %eax + adcl -124(%esi), %eax + adcl -120(%esi), %eax + adcl -116(%esi), %eax + adcl -112(%esi), %eax + adcl -108(%esi), %eax + adcl -104(%esi), %eax + adcl -100(%esi), %eax + adcl -96(%esi), %eax + adcl -92(%esi), %eax + adcl -88(%esi), %eax + adcl -84(%esi), %eax + adcl -80(%esi), %eax + adcl -76(%esi), %eax + adcl -72(%esi), %eax + adcl -68(%esi), %eax + adcl -64(%esi), %eax + adcl -60(%esi), %eax + adcl -56(%esi), %eax + adcl -52(%esi), %eax + adcl -48(%esi), %eax + adcl -44(%esi), %eax + adcl -40(%esi), %eax + adcl -36(%esi), %eax + adcl -32(%esi), %eax + adcl -28(%esi), %eax + adcl -24(%esi), %eax + adcl -20(%esi), %eax + adcl -16(%esi), %eax + adcl -12(%esi), %eax + adcl -8(%esi), %eax + adcl -4(%esi), %eax +45: + lea 128(%esi), %esi + adcl $0, %eax + dec %ecx + jge 40b + movl %edx, %ecx +50: andl $3, %ecx + jz 80f + + # Handle the last 1-3 bytes without jumping + notl %ecx # 1->2, 2->1, 3->0, higher bits are masked + movl $0xffffff,%ebx # by the shll and shrl instructions + shll $3,%ecx + shrl %cl,%ebx + andl -128(%esi),%ebx # esi is 4-aligned so should be ok + addl %ebx,%eax + adcl $0,%eax +80: + ret + +#endif /* CPU==686 */ + +/* +unsigned int csum_partial_copy_generic (const char *src, char *dst, + int len, int sum, int *src_err_ptr, int *dst_err_ptr) + */ + +/* + * Copy from ds while checksumming, otherwise like csum_partial + * + * The macros SRC and DST specify the type of access for the instruction. + * thus we can call a custom exception handler for all access types. + * + * FIXME: could someone double-check whether I haven't mixed up some SRC and + * DST definitions? It's damn hard to trigger all cases. I hope I got + * them all but there's no guarantee. + */ + +#define SRC(y...) \ + 9999: y; \ + .section __ex_table, "a"; \ + .long 9999b, 6001f ; \ + .previous + +#define DST(y...) \ + 9999: y; \ + .section __ex_table, "a"; \ + .long 9999b, 6002f ; \ + .previous + +.align 4 +.globl csum_partial_copy_generic + +#if CPU!=686 + +#define ARGBASE 16 +#define FP 12 + +csum_partial_copy_generic: + subl $4,%esp + pushl %edi + pushl %esi + pushl %ebx + movl ARGBASE+16(%esp),%eax # sum + movl ARGBASE+12(%esp),%ecx # len + movl ARGBASE+4(%esp),%esi # src + movl ARGBASE+8(%esp),%edi # dst + + testl $2, %edi # Check alignment. + jz 2f # Jump if alignment is ok. + subl $2, %ecx # Alignment uses up two bytes. + jae 1f # Jump if we had at least two bytes. + addl $2, %ecx # ecx was < 2. Deal with it. + jmp 4f +SRC(1: movw (%esi), %bx ) + addl $2, %esi +DST( movw %bx, (%edi) ) + addl $2, %edi + addw %bx, %ax + adcl $0, %eax +2: + movl %ecx, FP(%esp) + shrl $5, %ecx + jz 2f + testl %esi, %esi +SRC(1: movl (%esi), %ebx ) +SRC( movl 4(%esi), %edx ) + adcl %ebx, %eax +DST( movl %ebx, (%edi) ) + adcl %edx, %eax +DST( movl %edx, 4(%edi) ) + +SRC( movl 8(%esi), %ebx ) +SRC( movl 12(%esi), %edx ) + adcl %ebx, %eax +DST( movl %ebx, 8(%edi) ) + adcl %edx, %eax +DST( movl %edx, 12(%edi) ) + +SRC( movl 16(%esi), %ebx ) +SRC( movl 20(%esi), %edx ) + adcl %ebx, %eax +DST( movl %ebx, 16(%edi) ) + adcl %edx, %eax +DST( movl %edx, 20(%edi) ) + +SRC( movl 24(%esi), %ebx ) +SRC( movl 28(%esi), %edx ) + adcl %ebx, %eax +DST( movl %ebx, 24(%edi) ) + adcl %edx, %eax +DST( movl %edx, 28(%edi) ) + +SRC( lea 32(%esi), %esi ) +DST( lea 32(%edi), %edi ) + dec %ecx + jne 1b + adcl $0, %eax +2: movl FP(%esp), %edx + movl %edx, %ecx + andl $0x1c, %edx + je 4f + shrl $2, %edx # This clears CF +SRC(3: movl (%esi), %ebx ) + adcl %ebx, %eax +DST( movl %ebx, (%edi) ) +SRC( lea 4(%esi), %esi ) +DST( lea 4(%edi), %edi ) + dec %edx + jne 3b + adcl $0, %eax +4: andl $3, %ecx + jz 7f + cmpl $2, %ecx + jb 5f +SRC( movw (%esi), %cx ) +SRC( leal 2(%esi), %esi ) +DST( movw %cx, (%edi) ) +DST( leal 2(%edi), %edi ) + je 6f + shll $16,%ecx +SRC(5: movb (%esi), %cl ) +DST( movb %cl, (%edi) ) +6: addl %ecx, %eax + adcl $0, %eax +7: +5000: + +# Exception handler: +.section .fixup, "ax" + +6000: + + movl $-EFAULT, (%ebx) + + # zero the complete destination - computing the rest + # is too much work + movl ARGBASE+8(%esp), %edi # dst + movl ARGBASE+12(%esp), %ecx # len + xorl %eax,%eax + rep ; stosb + + jmp 5000b + +6001: + movl ARGBASE+20(%esp), %ebx # src_err_ptr + jmp 6000b + +6002: + movl ARGBASE+24(%esp), %ebx # dst_err_ptr + jmp 6000b + +.previous + + popl %ebx + popl %esi + popl %edi + popl %ecx # equivalent to addl $4,%esp + ret + +#else + +/* Version for PentiumII/PPro */ + +#define ROUND1(x) \ + SRC(movl x(%esi), %ebx ) ; \ + addl %ebx, %eax\n ; \ + DST(movl %ebx, x(%edi) ) ; + +#define ROUND(x) \ + SRC(movl x(%esi), %ebx ) ; \ + adcl %ebx, %eax ; \ + DST(movl %ebx, x(%edi) ) ; + +#define ARGBASE 12 + +csum_partial_copy_generic: + pushl %ebx + pushl %edi + pushl %esi + movl ARGBASE+4(%esp),%esi #src + movl ARGBASE+8(%esp),%edi #dst + movl ARGBASE+12(%esp),%ecx #len + movl ARGBASE+16(%esp),%eax #sum + movl %ecx, %edx + movl %ecx, %ebx + shrl $6, %ecx + andl $0x3c, %ebx + negl %ebx + subl %ebx, %esi + subl %ebx, %edi + lea 3f(%ebx,%ebx), %ebx + testl %esi, %esi + jmp *%ebx +1: addl $64,%esi + addl $64,%edi + ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52) + ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36) + ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20) + ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4) +3: adcl $0,%eax + dec %ecx + jge 1b +4: andl $3, %edx + jz 7f + cmpl $2, %edx + jb 5f +SRC( movw (%esi), %dx ) + leal 2(%esi), %esi +DST( movw %dx, (%edi) ) + leal 2(%edi), %edi + je 6f + shll $16,%edx +5: +SRC( movb (%esi), %dl ) +DST( movb %dl, (%edi) ) +6: addl %edx, %eax + adcl $0, %eax +7: +.section .fixup, "ax" +6000: movl $-EFAULT, (%ebx) + # zero the complete destination (computing the rest is too much work) + movl ARGBASE+8(%esp),%edi # dst + movl ARGBASE+12(%esp),%ecx # len + xorl %eax,%eax + rep; stosb + jmp 7b +6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr + jmp 6000b +6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr + jmp 6000b +.previous + + popl %esi + popl %edi + popl %ebx + ret + +#undef ROUND +#undef ROUND1 + +#endif /* CPU==i686 */ diff -u --recursive --new-file v2.1.132/linux/arch/i386/lib/checksum.c linux/arch/i386/lib/checksum.c --- v2.1.132/linux/arch/i386/lib/checksum.c Thu Sep 17 17:53:34 1998 +++ linux/arch/i386/lib/checksum.c Wed Dec 31 16:00:00 1969 @@ -1,459 +0,0 @@ -/* - * 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. - * - * IP/TCP/UDP checksumming routines - * - * Authors: Jorge Cwik, - * Arnt Gulbrandsen, - * Tom May, - * Pentium Pro/II routines: - * Alexander Kjeldaas - * Finn Arne Gangstad - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - * - * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception - * handling. - * Andi Kleen, add zeroing on error, fix constraints. - * - * To fix: - * Convert to pure asm, because this file is too hard - * for gcc's register allocator and it is not clear if the - * contraints are correct. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include - -/* - * computes a partial checksum, e.g. for TCP/UDP fragments - */ - -#if CPU!=686 - -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) { - /* - * Experiments with Ethernet and SLIP connections show that buff - * is aligned on either a 2-byte or 4-byte boundary. We get at - * least a twofold speedup on 486 and Pentium if it is 4-byte aligned. - * Fortunately, it is easy to convert 2-byte alignment to 4-byte - * alignment for the unrolled loop. - */ - __asm__(" - testl $2, %%esi # Check alignment. - jz 2f # Jump if alignment is ok. - subl $2, %%ecx # Alignment uses up two bytes. - jae 1f # Jump if we had at least two bytes. - addl $2, %%ecx # ecx was < 2. Deal with it. - jmp 4f -1: movw (%%esi), %%bx - addl $2, %%esi - addw %%bx, %%ax - adcl $0, %%eax -2: - movl %%ecx, %%edx - shrl $5, %%ecx - jz 2f - testl %%esi, %%esi -1: movl (%%esi), %%ebx - adcl %%ebx, %%eax - movl 4(%%esi), %%ebx - adcl %%ebx, %%eax - movl 8(%%esi), %%ebx - adcl %%ebx, %%eax - movl 12(%%esi), %%ebx - adcl %%ebx, %%eax - movl 16(%%esi), %%ebx - adcl %%ebx, %%eax - movl 20(%%esi), %%ebx - adcl %%ebx, %%eax - movl 24(%%esi), %%ebx - adcl %%ebx, %%eax - movl 28(%%esi), %%ebx - adcl %%ebx, %%eax - lea 32(%%esi), %%esi - dec %%ecx - jne 1b - adcl $0, %%eax -2: movl %%edx, %%ecx - andl $0x1c, %%edx - je 4f - shrl $2, %%edx # This clears CF -3: adcl (%%esi), %%eax - lea 4(%%esi), %%esi - dec %%edx - jne 3b - adcl $0, %%eax -4: andl $3, %%ecx - jz 7f - cmpl $2, %%ecx - jb 5f - movw (%%esi),%%cx - leal 2(%%esi),%%esi - je 6f - shll $16,%%ecx -5: movb (%%esi),%%cl -6: addl %%ecx,%%eax - adcl $0, %%eax -7: " - : "=a"(sum) - : "0"(sum), "c"(len), "S"(buff) - : "bx", "dx", "si", "cx", "memory"); - return(sum); -} - -#else /* 686 */ - -unsigned int csum_partial(const unsigned char * buf, int len, unsigned int sum) { - __asm__ (" - testl $2, %%esi - jnz 30f -10: - movl %%ecx, %%edx - movl %%ecx, %%ebx - andl $0x7c, %%ebx - shrl $7, %%ecx - addl %%ebx,%%esi - shrl $2, %%ebx - negl %%ebx - lea 45f(%%ebx,%%ebx,2), %%ebx - testl %%esi, %%esi - jmp *%%ebx - - # Handle 2-byte-aligned regions -20: addw (%%esi), %%ax - lea 2(%%esi), %%esi - adcl $0, %%eax - jmp 10b - -30: subl $2, %%ecx - ja 20b - je 32f - movzbl (%%esi),%%ebx # csumming 1 byte, 2-aligned - addl %%ebx, %%eax - adcl $0, %%eax - jmp 80f -32: - addw (%%esi), %%ax # csumming 2 bytes, 2-aligned - adcl $0, %%eax - jmp 80f - -40: - addl -128(%%esi), %%eax - adcl -124(%%esi), %%eax - adcl -120(%%esi), %%eax - adcl -116(%%esi), %%eax - adcl -112(%%esi), %%eax - adcl -108(%%esi), %%eax - adcl -104(%%esi), %%eax - adcl -100(%%esi), %%eax - adcl -96(%%esi), %%eax - adcl -92(%%esi), %%eax - adcl -88(%%esi), %%eax - adcl -84(%%esi), %%eax - adcl -80(%%esi), %%eax - adcl -76(%%esi), %%eax - adcl -72(%%esi), %%eax - adcl -68(%%esi), %%eax - adcl -64(%%esi), %%eax - adcl -60(%%esi), %%eax - adcl -56(%%esi), %%eax - adcl -52(%%esi), %%eax - adcl -48(%%esi), %%eax - adcl -44(%%esi), %%eax - adcl -40(%%esi), %%eax - adcl -36(%%esi), %%eax - adcl -32(%%esi), %%eax - adcl -28(%%esi), %%eax - adcl -24(%%esi), %%eax - adcl -20(%%esi), %%eax - adcl -16(%%esi), %%eax - adcl -12(%%esi), %%eax - adcl -8(%%esi), %%eax - adcl -4(%%esi), %%eax -45: - lea 128(%%esi), %%esi - adcl $0, %%eax - dec %%ecx - jge 40b - movl %%edx, %%ecx -50: andl $3, %%ecx - jz 80f - - # Handle the last 1-3 bytes without jumping - notl %%ecx # 1->2, 2->1, 3->0, higher bits are masked - movl $0xffffff,%%ebx # by the shll and shrl instructions - shll $3,%%ecx - shrl %%cl,%%ebx - andl -128(%%esi),%%ebx # esi is 4-aligned so should be ok - addl %%ebx,%%eax - adcl $0,%%eax -80: " - : "=a"(sum) - : "0"(sum), "c"(len), "S"(buf) - : "bx", "dx", "cx", "si", "memory"); - return(sum); -} - -#endif - -/* - * Copy from ds while checksumming, otherwise like csum_partial - * - * The macros SRC and DST specify the type of access for the instruction. - * thus we can call a custom exception handler for all access types. - * - * FIXME: could someone double-check whether I haven't mixed up some SRC and - * DST definitions? It's damn hard to trigger all cases. I hope I got - * them all but there's no guarantee. - */ - -#define SRC(y...) \ -" 9999: "#y"; \n \ - .section __ex_table, \"a\"; \n \ - .long 9999b, 6001f \n \ - .previous\n" - -#define DST(y...) \ -" 9999: "#y"; \n \ - .section __ex_table, \"a\"; \n \ - .long 9999b, 6002f \n \ - .previous\n" - -#if CPU!=686 - -unsigned int csum_partial_copy_generic (const char *src, char *dst, - int len, int sum, int *src_err_ptr, int *dst_err_ptr) -{ - __u32 tmp_var; - - __asm__ __volatile__ ( " - movl %6,%%edi - testl $2, %%edi # Check alignment. - jz 2f # Jump if alignment is ok. - subl $2, %%ecx # Alignment uses up two bytes. - jae 1f # Jump if we had at least two bytes. - addl $2, %%ecx # ecx was < 2. Deal with it. - jmp 4f -"SRC( 1: movw (%%esi), %%bx )" - addl $2, %%esi -"DST( movw %%bx, (%%edi) )" - addl $2, %%edi - addw %%bx, %%ax - adcl $0, %%eax - 2: - movl %%ecx, %8 - shrl $5, %%ecx - jz 2f - testl %%esi, %%esi -"SRC( 1: movl (%%esi), %%ebx )" -"SRC( movl 4(%%esi), %%edx )" - adcl %%ebx, %%eax -"DST( movl %%ebx, (%%edi) )" - adcl %%edx, %%eax -"DST( movl %%edx, 4(%%edi) )" - -"SRC( movl 8(%%esi), %%ebx )" -"SRC( movl 12(%%esi), %%edx )" - adcl %%ebx, %%eax -"DST( movl %%ebx, 8(%%edi) )" - adcl %%edx, %%eax -"DST( movl %%edx, 12(%%edi) )" - -"SRC( movl 16(%%esi), %%ebx )" -"SRC( movl 20(%%esi), %%edx )" - adcl %%ebx, %%eax -"DST( movl %%ebx, 16(%%edi) )" - adcl %%edx, %%eax -"DST( movl %%edx, 20(%%edi) )" - -"SRC( movl 24(%%esi), %%ebx )" -"SRC( movl 28(%%esi), %%edx )" - adcl %%ebx, %%eax -"DST( movl %%ebx, 24(%%edi) )" - adcl %%edx, %%eax -"DST( movl %%edx, 28(%%edi) )" - -"SRC( lea 32(%%esi), %%esi )" -"DST( lea 32(%%edi), %%edi )" - dec %%ecx - jne 1b - adcl $0, %%eax - 2: movl %8, %%edx - movl %%edx, %%ecx - andl $0x1c, %%edx - je 4f - shrl $2, %%edx # This clears CF -"SRC( 3: movl (%%esi), %%ebx )" - adcl %%ebx, %%eax -"DST( movl %%ebx, (%%edi) )" -"SRC( lea 4(%%esi), %%esi )" -"DST( lea 4(%%edi), %%edi )" - dec %%edx - jne 3b - adcl $0, %%eax - 4: andl $3, %%ecx - jz 7f - cmpl $2, %%ecx - jb 5f -"SRC( movw (%%esi), %%cx )" -"SRC( leal 2(%%esi), %%esi )" -"DST( movw %%cx, (%%edi) )" -"DST( leal 2(%%edi), %%edi )" - je 6f - shll $16,%%ecx -"SRC( 5: movb (%%esi), %%cl )" -"DST( movb %%cl, (%%edi) )" - 6: addl %%ecx, %%eax - adcl $0, %%eax - 7: - -5000: - -# Exception handler: -################################################ - # -.section .fixup, \"ax\" # - # -6000: # - # - movl %7, (%%ebx) # - # -# zero the complete destination - computing the rest -# is too much work - movl %6, %%edi - movl %9, %%ecx - xorl %%eax,%%eax - rep ; stosb - # - jmp 5000b # - # -6001: # - movl %1, %%ebx # - jmp 6000b # - # -6002: # - movl %2, %%ebx # - jmp 6000b # - # -.previous # - # -################################################ - -" - : "=a" (sum) - : "m" (src_err_ptr), "m" (dst_err_ptr), - "0" (sum), "c" (len), "S" (src), "m" (dst), - "i" (-EFAULT), "m"(tmp_var), - "m" (len) - : "bx", "dx", "si", "di", "cx", "memory" ); - - return(sum); -} - -#else /* CPU == 686 */ - -#define ROUND1(x) \ - SRC(movl x(%%esi), %%ebx ) \ - "addl %%ebx, %%eax\n" \ - DST(movl %%ebx, x(%%edi) ) - -#define ROUND(x) \ - SRC(movl x(%%esi), %%ebx ) \ - "adcl %%ebx, %%eax\n" \ - DST(movl %%ebx, x(%%edi) ) - -unsigned int csum_partial_copy_generic (const char *src, char *dst, - int len, int sum, int *src_err_ptr, int *dst_err_ptr) -{ - __asm__ __volatile__ (" - movl %4,%%ecx - movl %%ecx, %%edx - movl %%ecx, %%ebx - shrl $6, %%ecx - andl $0x3c, %%ebx - negl %%ebx - subl %%ebx, %%esi - subl %%ebx, %%edi - lea 3f(%%ebx,%%ebx), %%ebx - testl %%esi, %%esi - jmp *%%ebx -1: addl $64,%%esi - addl $64,%%edi\n" -ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52) -ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36) -ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20) -ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4) -"3: adcl $0,%%eax - dec %%ecx - jge 1b -4: andl $3, %%edx - jz 7f - cmpl $2, %%edx - jb 5f - " SRC(movw (%%esi), %%dx )" - leal 2(%%esi), %%esi - " DST(movw %%dx, (%%edi) )" - leal 2(%%edi), %%edi - je 6f - shll $16,%%edx -5:" SRC(movb (%%esi), %%dl )" - " DST(movb %%dl, (%%edi) )" -6: addl %%edx, %%eax - adcl $0, %%eax -7: -.section .fixup, \"ax\" -6000: movl %7, (%%ebx) -# zero the complete destination (computing the rest is too much work) - movl %8,%%edi - movl %4,%%ecx - xorl %%eax,%%eax - rep ; stosb - jmp 7b -6001: movl %1, %%ebx - jmp 6000b -6002: movl %2, %%ebx - jmp 6000b -.previous - " - : "=a"(sum) - : "m"(src_err_ptr), "m"(dst_err_ptr), - "0"(sum), "m"(len), "S"(src), "D" (dst), - "i" (-EFAULT), - "m" (dst) - : "bx", "cx", "si", "di", "dx", "memory" ); - return(sum); -} - -#undef ROUND -#undef ROUND1 - -#endif - - -#undef SRC -#undef DST - -/* - * FIXME: old compatibility stuff, will be removed soon. - */ - -unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum) -{ - int src_err=0, dst_err=0; - - sum = csum_partial_copy_generic ( src, dst, len, sum, &src_err, &dst_err); - - if (src_err || dst_err) - printk("old csum_partial_copy_fromuser(), tell mingo to convert me.\n"); - - return sum; -} - - diff -u --recursive --new-file v2.1.132/linux/arch/i386/lib/delay.c linux/arch/i386/lib/delay.c --- v2.1.132/linux/arch/i386/lib/delay.c Fri Oct 9 13:27:05 1998 +++ linux/arch/i386/lib/delay.c Sun Dec 27 10:36:38 1998 @@ -19,23 +19,23 @@ void __delay(unsigned long loops) { + int d0; __asm__ __volatile__( "\tjmp 1f\n" ".align 16\n" "1:\tjmp 2f\n" ".align 16\n" "2:\tdecl %0\n\tjns 2b" - :/* no outputs */ - :"a" (loops) - :"ax"); + :"=&a" (d0) + :"0" (loops)); } inline void __const_udelay(unsigned long xloops) { + int d0; __asm__("mull %0" - :"=d" (xloops) - :"a" (xloops),"0" (current_cpu_data.loops_per_sec) - :"ax"); + :"=d" (xloops), "=&a" (d0) + :"1" (xloops),"0" (current_cpu_data.loops_per_sec)); __delay(xloops); } diff -u --recursive --new-file v2.1.132/linux/arch/i386/lib/old-checksum.c linux/arch/i386/lib/old-checksum.c --- v2.1.132/linux/arch/i386/lib/old-checksum.c Wed Dec 31 16:00:00 1969 +++ linux/arch/i386/lib/old-checksum.c Sun Dec 27 10:32:09 1998 @@ -0,0 +1,19 @@ +/* + * FIXME: old compatibility stuff, will be removed soon. + */ + +#include + +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum) +{ + int src_err=0, dst_err=0; + + sum = csum_partial_copy_generic ( src, dst, len, sum, &src_err, &dst_err); + + if (src_err || dst_err) + printk("old csum_partial_copy_fromuser(), tell mingo to convert me.\n"); + + return sum; +} + + diff -u --recursive --new-file v2.1.132/linux/arch/i386/lib/usercopy.c linux/arch/i386/lib/usercopy.c --- v2.1.132/linux/arch/i386/lib/usercopy.c Wed Aug 26 11:37:33 1998 +++ linux/arch/i386/lib/usercopy.c Sun Dec 27 10:36:38 1998 @@ -29,6 +29,8 @@ */ #define __do_strncpy_from_user(dst,src,count,res) \ +do { \ + int __d0, __d1, __d2; \ __asm__ __volatile__( \ " testl %1,%1\n" \ " jz 2f\n" \ @@ -41,16 +43,18 @@ "1: subl %1,%0\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ - "3: movl %2,%0\n" \ + "3: movl %5,%0\n" \ " jmp 2b\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 0b,3b\n" \ ".previous" \ - : "=d"(res), "=c"(count) \ - : "i"(-EFAULT), "0"(count), "1"(count), "S"(src), "D"(dst) \ - : "si", "di", "ax", "memory") + : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \ + "=&D" (__d2) \ + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ + : "memory"); \ +} while (0) long __strncpy_from_user(char *dst, const char *src, long count) @@ -74,14 +78,16 @@ * Zero Userspace */ -#define __do_clear_user(addr,size) \ - __asm__ __volatile__( \ +#define __do_clear_user(addr,size) \ +do { \ + int __d0; \ + __asm__ __volatile__( \ "0: rep; stosl\n" \ - " movl %1,%0\n" \ + " movl %2,%0\n" \ "1: rep; stosb\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ - "3: lea 0(%1,%0,4),%0\n" \ + "3: lea 0(%2,%0,4),%0\n" \ " jmp 2b\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ @@ -89,9 +95,9 @@ " .long 0b,3b\n" \ " .long 1b,2b\n" \ ".previous" \ - : "=&c"(size) \ - : "r"(size & 3), "0"(size / 4), "D"(addr), "a"(0) \ - : "di") + : "=&c"(size), "=&D" (__d0) \ + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \ +} while (0) unsigned long clear_user(void *to, unsigned long n) diff -u --recursive --new-file v2.1.132/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- v2.1.132/linux/arch/i386/mm/init.c Wed Dec 16 10:32:54 1998 +++ linux/arch/i386/mm/init.c Sun Dec 27 10:39:50 1998 @@ -119,24 +119,28 @@ pte_t * __bad_pagetable(void) { extern char empty_bad_page_table[PAGE_SIZE]; + int d0, d1; - __asm__ __volatile__("cld ; rep ; stosl": - :"a" (pte_val(BAD_PAGE)), - "D" ((long) empty_bad_page_table), - "c" (PAGE_SIZE/4) - :"di","cx"); + __asm__ __volatile__("cld ; rep ; stosl" + : "=&D" (d0), "=&c" (d1) + : "a" (pte_val(BAD_PAGE)), + "0" ((long) empty_bad_page_table), + "1" (PAGE_SIZE/4) + : "memory"); return (pte_t *) empty_bad_page_table; } pte_t __bad_page(void) { extern char empty_bad_page[PAGE_SIZE]; + int d0, d1; - __asm__ __volatile__("cld ; rep ; stosl": - :"a" (0), - "D" ((long) empty_bad_page), - "c" (PAGE_SIZE/4) - :"di","cx"); + __asm__ __volatile__("cld ; rep ; stosl" + : "=&D" (d0), "=&c" (d1) + : "a" (0), + "0" ((long) empty_bad_page), + "1" (PAGE_SIZE/4) + : "memory"); return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED)); } @@ -298,7 +302,8 @@ * NOTE! There are Linux loaders that will corrupt the EBDA * area, and as such this kind of SMP config may be less * trustworthy, simply because the SMP table may have been - * stomped on during early boot. + * stomped on during early boot. These loaders are buggy and + * should be fixed. */ address = *(unsigned short *)phys_to_virt(0x40E); address<<=4; diff -u --recursive --new-file v2.1.132/linux/arch/i386/vmlinux.lds linux/arch/i386/vmlinux.lds --- v2.1.132/linux/arch/i386/vmlinux.lds Wed Sep 9 14:51:06 1998 +++ linux/arch/i386/vmlinux.lds Sun Dec 27 22:45:13 1998 @@ -45,8 +45,12 @@ . = ALIGN(4096); __init_end = .; + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + . = ALIGN(4096); .data.page_aligned : { *(.data.idt) } + __bss_start = .; /* BSS */ .bss : { diff -u --recursive --new-file v2.1.132/linux/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c --- v2.1.132/linux/arch/mips/kernel/irq.c Fri Oct 23 22:01:19 1998 +++ linux/arch/mips/kernel/irq.c Wed Dec 23 09:44:40 1998 @@ -287,7 +287,7 @@ } /* wait for spurious interrupts to mask themselves out again */ - for (delay = jiffies + HZ/10; delay > jiffies; ) + for (delay = jiffies + HZ/10; time_before(jiffies, delay); ) /* about 100ms delay */; /* now filter out any obviously spurious interrupts */ diff -u --recursive --new-file v2.1.132/linux/arch/ppc/8xx_io/uart.c linux/arch/ppc/8xx_io/uart.c --- v2.1.132/linux/arch/ppc/8xx_io/uart.c Sun Nov 8 14:02:44 1998 +++ linux/arch/ppc/8xx_io/uart.c Wed Dec 23 09:44:40 1998 @@ -1692,7 +1692,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; bdp = info->tx_cur; } while (bdp->cbd_sc & BD_SC_READY); diff -u --recursive --new-file v2.1.132/linux/arch/ppc/apus_defconfig linux/arch/ppc/apus_defconfig --- v2.1.132/linux/arch/ppc/apus_defconfig Thu Nov 19 09:56:27 1998 +++ linux/arch/ppc/apus_defconfig Wed Dec 23 07:34:11 1998 @@ -14,6 +14,7 @@ # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # diff -u --recursive --new-file v2.1.132/linux/arch/ppc/chrp_defconfig linux/arch/ppc/chrp_defconfig --- v2.1.132/linux/arch/ppc/chrp_defconfig Sun Nov 8 14:02:44 1998 +++ linux/arch/ppc/chrp_defconfig Wed Dec 23 07:34:11 1998 @@ -14,6 +14,7 @@ # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # diff -u --recursive --new-file v2.1.132/linux/arch/ppc/common_defconfig linux/arch/ppc/common_defconfig --- v2.1.132/linux/arch/ppc/common_defconfig Tue Dec 22 14:16:54 1998 +++ linux/arch/ppc/common_defconfig Wed Dec 23 07:34:11 1998 @@ -14,6 +14,7 @@ CONFIG_ALL_PPC=y # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set # # General setup diff -u --recursive --new-file v2.1.132/linux/arch/ppc/config.in linux/arch/ppc/config.in --- v2.1.132/linux/arch/ppc/config.in Thu Nov 19 09:56:27 1998 +++ linux/arch/ppc/config.in Wed Dec 23 07:34:11 1998 @@ -22,6 +22,9 @@ if [ "$CONFIG_ALL_PPC" != "y" ];then define_bool CONFIG_MACH_SPECIFIC y fi + +bool 'Symmetric multi-processing support' CONFIG_SMP + endmenu if [ "$CONFIG_MBX" = "y" ];then diff -u --recursive --new-file v2.1.132/linux/arch/ppc/defconfig linux/arch/ppc/defconfig --- v2.1.132/linux/arch/ppc/defconfig Thu Nov 19 09:56:27 1998 +++ linux/arch/ppc/defconfig Wed Dec 23 07:34:11 1998 @@ -14,6 +14,7 @@ # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # diff -u --recursive --new-file v2.1.132/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile --- v2.1.132/linux/arch/ppc/kernel/Makefile Tue Dec 22 14:16:54 1998 +++ linux/arch/ppc/kernel/Makefile Wed Dec 23 07:34:11 1998 @@ -42,7 +42,7 @@ endif endif -ifdef SMP +ifdef CONFIG_SMP O_OBJS += smp.o endif diff -u --recursive --new-file v2.1.132/linux/arch/ppc/lib/Makefile linux/arch/ppc/lib/Makefile --- v2.1.132/linux/arch/ppc/lib/Makefile Mon Jan 12 15:18:13 1998 +++ linux/arch/ppc/lib/Makefile Wed Dec 23 07:34:11 1998 @@ -8,7 +8,7 @@ O_TARGET = lib.o O_OBJS = checksum.o string.o strcase.o -ifdef SMP +ifdef CONFIG_SMP O_OBJS += locks.o endif diff -u --recursive --new-file v2.1.132/linux/arch/ppc/mbx_defconfig linux/arch/ppc/mbx_defconfig --- v2.1.132/linux/arch/ppc/mbx_defconfig Tue Dec 22 14:16:54 1998 +++ linux/arch/ppc/mbx_defconfig Wed Dec 23 07:34:11 1998 @@ -14,6 +14,7 @@ # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set CONFIG_MBX=y +CONFIG_SMP=n CONFIG_MACH_SPECIFIC=y CONFIG_SERIAL_CONSOLE=y diff -u --recursive --new-file v2.1.132/linux/arch/ppc/pmac_defconfig linux/arch/ppc/pmac_defconfig --- v2.1.132/linux/arch/ppc/pmac_defconfig Thu Nov 19 09:56:27 1998 +++ linux/arch/ppc/pmac_defconfig Wed Dec 23 07:34:11 1998 @@ -14,6 +14,7 @@ # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # diff -u --recursive --new-file v2.1.132/linux/arch/ppc/prep_defconfig linux/arch/ppc/prep_defconfig --- v2.1.132/linux/arch/ppc/prep_defconfig Thu Nov 19 09:56:27 1998 +++ linux/arch/ppc/prep_defconfig Wed Dec 23 07:34:11 1998 @@ -14,6 +14,7 @@ # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # diff -u --recursive --new-file v2.1.132/linux/arch/sparc/ap1000/util.c linux/arch/sparc/ap1000/util.c --- v2.1.132/linux/arch/sparc/ap1000/util.c Sun Jun 7 11:16:28 1998 +++ linux/arch/sparc/ap1000/util.c Wed Dec 23 09:44:40 1998 @@ -393,7 +393,7 @@ unsigned end = jiffies + 20*HZ; /* we are booting from another cell */ printk("waiting for the master cell\n"); - while (jiffies < end) ; + while (time_before(jiffies, end)) ; printk("continuing\n"); } } diff -u --recursive --new-file v2.1.132/linux/drivers/acorn/block/fd1772.c linux/drivers/acorn/block/fd1772.c --- v2.1.132/linux/drivers/acorn/block/fd1772.c Wed Aug 26 11:37:34 1998 +++ linux/drivers/acorn/block/fd1772.c Wed Dec 23 09:44:40 1998 @@ -1090,7 +1090,7 @@ NeedSeek = 0; if ((timer_active & (1 << FLOPPY_TIMER)) && - timer_table[FLOPPY_TIMER].expires < jiffies + 5) + time_after(jiffies + 5, timer_table[FLOPPY_TIMER].expires)) /* If the check for a disk change is done too early after this * last seek command, the WP bit still reads wrong :-(( */ @@ -1424,7 +1424,7 @@ FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_RESTORE | FDC1772CMDADD_H | FDC1772STEP_6); /*printk("fd_test_drive_present: Going into timeout loop\n"); */ - for (ok = 0, timeout = jiffies + 2 * HZ + HZ / 2; jiffies < timeout;) { + for (ok = 0, timeout = jiffies + 2 * HZ + HZ / 2; time_before(jiffies, timeout);) { /* What does this piece of atariism do? - query for an interrupt? */ /* if (!(mfp.par_dt_reg & 0x20)) break; */ diff -u --recursive --new-file v2.1.132/linux/drivers/acorn/net/ether1.c linux/drivers/acorn/net/ether1.c --- v2.1.132/linux/drivers/acorn/net/ether1.c Wed Apr 8 19:36:25 1998 +++ linux/drivers/acorn/net/ether1.c Wed Dec 23 09:44:41 1998 @@ -519,7 +519,7 @@ /* 586 should now unset iscp.busy */ i = jiffies + HZ/2; while (ether1_inw (dev, ISCP_ADDR, iscp_t, iscp_busy, DISABLEIRQS) == 1) { - if (jiffies > i) { + if (time_after(jiffies, i)) { printk (KERN_WARNING "%s: can't initialise 82586: iscp is busy\n", dev->name); return 1; } @@ -529,7 +529,7 @@ i += HZ/10; while (((status = ether1_inw (dev, CFG_ADDR, cfg_t, cfg_status, DISABLEIRQS)) & STAT_COMPLETE) == 0) { - if (jiffies > i) + if (time_after(jiffies, i)) break; } @@ -546,7 +546,7 @@ i += HZ/10; while (((status = ether1_inw (dev, SA_ADDR, sa_t, sa_status, DISABLEIRQS)) & STAT_COMPLETE) == 0) { - if (jiffies > i) + if (time_after(jiffies, i)) break; } @@ -563,7 +563,7 @@ i += HZ/10; while (((status = ether1_inw (dev, MC_ADDR, mc_t, mc_status, DISABLEIRQS)) & STAT_COMPLETE) == 0) { - if (jiffies > i) + if (time_after(jiffies, i)) break; } @@ -580,7 +580,7 @@ i += HZ; while (((status = ether1_inw (dev, TDR_ADDR, tdr_t, tdr_status, DISABLEIRQS)) & STAT_COMPLETE) == 0) { - if (jiffies > i) + if (time_after(jiffies, i)) break; } diff -u --recursive --new-file v2.1.132/linux/drivers/acorn/scsi/acornscsi.c linux/drivers/acorn/scsi/acornscsi.c --- v2.1.132/linux/drivers/acorn/scsi/acornscsi.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/acorn/scsi/acornscsi.c Wed Dec 23 09:44:41 1998 @@ -323,7 +323,7 @@ save_flags (flags); sti (); - while (jiffies < target_jiffies) barrier(); + while (time_before(jiffies, target_jiffies)) barrier(); restore_flags (flags); } diff -u --recursive --new-file v2.1.132/linux/drivers/acorn/scsi/fas216.c linux/drivers/acorn/scsi/fas216.c --- v2.1.132/linux/drivers/acorn/scsi/fas216.c Tue Jul 21 00:15:30 1998 +++ linux/drivers/acorn/scsi/fas216.c Wed Dec 23 09:44:41 1998 @@ -2049,7 +2049,7 @@ save_flags(flags); sti(); - while (jiffies < target_jiffies) barrier(); + while (time_before(jiffies, target_jiffies)) barrier(); restore_flags(flags); diff -u --recursive --new-file v2.1.132/linux/drivers/ap1000/ddv_util.c linux/drivers/ap1000/ddv_util.c --- v2.1.132/linux/drivers/ap1000/ddv_util.c Sun Jan 26 02:07:10 1997 +++ linux/drivers/ap1000/ddv_util.c Wed Dec 23 09:44:41 1998 @@ -92,7 +92,7 @@ return(-1); } for (timeout=jiffies + 10; - (jiffies < timeout) || (OPT_IO(PBUF0) == 0); + time_before(jiffies, timeout) || (OPT_IO(PBUF0) == 0); ) /* wait */ ; if (OPT_IO(PBUF0) == 0) { printk("WARNING: option kernel didn't startup\n"); diff -u --recursive --new-file v2.1.132/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.1.132/linux/drivers/block/genhd.c Thu Nov 19 09:56:28 1998 +++ linux/drivers/block/genhd.c Sun Dec 27 10:44:45 1998 @@ -317,11 +317,50 @@ #endif #ifdef CONFIG_BSD_DISKLABEL +static void check_and_add_bsd_partition(struct gendisk *hd, struct bsd_partition *bsd_p) +{ + struct hd_struct *lin_p; + /* check relative position of partitions. */ + for (lin_p = hd->part + 1; lin_p - hd->part < current_minor; lin_p++) { + /* no relationship -> try again */ + if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset + || lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size) + continue; + /* equal -> no need to add */ + if (lin_p->start_sect == bsd_p->p_offset && + lin_p->nr_sects == bsd_p->p_size) + return; + /* bsd living within dos partition */ + if (lin_p->start_sect <= bsd_p->p_offset && lin_p->start_sect + + lin_p->nr_sects >= bsd_p->p_offset + bsd_p->p_size) { +#ifdef DEBUG_BSD_DISKLABEL + printk("w: %d %ld+%ld,%d+%d", + lin_p - hd->part, + lin_p->start_sect, lin_p->nr_sects, + bsd_p->p_offset, bsd_p->p_size); +#endif + break; + } + /* ouch: bsd and linux overlap. Don't even try for that partition */ +#ifdef DEBUG_BSD_DISKLABEL + printk("???: %d %ld+%ld,%d+%d", + lin_p - hd->part, lin_p->start_sect, lin_p->nr_sects, + bsd_p->p_offset, bsd_p->p_size); +#endif + printk("???"); + return; + } /* if the bsd partition is not currently known to linux, we end + * up here + */ + add_partition(hd, current_minor, bsd_p->p_offset, bsd_p->p_size); + current_minor++; +} /* * Create devices for BSD partitions listed in a disklabel, under a * dos-like partition. See extended_partition() for more information. */ -static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev) +static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev, + int max_partitions) { struct buffer_head *bh; struct bsd_disklabel *l; @@ -337,19 +376,56 @@ return; } - p = &l->d_partitions[0]; - while (p - &l->d_partitions[0] <= BSD_MAXPARTITIONS) { + if (l->d_npartitions < max_partitions) + max_partitions = l->d_npartitions; + for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { if ((current_minor & mask) >= (4 + hd->max_p)) break; - if (p->p_fstype != BSD_FS_UNUSED) { - add_partition(hd, current_minor, p->p_offset, p->p_size); + if (p->p_fstype != BSD_FS_UNUSED) + check_and_add_bsd_partition(hd, p); + } + brelse(bh); + +} +#endif + +#ifdef CONFIG_UNIXWARE_DISKLABEL +/* + * Create devices for Unixware partitions listed in a disklabel, under a + * dos-like partition. See extended_partition() for more information. + */ +static void unixware_partition(struct gendisk *hd, kdev_t dev) +{ + struct buffer_head *bh; + struct unixware_disklabel *l; + struct unixware_slice *p; + int mask = (1 << hd->minor_shift) - 1; + + if (!(bh = bread(dev, 14, get_ptable_blocksize(dev)))) + return; + bh->b_state = 0; + l = (struct unixware_disklabel *) (bh->b_data+512); + if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC || + le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) { + brelse(bh); + return; + } + printk(" vtoc.v_slice[1]; + /* I omit the 0th slice as it is the same as whole disk. */ + while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) { + if ((current_minor & mask) == 0) + break; + + if (p->s_label != UNIXWARE_FS_UNUSED) { + add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p)); current_minor++; } p++; } brelse(bh); - + printk(" >"); } #endif @@ -360,6 +436,11 @@ struct partition *p; unsigned char *data; int mask = (1 << hd->minor_shift) - 1; +#ifdef CONFIG_BSD_DISKLABEL + /* no bsd disklabel as a default */ + kdev_t bsd_kdev = 0; + int bsd_maxpart; +#endif #ifdef CONFIG_BLK_DEV_IDE int tested_for_xlate = 0; @@ -476,12 +557,25 @@ hd->part[minor].nr_sects = 2; } #ifdef CONFIG_BSD_DISKLABEL + /* tag first disklabel for late recognition */ if (SYS_IND(p) == BSD_PARTITION) { - printk(" <"); - bsd_disklabel_partition(hd, MKDEV(hd->major, minor)); - printk(" >"); + printk("!"); + if (!bsd_kdev) { + bsd_kdev = MKDEV(hd->major, minor); + bsd_maxpart = BSD_MAXPARTITIONS; + } + } else if (SYS_IND(p) == OPENBSD_PARTITION) { + printk("!"); + if (!bsd_kdev) { + bsd_kdev = MKDEV(hd->major, minor); + bsd_maxpart = OPENBSD_MAXPARTITIONS; + } } #endif +#ifdef CONFIG_UNIXWARE_DISKLABEL + if (SYS_IND(p) == UNIXWARE_PARTITION) + unixware_partition(hd, MKDEV(hd->major, minor)); +#endif #ifdef CONFIG_SOLARIS_X86_PARTITION /* james@bpgc.com: Solaris has a nasty indicator: 0x82 @@ -495,6 +589,13 @@ } #endif } +#ifdef CONFIG_BSD_DISKLABEL + if (bsd_kdev) { + printk(" <"); + bsd_disklabel_partition(hd, bsd_kdev, bsd_maxpart); + printk(" >"); + } +#endif /* * Check for old-style Disk Manager partition table */ diff -u --recursive --new-file v2.1.132/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c --- v2.1.132/linux/drivers/block/ide-cd.c Sun Nov 8 14:02:51 1998 +++ linux/drivers/block/ide-cd.c Wed Dec 23 07:56:01 1998 @@ -1,4 +1,3 @@ -#define VERBOSE_IDE_CD_ERRORS 1 /* * linux/drivers/block/ide-cd.c * Copyright (C) 1994, 1995, 1996 scott snyder @@ -28,7 +27,6 @@ * This will allow us to get automagically notified when the media changes * on ATAPI drives (something the stock ATAPI spec is lacking). Looks * very cool. I discovered its existance the other day at work... - * -Fix ide_cdrom_reset so that it works (it does nothing right now) * -Query the drive to find what features are available before trying to * use them (like trying to close the tray in drives that can't). * -Make it so that Pioneer CD DR-A24X and friends don't get screwed up on @@ -36,9 +34,6 @@ * -Handle older drives that can't report their speed. (i.e. check if they * support a version of ATAPI where they can report their speed before * checking their speed and believing what they return). - * -It seems we do not always honor it when Uniform gets a request to change - * the cdi->options. We should _always_ check the options before doing stuff. - * This must be fixed. * * * ---------------------------------- @@ -226,9 +221,16 @@ * Jens Axboe * Chris Zwilling * + * 4.51 Dec 23, 1998 -- Jens Axboe + * - ide_cdrom_reset enabled since the ide subsystem + * handles resets fine now. + * - Transfer size fix for Samsung CD-ROMs, thanks to + * "Ville Hallik" . + * - other minor stuff. + * *************************************************************************/ -#define IDECD_VERSION "4.50" +#define IDECD_VERSION "4.51" #include #include @@ -456,7 +458,7 @@ len *= 4; pc->c[0] = REQUEST_SENSE; - pc->c[4] = len; + pc->c[4] = (unsigned char) len; pc->buffer = (char *)reqbuf; pc->buflen = len; pc->sense_data = (struct atapi_request_sense *)failed_command; @@ -856,7 +858,12 @@ if ((len % SECTOR_SIZE) != 0) { printk ("%s: cdrom_read_intr: Bad transfer size %d\n", drive->name, len); - printk (" This drive is not supported by this version of the driver\n"); + if (CDROM_CONFIG_FLAGS (drive)->limit_nframes) + printk (" This drive is not supported by this version of the driver\n"); + else { + printk (" Trying to limit transfer sizes\n"); + CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1; + } cdrom_end_request (0, drive); return; } @@ -992,7 +999,6 @@ { struct packet_command pc; struct request *rq = HWGROUP(drive)->rq; - int nsect, sector, nframes, frame, nskip; /* Number of sectors to transfer. */ @@ -1029,8 +1035,10 @@ nframes = (nsect + SECTORS_PER_FRAME-1) / SECTORS_PER_FRAME; frame = sector / SECTORS_PER_FRAME; - /* Largest number of frames was can transfer at once is 64k-1. */ - nframes = MIN (nframes, 65535); + /* Largest number of frames was can transfer at once is 64k-1. For + some drives we need to limit this even more. */ + nframes = MIN (nframes, (CDROM_CONFIG_FLAGS (drive)->limit_nframes) ? + (65534 / CD_FRAMESIZE) : 65535); /* Set up the command */ memset (&pc.c, 0, sizeof (pc.c)); @@ -1328,7 +1336,7 @@ struct atapi_request_sense *reqbuf = pc->sense_data; if (reqbuf->sense_key == UNIT_ATTENTION) - ; + cdrom_saw_media_change (drive); else if (reqbuf->sense_key == NOT_READY && reqbuf->asc == 4) { /* The drive is in the process of loading @@ -2477,19 +2485,12 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi) { -/* This doesn't work reliably yet, and so it is currently just a stub. */ - -#if 0 ide_drive_t *drive = (ide_drive_t*) cdi->handle; struct request req; + ide_init_drive_cmd (&req); req.cmd = RESET_DRIVE_COMMAND; return ide_do_drive_cmd (drive, &req, ide_wait); -#endif - -/* For now, just return 0, as if things had worked... */ - return 0; - } @@ -2916,10 +2917,10 @@ int major = HWIF(drive)->major; int minor = drive->select.b.unit << PARTN_BITS; - ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL); - ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL); - ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL); - ide_add_setting(drive, "dsc_overlap", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL); + ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL); + ide_add_setting(drive, "file_readahead", SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL); + ide_add_setting(drive, "max_kb_per_request", SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL); + ide_add_setting(drive, "dsc_overlap", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL); } static @@ -2959,6 +2960,13 @@ CDROM_CONFIG_FLAGS (drive)->cd_rw = 0; CDROM_CONFIG_FLAGS (drive)->no_eject = 1; CDROM_CONFIG_FLAGS (drive)->supp_disc_present = 0; + + /* limit transfer size per interrupt. currently only one Samsung + drive needs this. */ + CDROM_CONFIG_FLAGS (drive)->limit_nframes = 0; + if (drive->id != NULL) + if (strcmp (drive->id->model, "SAMSUNG CD-ROM SCR-2432") == 0) + CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1; #if ! STANDARD_ATAPI /* by default Sanyo 3 CD changer support is turned off and diff -u --recursive --new-file v2.1.132/linux/drivers/block/ide-cd.h linux/drivers/block/ide-cd.h --- v2.1.132/linux/drivers/block/ide-cd.h Sun Nov 8 14:02:51 1998 +++ linux/drivers/block/ide-cd.h Mon Dec 28 14:09:30 1998 @@ -14,7 +14,7 @@ memory, though. */ #ifndef VERBOSE_IDE_CD_ERRORS -#define VERBOSE_IDE_CD_ERRORS 0 +#define VERBOSE_IDE_CD_ERRORS 1 #endif @@ -130,6 +130,9 @@ __u8 cd_rw : 1; /* Drive can write to CD-R/W media . */ __u8 supp_disc_present: 1; /* Changer can report exact contents of slots. */ + __u8 limit_nframes : 1; /* Drive does not provide data in + multiples of SECTOR_SIZE when more + than one interrupt is needed. */ __u8 seeking : 1; /* Seeking in progress */ __u8 reserved : 6; byte max_speed; /* Max speed of the drive */ diff -u --recursive --new-file v2.1.132/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c --- v2.1.132/linux/drivers/block/ide-floppy.c Fri Oct 23 22:01:20 1998 +++ linux/drivers/block/ide-floppy.c Wed Dec 23 07:54:22 1998 @@ -633,6 +633,9 @@ } if (error) floppy->failed_pc = NULL; + /* Why does this happen? */ + if (!rq) + return; if (!IDEFLOPPY_RQ_CMD (rq->cmd)) { ide_end_request (uptodate, hwgroup); return; diff -u --recursive --new-file v2.1.132/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c --- v2.1.132/linux/drivers/block/ide-probe.c Thu Nov 19 09:56:28 1998 +++ linux/drivers/block/ide-probe.c Wed Dec 23 09:44:41 1998 @@ -291,7 +291,7 @@ delay_50ms(); OUT_BYTE(WIN_SRST, IDE_COMMAND_REG); timeout = jiffies; - while ((GET_STAT() & BUSY_STAT) && jiffies < timeout + WAIT_WORSTCASE) + while ((GET_STAT() & BUSY_STAT) && time_before(jiffies, timeout + WAIT_WORSTCASE)) delay_50ms(); rc = try_to_identify(drive, cmd); } diff -u --recursive --new-file v2.1.132/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.1.132/linux/drivers/block/ll_rw_blk.c Thu Nov 12 16:21:18 1998 +++ linux/drivers/block/ll_rw_blk.c Mon Dec 28 11:19:19 1998 @@ -644,91 +644,12 @@ if (bh[i]) { clear_bit(BH_Dirty, &bh[i]->b_state); clear_bit(BH_Uptodate, &bh[i]->b_state); + bh[i]->b_end_io(bh[i], 0); } } return; } -void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buf) -{ - int i, j; - int buffersize; - int max_req; - unsigned long rsector; - kdev_t rdev; - struct request * req[8]; - unsigned int major = MAJOR(dev); - struct semaphore sem = MUTEX_LOCKED; - - if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) { - printk(KERN_NOTICE "ll_rw_swap_file: trying to swap to" - " nonexistent block-device\n"); - return; - } - max_req = NR_REQUEST; - switch (rw) { - case READ: - break; - case WRITE: - max_req = (NR_REQUEST * 2) / 3; - if (is_read_only(dev)) { - printk(KERN_NOTICE - "Can't swap to read-only device %s\n", - kdevname(dev)); - return; - } - break; - default: - panic("ll_rw_swap: bad block dev cmd, must be R/W"); - } - buffersize = PAGE_SIZE / nb; - - if ((major == LOOP_MAJOR) || (major == NBD_MAJOR)) - max_req >>= 1; - for (j=0, i=0; i> 9); -#ifdef CONFIG_BLK_DEV_MD - if (major==MD_MAJOR && - md_map (MINOR(dev), &rdev, - &rsector, buffersize >> 9)) { - printk (KERN_ERR - "Bad md_map in ll_rw_swap_file\n"); - return; - } -#endif - - if (j == 0) { - req[j] = get_request_wait(max_req, rdev); - } else { - unsigned long flags; - spin_lock_irqsave(&io_request_lock,flags); - req[j] = get_request(max_req, rdev); - spin_unlock_irqrestore(&io_request_lock,flags); - if (req[j] == NULL) - break; - } - req[j]->cmd = rw; - req[j]->errors = 0; - req[j]->sector = rsector; - req[j]->nr_sectors = buffersize >> 9; - req[j]->current_nr_sectors = buffersize >> 9; - req[j]->buffer = buf; - req[j]->sem = &sem; - req[j]->bh = NULL; - req[j]->next = NULL; - add_request(MAJOR(rdev)+blk_dev,req[j]); - } - run_task_queue(&tq_disk); - while (j > 0) { - j--; - down(&sem); - } - } -} #ifdef CONFIG_STRAM_SWAP extern int stram_device_init( void ); #endif diff -u --recursive --new-file v2.1.132/linux/drivers/block/paride/pg.c linux/drivers/block/paride/pg.c --- v2.1.132/linux/drivers/block/paride/pg.c Sun Nov 8 14:02:51 1998 +++ linux/drivers/block/paride/pg.c Wed Dec 23 09:44:41 1998 @@ -367,21 +367,21 @@ PG.status = 0; j = 0; - while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(jiffies=tmo)) { + if ((r&(STAT_ERR&stop))||time_after_eq(jiffies, tmo)) { s = RR(0,7); e = RR(0,1); p = RR(0,2); if (verbose > 1) printk("%s: %s: stat=0x%x err=0x%x phase=%d%s\n", - PG.name,msg,s,e,p,(jiffies>=tmo)?" timeout":""); + PG.name,msg,s,e,p,time_after_eq(jiffies, tmo)?" timeout":""); - if (jiffies>=tmo) e |= 0x100; + if (time_after_eq(jiffies, tmo)) e |= 0x100; PG.status = (e >> 4) & 0xff; return -1; } diff -u --recursive --new-file v2.1.132/linux/drivers/block/paride/pseudo.h linux/drivers/block/paride/pseudo.h --- v2.1.132/linux/drivers/block/paride/pseudo.h Tue Dec 22 14:16:55 1998 +++ linux/drivers/block/paride/pseudo.h Sun Dec 27 11:25:58 1998 @@ -47,7 +47,7 @@ static int ps_tq_active = 0; static int ps_nice = 0; -static spinlock_t ps_spinlock = SPIN_LOCK_UNLOCKED; +static spinlock_t ps_spinlock __attribute__((unused)) = SPIN_LOCK_UNLOCKED; static struct timer_list ps_timer = {0,0,0,0,ps_timer_int}; static struct tq_struct ps_tq = {0,0,ps_tq_int,NULL}; diff -u --recursive --new-file v2.1.132/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- v2.1.132/linux/drivers/cdrom/cdrom.c Thu Nov 19 09:56:28 1998 +++ linux/drivers/cdrom/cdrom.c Wed Dec 23 07:56:01 1998 @@ -87,15 +87,20 @@ Thanks to Grant R. Guenther for spotting this bug. -- Made a few things more pedanticly correct. - 2.50 Oct 19, 1998 - Jens Axboe +2.50 Oct 19, 1998 - Jens Axboe -- New maintainers! Erik was too busy to continue the work on the driver, so now Chris Zwilling and Jens Axboe will do their best to follow in his footsteps + + 2.51 Dec 20, 1998 - Jens Axboe + -- Check if drive is capable of doing what we ask before blindly changing + cdi->options in various ioctl. + -- Added version to proc entry. -------------------------------------------------------------------------*/ -#define REVISION "Revision: 2.50" -#define VERSION "Id: cdrom.c 2.50 1998/10/19" +#define REVISION "Revision: 2.51" +#define VERSION "Id: cdrom.c 2.51 1998/12/20" /* I use an error-log mask to give fine grain control over the type of messages dumped to the system logs. The available masks include: */ @@ -211,6 +216,8 @@ struct cdrom_device_ops *cdo = cdi->ops; int *change_capability = (int *)&cdo->capability; /* hack */ + cdinfo(CD_OPEN, "entering register_cdrom\n"); + if (major < 0 || major >= MAX_BLKDEV) return -1; if (cdo->open == NULL || cdo->release == NULL) @@ -236,9 +243,10 @@ cdi->mc_flags = 0; cdo->n_minors = 0; cdi->options = CDO_USE_FFLAGS; - if (autoclose==1) + + if (autoclose==1 && cdo->capability & ~cdi->mask & CDC_OPEN_TRAY) cdi->options |= (int) CDO_AUTO_CLOSE; - if (autoeject==1) + if (autoeject==1 && cdo->capability & ~cdi->mask & CDC_OPEN_TRAY) cdi->options |= (int) CDO_AUTO_EJECT; if (lockdoor==1) cdi->options |= (int) CDO_LOCK; @@ -257,6 +265,8 @@ struct cdrom_device_info *cdi, *prev; int major = MAJOR (unreg->dev); + cdinfo(CD_OPEN, "entering unregister_cdrom\n"); + if (major < 0 || major >= MAX_BLKDEV) return -1; @@ -713,6 +723,8 @@ case CDROMEJECT_SW: cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n"); + if (!(cdo->capability & ~cdi->mask & CDC_OPEN_TRAY)) + return -ENOSYS; cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT); if (arg) cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT; @@ -733,6 +745,8 @@ case CDROM_SET_OPTIONS: cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n"); + if (cdo->capability & arg & ~cdi->mask) + return -ENOSYS; cdi->options |= (int) arg; return cdi->options; @@ -984,7 +998,7 @@ int retv,pos; struct cdrom_device_info *cdi; - pos = sprintf(cdrom_drive_info, "CD-ROM information\n"); + pos = sprintf(cdrom_drive_info, "CD-ROM information, " VERSION "\n"); pos += sprintf(cdrom_drive_info+pos, "\ndrive name:\t"); for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) diff -u --recursive --new-file v2.1.132/linux/drivers/char/Config.in linux/drivers/char/Config.in --- v2.1.132/linux/drivers/char/Config.in Tue Dec 22 14:16:55 1998 +++ linux/drivers/char/Config.in Sun Dec 27 10:48:46 1998 @@ -56,12 +56,15 @@ bool 'Mouse Support (not serial mice)' CONFIG_MOUSE if [ "$CONFIG_MOUSE" = "y" ]; then + mainmenu_option next_comment + comment 'Mice' tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE tristate 'Logitech busmouse support' CONFIG_BUSMOUSE tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE 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 + endmenu fi tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE @@ -72,12 +75,14 @@ else comment ' Setting runtime QIC-02 configuration is done with qic02conf' comment ' from the tpqic02-support package. It is available at' - comment ' sunsite.unc.edu or ftp://titus.cfw.com/pub/Linux/util/' + comment ' metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/' fi fi bool 'Watchdog Timer Support' CONFIG_WATCHDOG if [ "$CONFIG_WATCHDOG" != "n" ]; then + mainmenu_option next_comment + comment 'Watchdog Cards' bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT tristate ' WDT Watchdog timer' CONFIG_WDT if [ "$CONFIG_WDT" != "n" ]; then @@ -89,12 +94,19 @@ tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT + endmenu fi + + +tristate '/dev/nvram support' CONFIG_NVRAM bool 'Enhanced Real Time Clock Support' CONFIG_RTC if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then bool 'Tadpole ANA H8 Support' CONFIG_H8 fi +mainmenu_option next_comment +comment 'Video For Linux' + tristate 'Video For Linux' CONFIG_VIDEO_DEV if [ "$CONFIG_VIDEO_DEV" != "n" ]; then dep_tristate 'AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK $CONFIG_VIDEO_DEV @@ -110,6 +122,10 @@ hex ' Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350 fi dep_tristate 'Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV + dep_tristate 'GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then + hex ' GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c + fi if [ "$CONFIG_PCI" != "n" ]; then dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV fi @@ -128,11 +144,18 @@ hex ' ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c fi fi -tristate '/dev/nvram support' CONFIG_NVRAM + +endmenu + +mainmenu_option next_comment +comment 'Joystick support' + tristate 'Joystick support' CONFIG_JOYSTICK if [ "$CONFIG_JOYSTICK" != "n" ]; then source drivers/char/joystick/Config.in fi +endmenu + mainmenu_option next_comment comment 'Ftape, the floppy tape device driver' tristate 'Ftape (QIC-80/Travan) support' CONFIG_FTAPE diff -u --recursive --new-file v2.1.132/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.1.132/linux/drivers/char/Makefile Tue Dec 22 14:16:55 1998 +++ linux/drivers/char/Makefile Sun Dec 27 10:49:06 1998 @@ -380,6 +380,14 @@ endif endif +ifeq ($(CONFIG_RADIO_GEMTEK),y) +L_OBJS += radio-gemtek.o +else + ifeq ($(CONFIG_RADIO_GEMTEK),m) + M_OBJS += radio-gemtek.o + endif +endif + ifeq ($(CONFIG_QIC02_TAPE),y) L_OBJS += tpqic02.o else diff -u --recursive --new-file v2.1.132/linux/drivers/char/isicom.c linux/drivers/char/isicom.c --- v2.1.132/linux/drivers/char/isicom.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/char/isicom.c Wed Dec 23 09:44:41 1998 @@ -152,12 +152,12 @@ inw(base+0x8); - for(i=jiffies+HZ/100;i>jiffies;); + for(i=jiffies+HZ/100;time_before(jiffies, i);); outw(0,base+0x8); /* Reset */ for(j=1;j<=3;j++) { - for(i=jiffies+HZ;i>jiffies;); + for(i=jiffies+HZ;time_before(jiffies, i);); printk("."); } signature=(inw(base+0x4)) & 0xff; diff -u --recursive --new-file v2.1.132/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c --- v2.1.132/linux/drivers/char/pc_keyb.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/char/pc_keyb.c Mon Dec 28 11:04:00 1998 @@ -761,6 +761,11 @@ } +/* + * Random magic cookie for the aux device + */ +#define AUX_DEV ((void *)queue) + static int release_aux(struct inode * inode, struct file * file) { fasync_aux(-1, file, 0); @@ -768,11 +773,7 @@ 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 + free_irq(AUX_IRQ, AUX_DEV); return 0; } @@ -787,11 +788,7 @@ 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 + if (request_irq(AUX_IRQ, keyboard_interrupt, SA_SHIRQ, "PS/2 Mouse", AUX_DEV)) { aux_count--; return -EBUSY; } diff -u --recursive --new-file v2.1.132/linux/drivers/char/radio-gemtek.c linux/drivers/char/radio-gemtek.c --- v2.1.132/linux/drivers/char/radio-gemtek.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/radio-gemtek.c Sun Dec 27 10:49:06 1998 @@ -0,0 +1,310 @@ +/* GemTek radio card driver for Linux (C) 1998 Jonas Munsin + * + * GemTek hasn't released any specs on the card, so the protocol had to + * be reverse engineered with dosemu. + * + * Besides the protocol changes, this is mostly a copy of: + * + * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff + * + * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood + * Coverted to new API by Alan Cox + * Various bugfixes and enhancements by Russell Kroll + * + * TODO: Allow for more than one of these foolish entities :-) + * + */ + +#include /* Modules */ +#include /* Initdata */ +#include /* check_region, request_region */ +#include /* udelay */ +#include /* outb, outb_p */ +#include /* copy to/from user */ +#include /* kernel radio structs */ +#include /* CONFIG_RADIO_GEMTEK_PORT */ + +#ifndef CONFIG_RADIO_GEMTEK_PORT +#define CONFIG_RADIO_GEMTEK_PORT -1 +#endif + +static int io = CONFIG_RADIO_GEMTEK_PORT; +static int users = 0; + +struct gemtek_device +{ + int port; + unsigned long curfreq; + int muted; +}; + + +/* local things */ + +/* the correct way to mute the gemtek may be to write the last written + * frequency || 0x10, but just writing 0x10 once seems to do it as well + */ +static void gemtek_mute(struct gemtek_device *dev) +{ + if(dev->muted) + return; + outb(0x10, io); + dev->muted = 1; +} + +static void gemtek_unmute(struct gemtek_device *dev) +{ + if(dev->muted == 0) + return; + outb(0x20, io); + dev->muted = 0; +} + +static void zero(void) +{ + outb_p(0x04, io); + udelay(5); + outb_p(0x05, io); + udelay(5); +} + +static void one(void) +{ + outb_p(0x06, io); + udelay(5); + outb_p(0x07, io); + udelay(5); +} + +static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq) +{ + int i; + +/* freq = 78.25*((float)freq/16000.0 + 10.52); */ + + freq /= 16; + freq += 10520; + freq *= 7825; + freq /= 100000; + + /* 2 start bits */ + outb_p(0x03, io); + udelay(5); + outb_p(0x07, io); + udelay(5); + + /* 28 frequency bits (lsb first) */ + for (i = 0; i < 14; i++) + if (freq & (1 << i)) + one(); + else + zero(); + /* 36 unknown bits */ + for (i = 0; i < 11; i++) + zero(); + one(); + for (i = 0; i < 4; i++) + zero(); + one(); + zero(); + + /* 2 end bits */ + outb_p(0x03, io); + udelay(5); + outb_p(0x07, io); + udelay(5); + + return 0; +} + +int gemtek_getsigstr(struct gemtek_device *dev) +{ + inb(io); + udelay(5); + if (inb(io) & 8) /* bit set = no signal present */ + return 0; + return 1; /* signal present */ +} + +static int gemtek_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +{ + struct gemtek_device *rt=dev->priv; + + switch(cmd) + { + case VIDIOCGCAP: + { + struct video_capability v; + v.type=VID_TYPE_TUNER; + v.channels=1; + v.audios=1; + /* No we don't do pictures */ + v.maxwidth=0; + v.maxheight=0; + v.minwidth=0; + v.minheight=0; + strcpy(v.name, "GemTek"); + if(copy_to_user(arg,&v,sizeof(v))) + return -EFAULT; + return 0; + } + case VIDIOCGTUNER: + { + struct video_tuner v; + if(copy_from_user(&v, arg,sizeof(v))!=0) + return -EFAULT; + if(v.tuner) /* Only 1 tuner */ + return -EINVAL; + v.rangelow=87*16000; + v.rangehigh=108*16000; + v.flags=VIDEO_TUNER_LOW; + v.mode=VIDEO_MODE_AUTO; + v.signal=0xFFFF*gemtek_getsigstr(rt); + if(copy_to_user(arg,&v, sizeof(v))) + return -EFAULT; + return 0; + } + case VIDIOCSTUNER: + { + struct video_tuner v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.tuner!=0) + return -EINVAL; + /* Only 1 tuner so no setting needed ! */ + return 0; + } + case VIDIOCGFREQ: + if(copy_to_user(arg, &rt->curfreq, sizeof(rt->curfreq))) + return -EFAULT; + return 0; + case VIDIOCSFREQ: + if(copy_from_user(&rt->curfreq, arg,sizeof(rt->curfreq))) + return -EFAULT; + /* needs to be called twice in order for getsigstr to work */ + gemtek_setfreq(rt, rt->curfreq); + gemtek_setfreq(rt, rt->curfreq); + return 0; + case VIDIOCGAUDIO: + { + struct video_audio v; + memset(&v,0, sizeof(v)); + v.flags|=VIDEO_AUDIO_MUTABLE; + v.volume=1; + v.step=65535; + strcpy(v.name, "Radio"); + if(copy_to_user(arg,&v, sizeof(v))) + return -EFAULT; + return 0; + } + case VIDIOCSAUDIO: + { + struct video_audio v; + if(copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if(v.audio) + return -EINVAL; + + if(v.flags&VIDEO_AUDIO_MUTE) + gemtek_mute(rt); + else + gemtek_unmute(rt); + + return 0; + } + default: + return -ENOIOCTLCMD; + } +} + +static int gemtek_open(struct video_device *dev, int flags) +{ + if(users) + return -EBUSY; + users++; + MOD_INC_USE_COUNT; + return 0; +} + +static void gemtek_close(struct video_device *dev) +{ + users--; + MOD_DEC_USE_COUNT; +} + +static struct gemtek_device gemtek_unit; + +static struct video_device gemtek_radio= +{ + "GemTek radio", + VID_TYPE_TUNER, + VID_HARDWARE_GEMTEK, + gemtek_open, + gemtek_close, + NULL, /* Can't read (no capture ability) */ + NULL, /* Can't write */ + NULL, /* Can't poll */ + gemtek_ioctl, + NULL, + NULL +}; + +__initfunc(int gemtek_init(struct video_init *v)) +{ + if (check_region(io, 4)) + { + printk(KERN_ERR "gemtek: port 0x%x already in use\n", io); + return -EBUSY; + } + + gemtek_radio.priv=&gemtek_unit; + + if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO)==-1) + return -EINVAL; + + request_region(io, 4, "gemtek"); + printk(KERN_INFO "GemTek Radio Card driver.\n"); + + /* mute card - prevents noisy bootups */ + outb(0x10, io); + udelay(5); + gemtek_unit.muted = 1; + + /* this is _maybe_ unnecessary */ + outb(0x01, io); + + return 0; +} + +#ifdef MODULE + +MODULE_AUTHOR("Jonas Munsin"); +MODULE_DESCRIPTION("A driver for the GemTek Radio Card"); +MODULE_PARM(io, "i"); +MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c)"); + +EXPORT_NO_SYMBOLS; + +int init_module(void) +{ + if(io==-1) + { + printk(KERN_ERR "You must set an I/O address with io=0x20c, io=0x30c, io=0x24c or io=0x34c\n"); + return -EINVAL; + } + return gemtek_init(NULL); +} + +void cleanup_module(void) +{ + video_unregister_device(&gemtek_radio); + release_region(io,4); +} + +#endif + +/* + Local variables: + compile-command: "gcc -c -DMODVERSIONS -D__KERNEL__ -DMODULE -O6 -Wall -Wstrict-prototypes -I /home/blp/tmp/linux-2.1.111-rtrack/include radio-rtrack2.c" + End: +*/ diff -u --recursive --new-file v2.1.132/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v2.1.132/linux/drivers/char/serial.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/char/serial.c Wed Dec 23 09:44:41 1998 @@ -2369,7 +2369,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } current->state = TASK_RUNNING; diff -u --recursive --new-file v2.1.132/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v2.1.132/linux/drivers/char/tpqic02.c Sun Nov 8 14:02:56 1998 +++ linux/drivers/char/tpqic02.c Wed Dec 23 09:44:41 1998 @@ -571,7 +571,7 @@ timeout -= spin_t; spin_t += jiffies; - while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && (jiffiesstate = TASK_INTERRUPTIBLE; /* nap 0.30 sec between checks, */ diff -u --recursive --new-file v2.1.132/linux/drivers/char/videodev.c linux/drivers/char/videodev.c --- v2.1.132/linux/drivers/char/videodev.c Thu Nov 12 16:21:19 1998 +++ linux/drivers/char/videodev.c Sun Dec 27 10:49:06 1998 @@ -68,6 +68,9 @@ #ifdef CONFIG_RADIO_MIROPCM20 extern int pcm20_init(struct video_init *); #endif +#ifdef CONFIG_RADIO_GEMTEK +extern int gemtek_init(struct video_init *); +#endif #ifdef CONFIG_VIDEO_PMS extern int init_pms_cards(struct video_init *); #endif @@ -103,6 +106,9 @@ #endif #ifdef CONFIG_RADIO_MIROPCM20 {"PCM20", pcm20_init}, +#endif +#ifdef CONFIG_RADIO_GEMTEK + {"GemTek", gemtek_init}, #endif {"end", NULL} }; diff -u --recursive --new-file v2.1.132/linux/drivers/isdn/avmb1/b1lli.c linux/drivers/isdn/avmb1/b1lli.c --- v2.1.132/linux/drivers/isdn/avmb1/b1lli.c Wed Apr 1 20:11:49 1998 +++ linux/drivers/isdn/avmb1/b1lli.c Wed Dec 23 09:44:41 1998 @@ -173,7 +173,7 @@ static inline unsigned char B1_get_byte(unsigned short base) { unsigned long i = jiffies + 5 * HZ; /* maximum wait time 5 sec */ - while (!B1_rx_full(base) && i > jiffies); + while (!B1_rx_full(base) && time_before(jiffies, i)); if (B1_rx_full(base)) return inb(base + B1_READ); printk(KERN_CRIT "b1lli: rx not full after 5 second\n"); @@ -477,7 +477,7 @@ if (loaddebug) printk(KERN_DEBUG "b1capi: loaded: wait 1 ..\n"); - for (i = jiffies + 10 * HZ; i > jiffies;) { + for (i = jiffies + 10 * HZ; time_before(jiffies, i);) { if (B1_tx_empty(base)) break; } @@ -487,7 +487,7 @@ } B1_put_byte(base, SEND_POLL); printk(KERN_DEBUG "b1capi: loaded: wait 2 ..\n"); - for (i = jiffies + 10 * HZ; i > jiffies;) { + for (i = jiffies + 10 * HZ; time_before(jiffies, i);) { if (B1_rx_full(base)) { if ((ans = B1_get_byte(base)) == RECEIVE_POLL) { if (loaddebug) diff -u --recursive --new-file v2.1.132/linux/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c --- v2.1.132/linux/drivers/isdn/hisax/callc.c Wed Apr 1 20:11:50 1998 +++ linux/drivers/isdn/hisax/callc.c Sun Dec 27 10:44:45 1998 @@ -62,7 +62,7 @@ #include "hisax.h" #ifdef MODULE -#define MOD_USE_COUNT ((&__this_module)->usecount) +#define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module)) #endif /* MODULE */ const char *lli_revision = "$Revision: 2.13 $"; @@ -2055,7 +2055,7 @@ if (csta->channel[0].debug & 0x400) { jiftime(tmp, jiffies); i = strlen(tmp); - sprintf(tmp + i, " LOCK modcnt %lx\n", MOD_USE_COUNT); + sprintf(tmp + i, " LOCK modcnt %d\n", MOD_USE_COUNT); HiSax_putstatus(csta, tmp); } #endif /* MODULE */ @@ -2066,7 +2066,7 @@ if (csta->channel[0].debug & 0x400) { jiftime(tmp, jiffies); i = strlen(tmp); - sprintf(tmp + i, " UNLOCK modcnt %lx\n", MOD_USE_COUNT); + sprintf(tmp + i, " UNLOCK modcnt %d\n", MOD_USE_COUNT); HiSax_putstatus(csta, tmp); } #endif /* MODULE */ @@ -2128,7 +2128,8 @@ break; #ifdef MODULE case (55): - MOD_USE_COUNT = 0; + while ( MOD_USE_COUNT > 0) + MOD_DEC_USE_COUNT; HiSax_mod_inc_use_count(); break; #endif /* MODULE */ diff -u --recursive --new-file v2.1.132/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c --- v2.1.132/linux/drivers/macintosh/macserial.c Thu Nov 19 09:56:28 1998 +++ linux/drivers/macintosh/macserial.c Wed Dec 23 09:44:41 1998 @@ -1328,7 +1328,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } current->state = TASK_RUNNING; diff -u --recursive --new-file v2.1.132/linux/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c --- v2.1.132/linux/drivers/macintosh/via-pmu.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/macintosh/via-pmu.c Wed Dec 23 09:44:41 1998 @@ -894,7 +894,7 @@ pmu_enable_backlight(0); /* Give the disks a little time to actually finish writing */ - for (wait = jiffies + (HZ/4); jiffies < wait; ) + for (wait = jiffies + (HZ/4); time_before(jiffies, wait); ) mb(); /* Disable all interrupts except pmu */ diff -u --recursive --new-file v2.1.132/linux/drivers/net/3c523.c linux/drivers/net/3c523.c --- v2.1.132/linux/drivers/net/3c523.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/net/3c523.c Sun Dec 27 10:53:45 1998 @@ -539,7 +539,7 @@ } dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */ - ((struct priv *) (dev->priv))->base = phys_to_virt(dev->mem_start + size - 0x01000000); + ((struct priv *) (dev->priv))->base = (unsigned long)phys_to_virt(dev->mem_start + size - 0x01000000); alloc586(dev); elmc_id_reset586(); /* make sure it doesn't generate spurious ints */ diff -u --recursive --new-file v2.1.132/linux/drivers/net/8390.c linux/drivers/net/8390.c --- v2.1.132/linux/drivers/net/8390.c Fri Nov 27 13:09:23 1998 +++ linux/drivers/net/8390.c Mon Dec 28 11:04:21 1998 @@ -37,7 +37,7 @@ 68K Macintosh. Support >16bit I/O spaces Paul Gortmaker : add kmod support for auto-loading of the 8390 module by all drivers that require it. - + Alan Cox : Spinlocking work, added 'BUG_83C690' Sources: The National Semiconductor LAN Databook, and the 3Com 3c503 databook. @@ -72,6 +72,8 @@ #define NS8390_CORE #include "8390.h" +#define BUG_83C690 + /* These are the operational function interfaces to board-specific routines. void reset_8390(struct device *dev) @@ -110,6 +112,34 @@ static void NS8390_trigger_send(struct device *dev, unsigned int length, int start_page); static void set_multicast_list(struct device *dev); +static void do_set_multicast_list(struct device *dev); + +/* + * SMP and the 8390 setup. + * + * The 8390 isnt exactly designed to be multithreaded on RX/TX. There is + * a page register that controls bank and packet buffer access. We guard + * this with ei_local->page_lock. Nobody should assume or set the page other + * than zero when the lock is not held. Lock holders must restore page 0 + * before unlocking. Even pure readers must take the lock to protect in + * page 0. + * + * To make life difficult the chip can also be very slow. We therefore can't + * just use spinlocks. For the longer lockups we disable the irq the device + * sits on and hold the lock. We must hold the lock because there is a dual + * processor case other than interrupts (get stats/set multicast list in + * parallel with each other and transmit). + * + * Note: in theory we can just disable the irq on the card _but_ there is + * a latency on SMP irq delivery. So we can easily go "disable irq" "sync irqs" + * enter lock, take the queued irq. So we waddle instead of flying. + * + * Finally by special arrangement for the purpose of being generally + * annoying the transmit function is called bh atomic. That places + * restrictions on the user context callers as disable_irq won't save + * them. + */ + /* Open/initialize the board. This routine goes all-out, setting everything @@ -118,6 +148,7 @@ */ int ei_open(struct device *dev) { + unsigned long flags; struct ei_device *ei_local = (struct ei_device *) dev->priv; /* This can't happen unless somebody forgot to call ethdev_init(). */ @@ -127,7 +158,14 @@ return -ENXIO; } + /* + * Grab the page lock so we own the register set, then call + * the init function. + */ + + spin_lock_irqsave(&ei_local->page_lock, flags); NS8390_init(dev, 1); + spin_unlock_irqrestore(&ei_local->page_lock, flags); dev->start = 1; ei_local->irqlock = 0; return 0; @@ -136,7 +174,16 @@ /* Opposite of above. Only used when "ifconfig down" is done. */ int ei_close(struct device *dev) { + struct ei_device *ei_local = (struct ei_device *) dev->priv; + unsigned long flags; + + /* + * Hold the page lock during close + */ + + spin_lock_irqsave(&ei_local->page_lock, flags); NS8390_init(dev, 0); + spin_unlock_irqrestore(&ei_local->page_lock, flags); dev->start = 0; return 0; } @@ -146,24 +193,39 @@ int e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; int length, send_length, output_page; + unsigned long flags; /* * We normally shouldn't be called if dev->tbusy is set, but the * existing code does anyway. If it has been too long since the - * last Tx, we assume the board has died and kick it. + * last Tx, we assume the board has died and kick it. We are + * bh_atomic here. */ if (dev->tbusy) { /* Do timeouts, just like the 8003 driver. */ - int txsr = inb(e8390_base+EN0_TSR), isr; + int txsr; + int isr; int tickssofar = jiffies - dev->trans_start; + + /* + * Need the page lock. Now see what went wrong. This bit is + * fast. + */ + + spin_lock_irqsave(&ei_local->page_lock, flags); + txsr = inb(e8390_base+EN0_TSR); if (tickssofar < TX_TIMEOUT || (tickssofar < (TX_TIMEOUT+5) && ! (txsr & ENTSR_PTX))) + { + spin_unlock_irqrestore(&ei_local->page_lock, flags); return 1; + } ei_local->stat.tx_errors++; isr = inb(e8390_base+EN0_ISR); if (dev->start == 0) { + spin_unlock_irqrestore(&ei_local->page_lock, flags); printk(KERN_WARNING "%s: xmit on stopped card\n", dev->name); return 1; } @@ -184,22 +246,54 @@ ei_local->interface_num ^= 1; /* Try a different xcvr. */ } + /* + * Play shuffle the locks, a reset on some chips takes a few + * mS. We very rarely hit this point. + */ + + spin_unlock_irqrestore(&ei_local->page_lock, flags); + + /* Ugly but a reset can be slow, yet must be protected */ + + disable_irq(dev->irq); + synchronize_irq(); + spin_lock(&ei_local->page_lock); + /* Try to restart the card. Perhaps the user has fixed something. */ ei_reset_8390(dev); NS8390_init(dev, 1); + + spin_unlock(&ei_local->page_lock); + enable_irq(dev->irq); dev->trans_start = jiffies; } length = skb->len; - /* Mask interrupts from the ethercard. */ + /* Mask interrupts from the ethercard. + SMP: We have to grab the lock here otherwise the IRQ handler + on another CPU can flip window and race the IRQ mask set. We end + up trashing the mcast filter not disabling irqs if we dont lock */ + + spin_lock_irqsave(&ei_local->page_lock, flags); outb_p(0x00, e8390_base + EN0_IMR); + spin_unlock_irqrestore(&ei_local->page_lock, flags); + + + /* + * Slow phase with lock held. + */ + disable_irq(dev->irq); synchronize_irq(); + + spin_lock(&ei_local->page_lock); + if (dev->interrupt) { printk(KERN_WARNING "%s: Tx request while isr active.\n",dev->name); outb_p(ENISR_ALL, e8390_base + EN0_IMR); + spin_unlock(&ei_local->page_lock); enable_irq(dev->irq); ei_local->stat.tx_errors++; dev_kfree_skb(skb); @@ -243,6 +337,7 @@ ei_local->irqlock = 0; dev->tbusy = 1; outb_p(ENISR_ALL, e8390_base + EN0_IMR); + spin_unlock(&ei_local->page_lock); enable_irq(dev->irq); ei_local->stat.tx_errors++; return 1; @@ -294,6 +389,8 @@ /* Turn 8390 interrupts back on. */ ei_local->irqlock = 0; outb_p(ENISR_ALL, e8390_base + EN0_IMR); + + spin_unlock(&ei_local->page_lock); enable_irq(dev->irq); dev_kfree_skb (skb); @@ -320,6 +417,13 @@ e8390_base = dev->base_addr; ei_local = (struct ei_device *) dev->priv; + + /* + * Protect the irq test too. + */ + + spin_lock(&ei_local->page_lock); + if (dev->interrupt || ei_local->irqlock) { #if 1 /* This might just be an interrupt for a PCI device sharing this line */ @@ -330,15 +434,17 @@ dev->name, inb_p(e8390_base + EN0_ISR), inb_p(e8390_base + EN0_IMR)); #endif + spin_unlock(&ei_local->page_lock); return; } + dev->interrupt = 1; /* Change to page 0 and read the intr status reg. */ outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD); if (ei_debug > 3) - printk("%s: interrupt(isr=%#2.2x).\n", dev->name, + printk(KERN_DEBUG "%s: interrupt(isr=%#2.2x).\n", dev->name, inb_p(e8390_base + EN0_ISR)); /* !!Assumption!! -- we stay in page 0. Don't break this. */ @@ -386,15 +492,16 @@ outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); if (nr_serviced >= MAX_SERVICE) { - printk("%s: Too much work at interrupt, status %#2.2x\n", + printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n", dev->name, interrupts); outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ } else { - printk("%s: unknown interrupt %#2x\n", dev->name, interrupts); + printk(KERN_WARNING "%s: unknown interrupt %#2x\n", dev->name, interrupts); outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */ } } dev->interrupt = 0; + spin_unlock(&ei_local->page_lock); return; } @@ -405,6 +512,8 @@ * letting the failed packet sit and collect dust in the Tx buffer. This * is a much better solution as it avoids kernel based Tx timeouts, and * an unnecessary card reset. + * + * Called with lock held */ static void ei_tx_err(struct device *dev) @@ -443,7 +552,7 @@ } /* We have finished a transmit: check for errors and then trigger the next - packet to be sent. */ + packet to be sent. Called with lock held */ static void ei_tx_intr(struct device *dev) { @@ -532,7 +641,8 @@ mark_bh (NET_BH); } -/* We have a good packet(s), get it/them out of the buffers. */ +/* We have a good packet(s), get it/them out of the buffers. + Called with lock held */ static void ei_receive(struct device *dev) { @@ -659,6 +769,8 @@ * the updated datasheets, or "the NIC may act in an unpredictable manner." * This includes causing "the NIC to defer indefinitely when it is stopped * on a busy network." Ugh. + * Called with lock held. Don't call this with the interrupts off or your + * computer will hate you - it takes 10mS or so. */ static void ei_rx_overrun(struct device *dev) @@ -726,19 +838,26 @@ outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD); } +/* + * Collect the stats. This is called unlocked and from several contexts. + */ + static struct net_device_stats *get_stats(struct device *dev) { int ioaddr = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; + unsigned long flags; /* If the card is stopped, just return the present stats. */ if (dev->start == 0) return &ei_local->stat; + spin_lock_irqsave(&ei_local->page_lock,flags); /* Read the counter registers, assuming we are in page 0. */ ei_local->stat.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0); ei_local->stat.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1); ei_local->stat.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2); + spin_unlock_irqrestore(&ei_local->page_lock, flags); return &ei_local->stat; } @@ -794,14 +913,14 @@ } /* - * Set or clear the multicast filter for this adaptor. + * Set or clear the multicast filter for this adaptor. May be called + * from a BH in 2.1.x. Must be called with lock held. */ -static void set_multicast_list(struct device *dev) +static void do_set_multicast_list(struct device *dev) { int e8390_base = dev->base_addr; int i; - unsigned long flags; struct ei_device *ei_local = (struct ei_device*)dev->priv; if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) @@ -825,21 +944,19 @@ * them as r/w so this is a bug. The SMC 83C790 (SMC Ultra and * Ultra32 EISA) appears to have this bug fixed. */ + if (dev->start) outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); - save_flags(flags); - cli(); outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); for(i = 0; i < 8; i++) { outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); -#ifdef NOT_83C690 +#ifndef BUG_83C690 if(inb_p(e8390_base + EN1_MULT_SHIFT(i))!=ei_local->mcfilter[i]) printk(KERN_ERR "Multicast filter read/write mismap %d\n",i); #endif } outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD); - restore_flags(flags); if(dev->flags&IFF_PROMISC) outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR); @@ -847,12 +964,29 @@ outb_p(E8390_RXCONFIG | 0x08, e8390_base + EN0_RXCR); else outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); -} + } + +/* + * Called without lock held. This is invoked from user context and may + * be parallel to just about everything else. Its also fairly quick and + * not called too often. Must protect against both bh and irq users + */ + +static void set_multicast_list(struct device *dev) +{ + unsigned long flags; + struct ei_device *ei_local = (struct ei_device*)dev->priv; + + spin_lock_irqsave(&ei_local->page_lock, flags); + do_set_multicast_list(dev); + spin_unlock_irqrestore(&ei_local->page_lock, flags); +} /* * Initialize the rest of the 8390 device structure. Do NOT __initfunc * this, as it is used by 8390 based modular drivers too. */ + int ethdev_init(struct device *dev) { if (ei_debug > 1) @@ -867,6 +1001,7 @@ return -ENOMEM; memset(dev->priv, 0, sizeof(struct ei_device)); ei_local = (struct ei_device *)dev->priv; + spin_lock_init(&ei_local->page_lock); } dev->hard_start_xmit = &ei_start_xmit; @@ -883,13 +1018,16 @@ /* This page of functions should be 8390 generic */ /* Follow National Semi's recommendations for initializing the "NIC". */ +/* + * Must be called with lock held. + */ + void NS8390_init(struct device *dev, int startp) { int e8390_base = dev->base_addr; struct ei_device *ei_local = (struct ei_device *) dev->priv; int i; int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48; - unsigned long flags; if(sizeof(struct e8390_pkt_hdr)!=4) panic("8390.c: header struct mispacked\n"); @@ -914,8 +1052,7 @@ outb_p(0x00, e8390_base + EN0_IMR); /* Copy the station address into the DS8390 registers. */ - save_flags(flags); - cli(); + outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base+E8390_CMD); /* 0x61 */ for(i = 0; i < 6; i++) { @@ -926,7 +1063,7 @@ outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); - restore_flags(flags); + dev->tbusy = 0; dev->interrupt = 0; ei_local->tx1 = ei_local->tx2 = 0; @@ -940,18 +1077,20 @@ outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */ /* 3c503 TechMan says rxconfig only after the NIC is started. */ outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); /* rx on, */ - set_multicast_list(dev); /* (re)load the mcast table */ + do_set_multicast_list(dev); /* (re)load the mcast table */ } return; } -/* Trigger a transmit start, assuming the length is valid. */ +/* Trigger a transmit start, assuming the length is valid. + Always called with the page lock held */ + static void NS8390_trigger_send(struct device *dev, unsigned int length, int start_page) { int e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) dev->priv; - + struct ei_device *ei_local = (struct ei_device *) dev->priv; + outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); if (inb_p(e8390_base) & E8390_TRANS) diff -u --recursive --new-file v2.1.132/linux/drivers/net/8390.h linux/drivers/net/8390.h --- v2.1.132/linux/drivers/net/8390.h Mon Oct 5 13:13:39 1998 +++ linux/drivers/net/8390.h Mon Dec 28 11:04:21 1998 @@ -155,30 +155,30 @@ things in there should be here!) */ /* You have one of these per-board */ struct ei_device { - const char *name; - void (*reset_8390)(struct device *); - void (*get_8390_hdr)(struct device *, struct e8390_pkt_hdr *, int); - void (*block_output)(struct device *, int, const unsigned char *, int); - void (*block_input)(struct device *, int, struct sk_buff *, int); - unsigned char mcfilter[8]; - unsigned open:1; - unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */ - unsigned txing:1; /* Transmit Active */ - unsigned irqlock:1; /* 8390's intrs disabled when '1'. */ - unsigned dmaing:1; /* Remote DMA Active */ - unsigned char tx_start_page, rx_start_page, stop_page; - unsigned char current_page; /* Read pointer in buffer */ - unsigned char interface_num; /* Net port (AUI, 10bT.) to use. */ - unsigned char txqueue; /* Tx Packet buffer queue length. */ - short tx1, tx2; /* Packet lengths for ping-pong tx. */ - short lasttx; /* Alpha version consistency check. */ - unsigned char reg0; /* Register '0' in a WD8013 */ - unsigned char reg5; /* Register '5' in a WD8013 */ - unsigned char saved_irq; /* Original dev->irq value. */ - /* The new statistics table. */ - struct net_device_stats stat; - unsigned char *reg_offset; /* Register mapping table */ - unsigned long priv; /* Private field to store bus IDs etc. */ + const char *name; + void (*reset_8390)(struct device *); + void (*get_8390_hdr)(struct device *, struct e8390_pkt_hdr *, int); + void (*block_output)(struct device *, int, const unsigned char *, int); + void (*block_input)(struct device *, int, struct sk_buff *, int); + unsigned char mcfilter[8]; + unsigned open:1; + unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */ + unsigned txing:1; /* Transmit Active */ + unsigned irqlock:1; /* 8390's intrs disabled when '1'. */ + unsigned dmaing:1; /* Remote DMA Active */ + unsigned char tx_start_page, rx_start_page, stop_page; + unsigned char current_page; /* Read pointer in buffer */ + unsigned char interface_num; /* Net port (AUI, 10bT.) to use. */ + unsigned char txqueue; /* Tx Packet buffer queue length. */ + short tx1, tx2; /* Packet lengths for ping-pong tx. */ + short lasttx; /* Alpha version consistency check. */ + unsigned char reg0; /* Register '0' in a WD8013 */ + unsigned char reg5; /* Register '5' in a WD8013 */ + unsigned char saved_irq; /* Original dev->irq value. */ + struct net_device_stats stat; /* The new statistics table. */ + u32 *reg_offset; /* Register mapping table */ + spinlock_t page_lock; /* Page register locks */ + unsigned long priv; /* Private field to store bus IDs etc. */ }; /* The maximum number of 8390 interrupt service routines called per IRQ. */ @@ -190,12 +190,12 @@ #define ei_status (*(struct ei_device *)(dev->priv)) /* Some generic ethernet register configurations. */ -#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */ -#define E8390_RX_IRQ_MASK 0x5 -#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */ -#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */ -#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */ -#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */ +#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */ +#define E8390_RX_IRQ_MASK 0x5 +#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */ +#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */ +#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */ +#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */ /* Register accessed at EN_CMD, the 8390 base addr. */ #define E8390_STOP 0x01 /* Stop and reset the chip */ @@ -208,6 +208,10 @@ #define E8390_PAGE1 0x40 /* using the two high-order bits */ #define E8390_PAGE2 0x80 /* Page 3 is invalid. */ +/* + * Only generate indirect loads given a machine that needs them. + */ + #if defined(CONFIG_MAC) || defined(CONFIG_AMIGA_PCMCIA) || \ defined(CONFIG_ARIADNE2) || defined(CONFIG_ARIADNE2_MODULE) #define EI_SHIFT(x) (ei_local->reg_offset[x]) diff -u --recursive --new-file v2.1.132/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.132/linux/drivers/net/Config.in Fri Nov 27 13:09:23 1998 +++ linux/drivers/net/Config.in Wed Dec 23 14:41:03 1998 @@ -224,6 +224,10 @@ # dep_tristate 'Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m # +# The COSA/SRP driver has not been tested as non-modular yet. +# +dep_tristate 'COSA/SRP sync serial boards support' CONFIG_COSA m +# if [ "$CONFIG_WAN_ROUTER" != "n" ]; then bool 'WAN drivers' CONFIG_WAN_DRIVERS if [ "$CONFIG_WAN_DRIVERS" = "y" ]; then diff -u --recursive --new-file v2.1.132/linux/drivers/net/cosa.c linux/drivers/net/cosa.c --- v2.1.132/linux/drivers/net/cosa.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/net/cosa.c Mon Dec 28 11:05:14 1998 @@ -1,4 +1,4 @@ -/* $Id: cosa.c,v 1.9 1998/12/08 02:24:23 kas Exp $ */ +/* $Id: cosa.c,v 1.11 1998/12/24 23:44:23 kas Exp $ */ /* * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak @@ -357,7 +357,7 @@ #endif { int i; - printk(KERN_INFO "cosa v1.02 (c) 1997-8 Jan Kasprzak \n"); + printk(KERN_INFO "cosa v1.03 (c) 1997-8 Jan Kasprzak \n"); #ifdef __SMP__ printk(KERN_INFO "cosa: SMP found. Please mail any success/failure reports to the author.\n"); #endif @@ -995,7 +995,9 @@ get_user_ret(len, &(d->len), -EFAULT); get_user_ret(code, &(d->code), -EFAULT); - if (d->len < 0) + if (d->addr < 0 || d->addr > COSA_MAX_FIRMWARE_SIZE) + return -EINVAL; + if (d->len < 0 || d->len > COSA_MAX_FIRMWARE_SIZE) return -EINVAL; if ((i=download(cosa, d->code, len, addr)) < 0) { @@ -1555,6 +1557,15 @@ * separate functions to make it more readable. These functions are inline, * so there should be no overhead of function call. */ + +/* + * Transmit interrupt routine - called when COSA is willing to obtain + * data from the OS. The most tricky part of the routine is selection + * of channel we (OS) want to send packet for. For SRP we should probably + * use the round-robin approach. The newer COSA firmwares have a simple + * flow-control - in the status word has bits 2 and 3 set to 1 means that the + * channel 0 or 1 doesn't want to receive data. + */ static inline void tx_interrupt(struct cosa_data *cosa, int status) { unsigned long flags, flags1; @@ -1564,16 +1575,24 @@ #endif spin_lock_irqsave(&cosa->lock, flags); set_bit(TXBIT, &cosa->rxtx); - /* - * Using a round-robin algorithm select a first channel that has - * data ready for transmit. - */ if (!test_bit(IRQBIT, &cosa->rxtx)) { + /* flow control */ + int i=0; do { + if (i++ > cosa->nchannels) { + printk(KERN_WARNING + "%s: No channel wants data in TX IRQ\n", + cosa->name); + clear_bit(TXBIT, &cosa->rxtx); + spin_unlock_irqrestore(&cosa->lock, flags); + return; + } cosa->txchan++; if (cosa->txchan >= cosa->nchannels) cosa->txchan = 0; - } while(!(cosa->txbitmap & (1<txchan))); + } while ((!(cosa->txbitmap & (1<txchan))) + || status & (1<<(cosa->txchan+DRIVER_TXMAP_SHIFT))); + cosa->txsize = cosa->chan[cosa->txchan].txsize; if (cosa_dma_able(cosa->chan+cosa->txchan, cosa->chan[cosa->txchan].txbuf, cosa->txsize)) { diff -u --recursive --new-file v2.1.132/linux/drivers/net/cosa.h linux/drivers/net/cosa.h --- v2.1.132/linux/drivers/net/cosa.h Tue Dec 22 14:16:55 1998 +++ linux/drivers/net/cosa.h Mon Dec 28 11:05:14 1998 @@ -1,4 +1,4 @@ -/* $Id: cosa.h,v 1.8 1998/11/09 03:54:49 kas Exp $ */ +/* $Id: cosa.h,v 1.5 1998/12/24 12:40:18 kas Exp $ */ /* * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak @@ -61,7 +61,7 @@ #define SR_START_ADDR 0x4400 /* SRP microcode start address */ #define COSA_LOAD_ADDR 0x400 /* SRP microcode load address */ - +#define COSA_MAX_FIRMWARE_SIZE 0x10000 /* ioctls */ struct cosa_download { diff -u --recursive --new-file v2.1.132/linux/drivers/net/lance.c linux/drivers/net/lance.c --- v2.1.132/linux/drivers/net/lance.c Tue Dec 22 14:16:55 1998 +++ linux/drivers/net/lance.c Mon Dec 28 11:05:14 1998 @@ -303,6 +303,10 @@ static int dma[MAX_CARDS] = { 0, }; static int irq[MAX_CARDS] = { 0, }; +MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i"); +MODULE_PARM(dma, "1-" __MODULE_STRING(MAX_CARDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i"); + static char ifnames[MAX_CARDS][IF_NAMELEN] = { {0, }, }; static struct device dev_lance[MAX_CARDS] = {{ @@ -363,11 +367,12 @@ { int *port, result; - if (high_memory <= 16*1024*1024) + if (high_memory <= phys_to_virt(16*1024*1024)) lance_need_isa_bounce_buffers = 0; #if defined(CONFIG_PCI) - if (pci_present()) { + if (pci_present()) + { struct pci_dev *pdev = NULL; if (lance_debug > 1) printk("lance.c: PCI bios is present, checking for devices...\n"); diff -u --recursive --new-file v2.1.132/linux/drivers/net/sdlamain.c linux/drivers/net/sdlamain.c --- v2.1.132/linux/drivers/net/sdlamain.c Fri Oct 23 22:01:21 1998 +++ linux/drivers/net/sdlamain.c Mon Dec 28 11:05:14 1998 @@ -29,10 +29,6 @@ * Jan 02, 1997 Gene Kozin Initial version. *****************************************************************************/ -#if !defined(__KERNEL__) || !defined(MODULE) -#error This code MUST be compiled as a kernel module! -#endif - #include /* OS configuration options */ #include /* offsetof(), etc. */ #include /* return codes */ @@ -122,7 +118,12 @@ * < 0 error. * Context: process */ + +#ifdef MODULE int init_module (void) +#else +int wanpipe_init(void) +#endif { int cnt, err = 0; @@ -173,6 +174,7 @@ return err; } +#ifdef MODULE /*============================================================================ * Module 'remove' entry point. * o unregister all adapters from the WAN router @@ -189,6 +191,8 @@ } kfree(card_array); } + +#endif /******* WAN Device Driver Entry Points *************************************/ diff -u --recursive --new-file v2.1.132/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c --- v2.1.132/linux/drivers/net/via-rhine.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/net/via-rhine.c Mon Dec 28 11:06:11 1998 @@ -66,6 +66,7 @@ #include #include +#include #include #include #include diff -u --recursive --new-file v2.1.132/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c --- v2.1.132/linux/drivers/pci/oldproc.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/pci/oldproc.c Sun Dec 27 11:01:34 1998 @@ -886,7 +886,7 @@ if (len + 40 > size) { return -1; } - len += sprintf(buf + len, "IRQ %x. ", dev->irq); + len += sprintf(buf + len, "IRQ %d. ", dev->irq); } if (dev->master) { diff -u --recursive --new-file v2.1.132/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c --- v2.1.132/linux/drivers/sbus/char/bpp.c Mon Oct 5 13:13:40 1998 +++ linux/drivers/sbus/char/bpp.c Wed Dec 23 09:44:41 1998 @@ -337,8 +337,8 @@ * responds real good. The first while loop guesses an expire * time accounting for possible wraparound of jiffies. */ - while (extime <= jiffies) extime = jiffies + 1; - while ( (jiffies < extime) + while (time_after_eq(jiffies, extime) extime = jiffies + 1; + while ( (time_before(jiffies, extime)) && (((pins & set) != set) || ((pins & clr) != 0)) ) { pins = get_pins(minor); } diff -u --recursive --new-file v2.1.132/linux/drivers/sbus/char/sab82532.c linux/drivers/sbus/char/sab82532.c --- v2.1.132/linux/drivers/sbus/char/sab82532.c Thu Nov 19 09:56:28 1998 +++ linux/drivers/sbus/char/sab82532.c Wed Dec 23 09:44:41 1998 @@ -1676,7 +1676,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && (orig_jiffies + timeout) < jiffies) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } current->state = TASK_RUNNING; diff -u --recursive --new-file v2.1.132/linux/drivers/sbus/char/su.c linux/drivers/sbus/char/su.c --- v2.1.132/linux/drivers/sbus/char/su.c Thu Nov 19 09:56:28 1998 +++ linux/drivers/sbus/char/su.c Wed Dec 23 09:44:41 1998 @@ -1818,7 +1818,7 @@ schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } current->state = TASK_RUNNING; diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/README.tmscsim linux/drivers/scsi/README.tmscsim --- v2.1.132/linux/drivers/scsi/README.tmscsim Sun Nov 8 14:03:02 1998 +++ linux/drivers/scsi/README.tmscsim Fri Dec 25 16:41:39 1998 @@ -17,6 +17,7 @@ chip. AM53C974 based SCSI adapters include: Tekram DC390, DC390T Dawicontrol 2974 + QLogic Fast! PCI Basic some on-board adapters (This is most probably not a complete list) @@ -44,7 +45,8 @@ 1.12, then 1.20a to 1.20t. Finally I decided to use the ncr53c8xx scheme. So the next revisions will be 2.0a to 2.0X (stable), 2.1a to 2.1X (experimental), 2.2a to 2.2X (stable, again) etc. (X = anything between a and z.) If I send -fixes to people for testing, those will have a digit appended, e.g. 2.0a1. +fixes to people for testing, I create intermediate versions with a digit +appended, e.g. 2.0c3. 2. Installation @@ -55,32 +57,36 @@ support into your kernel or as module when configuring your kernel for compiling. -If you got an older kernel with an old version of this driver included, you -should copy the files (dc390.h, tmscsim.h, tmscsim.c, scsiiom.c and -README.tmscsim) from this directory to linux/drivers/scsi. You have to -recompile your kernel/module of course. - -You should apply the three patches included in dc390-20-kernel.diff -(Applying them: cd /usr/src; patch -p0 <~/dc390-20-kernel.diff) -The patches are against 2.1.103, so you might have to manually resolve -rejections when applying to another kernel version. - -The patches will update the kernel startup code to allow boot parameters to -be passed to the driver, update the Documentation and finally offer you the -possibility to omit the non-DC390 parts of the driver. -(By selecting "Omit support for non DC390" you basically disable the -emulation of a DC390 EEPROM for non DC390 adapters. This saves a few bytes -of memory.) + If you got an old kernel (pre 2.1.127, pre 2.0.37p1) with an old version of + this driver: Get dc390-21125-20b.diff.gz or dc390-2036p21-20b1.diff.gz from + my website and apply the patch. + + If you want to do it manually, you should copy the files (dc390.h, + tmscsim.h, tmscsim.c, scsiiom.c and README.tmscsim) from this directory to + linux/drivers/scsi. You have to recompile your kernel/module of course. + + You should apply the three patches included in dc390-120-kernel.diff + (Applying them: cd /usr/src; patch -p0 <~/dc390-120-kernel.diff) + The patches are against 2.1.125, so you might have to manually resolve + rejections when applying to another kernel version. + + The patches will update the kernel startup code to allow boot parameters to + be passed to the driver, update the Documentation and finally offer you the + possibility to omit the non-DC390 parts of the driver. + (By selecting "Omit support for non DC390" you basically disable the + emulation of a DC390 EEPROM for non DC390 adapters. This saves a few bytes + of memory.) If you got a very old kernel without the tmscsim driver (pre 2.0.31) I recommend upgrading your kernel. However, if you don't want to, please contact me to get the appropriate patches. -Testing a SCSI driver is always a delicate thing to do. The 2.0 driver has + +Upgrading a SCSI driver is always a delicate thing to do. The 2.0 driver has proven stable on many systems, but it's still a good idea to take some precautions. In an ideal world you would have a full backup of your disks. The world isn't ideal and most people don't have full backups (me neither). -So take at least the following two measures: +So take at least the following measures: * make your kernel remount the FS read-only on detecting an error: tune2fs -e remount-ro /dev/sd?? * have copies of your SCSI disk's partition tables on some safe location: @@ -103,18 +109,19 @@ 3.Features ---------- - SCSI - * Tagged queueing + * Tagged command queueing * Sync speed up to 10 MHz * Disconnection * Multiple LUNs - General / Linux interface - * Support for up to 4 adapters. + * Support for up to 4 AM53C974 adapters. * DC390 EEPROM usage or boot/module params * Information via cat /proc/scsi/tmscsim/? * Dynamically configurable by writing to /proc/scsi/tmscsim/? * Dynamic allocation of resources - * SMP support: Adapter specific locks (Linux 2.1.x) + * SMP support: Locking on io_request lock (Linux 2.1/2.2) or adapter + specific locks (Linux 2.3) * Uniform source code for Linux-2.x.y * Support for dyn. addition/removal of devices via add/remove-single-device (Try: echo "scsi add-single-device H C I L" >/proc/scsi/scsi @@ -336,9 +343,7 @@ Further investigation on these problems: -* TagQ and Disconnection (Resel: SRB Tag Seleection) -* Problems with IRQ sharing (IO-APIC on SMP Systems) (??) -* Driver crashes with readcdda (xcdroast) +* Driver hangs with sync readcdda (xcdroast) (most probably VIA PCI error) Known problems: @@ -362,12 +367,9 @@ Richard Waltham or Doug Ledford , if you want to help further debugging it. * 2.0.35: CD changers (e.g. NAKAMICHI MBR-7.{0,2}) have problems because - the mid-level code doesn't handle BLIST_SINGLELUN correctly. Apply - the patch 2035-scsi-singlelun.diff. Thanks to Chiaki Ishikawa. - I was told that this fix will be in 2.0.36, so you don't need it for - 2.0.36. -[The patch file is contained in the dc390-XXX.tar.gz files which can be found -on the ftp server. See below.] + the mid-level code doesn't handle BLIST_SINGLELUN correctly. There used + to be a patch included here to fix this, but I was told that it is fixed + in 2.0.36. 7. Bug reports, debugging and updates @@ -379,7 +381,7 @@ Please append the output of /proc/scsi/scsi, /proc/scsi/tmscsim/? and maybe the DC390 log messages to the report. -Bug reports should be send to me (Kurt Garloff ) as well +Bug reports should be send to me (Kurt Garloff ) as well as to the linux-scsi list (), as sometimes bugs are caused by the SCSI mid-level code. @@ -391,7 +393,10 @@ having your box spending most of its time doing the logging. The latest version of the driver can be found at: -ftp://student.physik.uni-dortmund.de/pub/linux/kernel/dc390/ + http://www.garloff.de/kurt/linux/dc390/ +and + ftp://student.physik.uni-dortmund.de/pub/linux/kernel/dc390/ +(The latter might shut down some day.) 8. Acknowledgements @@ -408,6 +413,6 @@ ------------------------------------------------------------------------- -Written by Kurt Garloff 1998/06/11 -Last updated 1998/10/15, driver revision 2.0b -$Id: README.tmscsim,v 2.4 1998/10/24 08:45:02 garloff Exp $ +Written by Kurt Garloff 1998/06/11 +Last updated 1998/12/25, driver revision 2.0d +$Id: README.tmscsim,v 2.9 1998/12/25 18:04:20 garloff Exp $ diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c --- v2.1.132/linux/drivers/scsi/advansys.c Wed Sep 9 14:51:08 1998 +++ linux/drivers/scsi/advansys.c Wed Dec 23 09:44:41 1998 @@ -5785,8 +5785,8 @@ } scp->result = HOST_BYTE(DID_ERROR); ret = SCSI_RESET_ERROR; - } else if (jiffies >= boardp->last_reset && - jiffies < (boardp->last_reset + (10 * HZ))) { + } else if (time_after_eq(jiffies, boardp->last_reset) && + time_before(jiffies, boardp->last_reset + (10 * HZ))) { /* * Don't allow a reset to be attempted within 10 seconds * of the last reset. diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/dc390.h linux/drivers/scsi/dc390.h --- v2.1.132/linux/drivers/scsi/dc390.h Sun Nov 8 14:03:02 1998 +++ linux/drivers/scsi/dc390.h Mon Dec 28 14:10:17 1998 @@ -4,7 +4,7 @@ * Description: Device Driver for Tekram DC-390(T) PCI SCSI * * Bus Master Host Adapter * ***********************************************************************/ -/* $Id: dc390.h,v 2.3 1998/10/24 08:45:02 garloff Exp $ */ +/* $Id: dc390.h,v 2.12 1998/12/25 17:33:27 garloff Exp $ */ #include @@ -16,7 +16,7 @@ #define DC390_H #define DC390_BANNER "Tekram DC390/AM53C974" -#define DC390_VERSION "2.0b 1998/10/24" +#define DC390_VERSION "2.0d 1998/12/25" #if defined(HOSTS_C) || defined(MODULE) diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c --- v2.1.132/linux/drivers/scsi/g_NCR5380.c Tue Jun 9 11:57:30 1998 +++ linux/drivers/scsi/g_NCR5380.c Sun Dec 27 10:53:45 1998 @@ -495,7 +495,7 @@ dst[start+i] = NCR5380_read(C400_HOST_BUFFER); #else /* implies CONFIG_SCSI_G_NCR5380_MEM */ - memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128); + memcpy(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128); #endif start+=128; blocks--; @@ -516,7 +516,7 @@ dst[start+i] = NCR5380_read(C400_HOST_BUFFER); #else /* implies CONFIG_SCSI_G_NCR5380_MEM */ - memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128); + memcpy(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128); #endif start+=128; blocks--; @@ -603,7 +603,7 @@ NCR5380_write(C400_HOST_BUFFER, src[start+i]); #else /* implies CONFIG_SCSI_G_NCR5380_MEM */ - memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128); + memcpy(NCR53C400_host_buffer+NCR5380_map_name,src+start,128); #endif start+=128; blocks--; @@ -623,7 +623,7 @@ NCR5380_write(C400_HOST_BUFFER, src[start+i]); #else /* implies CONFIG_SCSI_G_NCR5380_MEM */ - memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128); + memcpy(NCR53C400_host_buffer+NCR5380_map_name,src+start,128); #endif start+=128; blocks--; diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c --- v2.1.132/linux/drivers/scsi/gdth.c Wed Sep 9 14:51:08 1998 +++ linux/drivers/scsi/gdth.c Wed Dec 23 09:44:41 1998 @@ -268,7 +268,7 @@ #endif #define PTR2USHORT(a) (ushort)(ulong)(a) -#define JIFFYWAIT(a) {ulong gdtjf;gdtjf=jiffies+(a);while(gdtjf>jiffies);} +#define JIFFYWAIT(a) {ulong gdtjf;gdtjf=jiffies+(a);while(time_before(jiffies,gdtjf));} #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) #define INDEX_OK(i,t) ((i) : : */ + register int d0; + asm("shr $2,%%ecx\n" \ " jz .no_more_bulk_bo\n" \ - " .align 4\n" \ + " .p2align 4,,7\n" \ ".loop_bulk_bo:\n" \ " movl (%%esi),%%ebx\n" \ BYTE_OUT(%%bl) \ @@ -401,19 +403,23 @@ BYTE_OUT(%%bh) \ " addl $4,%%esi\n" \ " loop .loop_bulk_bo\n" \ - " .align 4\n" \ + " .p2align 4,,7\n" \ ".no_more_bulk_bo:" \ - : "=S"(buffer): "c"(len), "d"(base), "S"(buffer):"eax", "ebx", "ecx"); + : "=S"(buffer), "=c"(d0) + : "1"(len), "d"(base), "0"(buffer) + : "eax", "ebx"); asm("andl $3,%%ecx\n" \ " jz .no_more_loose_bo\n" \ - " .align 4\n" \ + " .p2align 4,,7\n" \ ".loop_loose_bo:\n" \ BYTE_OUT((%%esi)) \ " incl %%esi\n" \ " loop .loop_loose_bo\n" \ ".no_more_loose_bo:\n" \ - : /* no output */ : "c"(len), "d"(base), "S"(buffer):"eax", "ebx", "ecx"); + : "=c"(d0) + : "0"(len), "d"(base), "S"(buffer) + : "eax", "ebx"); return 1; /* All went well - we hope! */ } @@ -439,9 +445,11 @@ * In case you are wondering what the last line of the asm does... * : : */ + register int d0; + asm("shr $2,%%ecx\n" \ " jz .no_more_bulk_bi\n" \ - " .align 4\n" \ + " .p2align 4,,7\n" \ ".loop_bulk_bi:\n" \ BYTE_IN(%%bl) \ BYTE_IN(%%bh) \ @@ -452,19 +460,23 @@ " movl %%ebx,(%%esi)\n" \ " addl $4,%%esi\n" \ " loop .loop_bulk_bi\n" \ - " .align 4\n" \ + " .p2align 4,,7\n" \ ".no_more_bulk_bi:" \ - : "=S"(buffer): "c"(len), "d"(base), "S"(buffer):"eax", "ebx", "ecx"); + : "=S"(buffer), "=c"(d0) + : "1"(len), "d"(base), "0"(buffer) + : "eax", "ebx"); asm("andl $3,%%ecx\n" \ " jz .no_more_loose_bi\n" \ - " .align 4\n" \ + " .p2align 4,,7\n" \ ".loop_loose_bi:\n" \ BYTE_IN((%%esi)) \ " incl %%esi\n" \ " loop .loop_loose_bi\n" \ ".no_more_loose_bi:\n" \ - : /* no output */ : "c"(len), "d"(base), "S"(buffer):"eax", "ebx", "ecx"); + : "=c"(d0) + : "0"(len), "d"(base), "S"(buffer) + : "eax", "ebx"); return 1; /* All went well - we hope! */ } @@ -496,9 +508,11 @@ * In case you are wondering what the last line of the asm does... * : : */ + register int d0; + asm("shr $2,%%ecx\n" \ " jz .no_more_bulk_ni\n" \ - " .align 4\n" \ + " .p2align 4,,7\n" \ ".loop_bulk_ni:\n" \ NIBBLE_IN(%%bl) \ NIBBLE_IN(%%bh) \ @@ -509,19 +523,23 @@ " movl %%ebx,(%%esi)\n" \ " addl $4,%%esi\n" \ " loop .loop_bulk_ni\n" \ - " .align 4\n" \ + " .p2align 4,,7\n" \ ".no_more_bulk_ni:" \ - : "=S"(buffer): "c"(len), "d"(str_p), "S"(buffer):"eax", "ebx", "ecx"); + : "=S"(buffer), "=c"(d0) + : "1"(len), "d"(str_p), "0"(buffer) + : "eax", "ebx"); asm("andl $3,%%ecx\n" \ " jz .no_more_loose_ni\n" \ - " .align 4\n" \ + " .p2align 4,,7\n" \ ".loop_loose_ni:\n" \ NIBBLE_IN((%%esi)) \ " incl %%esi\n" \ " loop .loop_loose_ni\n" \ ".no_more_loose_ni:\n" \ - : /* no output */ : "c"(len), "d"(str_p), "S"(buffer):"eax", "ebx", "ecx"); + : "=c"(d0) + : "0"(len), "d"(str_p), "S"(buffer) + : "eax", "ebx"); return 1; /* All went well - we hope! */ } #else /* Old style C routines */ diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c --- v2.1.132/linux/drivers/scsi/scsi_error.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/scsi/scsi_error.c Sun Dec 27 10:18:34 1998 @@ -1182,14 +1182,14 @@ } if (SCpnt->sense_buffer[2] & 0xe0) - return FAILED; + return SUCCESS; switch (SCpnt->sense_buffer[2] & 0xf) { case NO_SENSE: return SUCCESS; case RECOVERED_ERROR: - return SOFT_ERROR; + return /* SOFT_ERROR */ SUCCESS; case ABORTED_COMMAND: return NEEDS_RETRY; @@ -1212,18 +1212,17 @@ case COPY_ABORTED: case VOLUME_OVERFLOW: case MISCOMPARE: + return SUCCESS; case MEDIUM_ERROR: - return FAILED; + return NEEDS_RETRY; case ILLEGAL_REQUEST: - return SUCCESS; - case BLANK_CHECK: case DATA_PROTECT: case HARDWARE_ERROR: default: - return FAILED; + return SUCCESS; } } diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/scsiiom.c linux/drivers/scsi/scsiiom.c --- v2.1.132/linux/drivers/scsi/scsiiom.c Sun Nov 8 14:03:02 1998 +++ linux/drivers/scsi/scsiiom.c Fri Dec 25 16:41:39 1998 @@ -4,7 +4,7 @@ * Description: Device Driver for Tekram DC-390 (T) PCI SCSI * * Bus Master Host Adapter * ***********************************************************************/ -/* $Id: scsiiom.c,v 2.3 1998/10/24 09:10:28 garloff Exp $ */ +/* $Id: scsiiom.c,v 2.15 1998/12/25 17:33:27 garloff Exp $ */ UCHAR dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB ) @@ -36,7 +36,7 @@ DC390_write8 (ScsiFifo, bval); bval1 = SEL_W_ATN; pSRB->SRBState = SRB_START_; - DEBUG1(printk ("DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);) + DEBUG1(printk (KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);) if( pDCB->SyncMode & SYNC_ENABLE ) { if( !(pDCB->IdentifyMsg & 7) || /* LUN == 0 || Cmd != INQUIRY */ @@ -53,21 +53,21 @@ if(pDCB->SyncMode & EN_TAG_QUEUEING) { DC390_write8 (ScsiFifo, MSG_SIMPLE_QTAG); - DEBUG1(printk ("DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN3, pDCB->TagMask);) + DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN3, pDCB->TagMask);) bval = 0; wlval = 1; while (wlval & pDCB->TagMask) { bval++; wlval <<= 1; }; pDCB->TagMask |= wlval; DC390_write8 (ScsiFifo, bval); pSRB->TagNumber = bval; - DEBUG1(printk ("DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);) + DEBUG1(printk (KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);) bval1 = SEL_W_ATN3; pSRB->SRBState = SRB_START_; } else /* No TagQ */ { bval1 = SEL_W_ATN; - DEBUG1(printk ("DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);) + DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);) pSRB->SRBState = SRB_START_; } } @@ -82,7 +82,7 @@ bval &= 0xBF; /* No DisConn */ DC390_write8 (ScsiFifo, bval); bval1 = SEL_W_ATN; - DEBUG1(printk ("DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);) + DEBUG1(printk (KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);) pSRB->SRBState = SRB_START_; /* ??? */ if( pDCB->SyncMode & SYNC_ENABLE ) @@ -101,13 +101,13 @@ if(pDCB->SyncMode & EN_TAG_QUEUEING) { pSRB->MsgOutBuf[0] = MSG_SIMPLE_QTAG; - DEBUG1(printk ("DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN_STOP, pDCB->TagMask);) + DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN_STOP, pDCB->TagMask);) bval = 0; wlval = 1; while (wlval & pDCB->TagMask) { bval++; wlval <<= 1; }; pDCB->TagMask |= wlval; pSRB->TagNumber = bval; - DEBUG1(printk ("DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);) + DEBUG1(printk (KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);) pSRB->MsgOutBuf[1] = bval; pSRB->MsgCnt = 2; bval1 = SEL_W_ATN_STOP; @@ -119,7 +119,7 @@ pSRB->MsgCnt = 1; pSRB->SRBState = SRB_START_; bval1 = SEL_W_ATN_STOP; - DEBUG1(printk ("DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);) + DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);) }; } } @@ -134,7 +134,7 @@ DC390_write8 (ScsiFifo, bval); DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer)); DC390_write8 (ScsiFifo, bval); - DEBUG1(printk ("DC390: AutoReqSense !\n");) + DEBUG1(printk (KERN_DEBUG "DC390: AutoReqSense !\n");) } else /* write cmnd to bus */ { @@ -150,16 +150,16 @@ { pSRB->SRBState = SRB_READY; pDCB->TagMask &= ~( 1 << pSRB->TagNumber ); - DEBUG0(printk ("DC390: Interrupt during StartSCSI!\n");) + DEBUG0(printk (KERN_WARNING "DC390: Interrupt during StartSCSI!\n");) return 1; } else { pSRB->ScsiPhase = SCSI_NOP1; DEBUG0(if (pACB->pActiveDCB) \ - printk ("DC390: ActiveDCB != 0\n");) + printk (KERN_WARNING "DC390: ActiveDCB != 0\n");) DEBUG0(if (pDCB->pActiveSRB) \ - printk ("DC390: ActiveSRB != 0\n");) + printk (KERN_WARNING "DC390: ActiveSRB != 0\n");) pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB; //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); @@ -183,12 +183,10 @@ DEBUG0(PDEVSET1;) DEBUG0(PCI_READ_CONFIG_WORD (PDEV, PCI_STATUS, &pstate);) DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY))\ - { printk("DC390: PCI state = %04x!\n", pstate); \ + { printk(KERN_WARNING "DC390: PCI state = %04x!\n", pstate); \ PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));};) - dstate = DC390_read8 (DMA_Status); - DC390_write8 (DMA_Status, dstate); /* clear */ - //DC390_write8 (DMA_Status, DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT); /* clear */ + dstate = DC390_read8 (DMA_Status); if (! pACB->pActiveDCB || ! pACB->pActiveDCB->pActiveSRB) return dstate; else pSRB = pACB->pActiveDCB->pActiveSRB; @@ -207,12 +205,11 @@ { DEBUG1(printk (KERN_DEBUG "DC390: read residual bytes ... \n");) dstate = DC390_read8 (DMA_Status); - DC390_write8 (DMA_Status, dstate); /* clear */ residual = DC390_read8 (CtcReg_Low) | DC390_read8 (CtcReg_Mid) << 8 | DC390_read8 (CtcReg_High) << 16; residual += DC390_read8 (Current_Fifo) & 0x1f; } while (residual && ! (dstate & SCSI_INTERRUPT) && --ctr); - if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!\n", DC390_read32 (DMA_Wk_ByteCntr)); + if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr)); /* residual = ... */ } else @@ -231,6 +228,7 @@ DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); } + dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24; return dstate; }; #endif @@ -245,14 +243,16 @@ UCHAR phase, i; void (*stateV)( PACB, PSRB, PUCHAR ); UCHAR istate, istatus; +#if DMA_INT UCHAR dstatus; +#endif DC390_AFLAGS DC390_IFLAGS DC390_DFLAGS pACB = dc390_pACB_start; if (pACB == 0) { - printk(KERN_ERR "DC390: Interrupt on uninitialized adapter!\n"); + printk(KERN_WARNING "DC390: Interrupt on uninitialized adapter!\n"); return; } DC390_LOCK_DRV; @@ -275,8 +275,8 @@ DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus);) - if( pACB == (PACB )-1) { DC390_UNLOCK_DRV; return; }; - + if( !pACB ) { DC390_UNLOCK_DRV; return; }; + #if DMA_INT DC390_LOCK_IO; DC390_LOCK_ACB; @@ -284,15 +284,17 @@ DC390_UNLOCK_ACB; DC390_UNLOCK_IO; - DEBUG1(printk ("dstatus=%02x,", dstatus);) + DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus);) if (! (dstatus & SCSI_INTERRUPT)) { - DEBUG0(printk ("DC390 Int w/o SCSI actions (only DMA?)\n");) + DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n");) DC390_UNLOCK_DRV; return; }; #else - dstatus = DC390_read8 (DMA_Status); + //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT); + //dstatus = DC390_read8 (DMA_Status); + //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT); #endif DC390_LOCK_IO; @@ -302,14 +304,15 @@ istate = DC390_read8 (Intern_State); istatus = DC390_read8 (INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */ - DEBUG1(printk ("Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus);) - dc390_laststatus = dstatus<<24 | sstatus<<16 | istate<<8 | istatus; + DEBUG1(printk (KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus);) + dc390_laststatus &= ~0x00ffffff; + dc390_laststatus |= /* dstatus<<24 | */ sstatus<<16 | istate<<8 | istatus; if (sstatus & ILLEGAL_OP_ERR) - { - printk ("DC390: Illegal Operation detected (%08lx)!\n", dc390_laststatus); - dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB); - }; + { + printk ("DC390: Illegal Operation detected (%08lx)!\n", dc390_laststatus); + dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB); + }; if(istatus & DISCONNECTED) { @@ -323,18 +326,6 @@ goto unlock; } - if(istatus & INVALID_CMD) - { - dc390_InvalidCmd( pACB ); - goto unlock; - } - - if(istatus & SCSI_RESET) - { - dc390_ScsiRstDetect( pACB ); - goto unlock; - } - if( istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) ) { pDCB = pACB->pActiveDCB; @@ -345,7 +336,7 @@ }; pSRB = pDCB->pActiveSRB; if( pDCB->DCBFlag & ABORT_DEV_ ) - dc390_EnableMsgOut( pACB, pSRB ); + dc390_EnableMsgOut_Abort (pACB, pSRB); phase = pSRB->ScsiPhase; DEBUG1(printk (KERN_INFO "DC390: [%i]%s(0) (%02x)\n", phase, dc390_p0_str[phase], sstatus);) @@ -357,7 +348,21 @@ DEBUG1(printk (KERN_INFO "DC390: [%i]%s(1) (%02x)\n", phase, dc390_p1_str[phase], sstatus);) stateV = (void *) dc390_phase1[phase]; ( *stateV )( pACB, pSRB, &sstatus ); + goto unlock; } + + if(istatus & INVALID_CMD) + { + dc390_InvalidCmd( pACB ); + goto unlock; + } + + if(istatus & SCSI_RESET) + { + dc390_ScsiRstDetect( pACB ); + goto unlock; + } + unlock: DC390_LOCK_DRV_NI; DC390_UNLOCK_ACB; @@ -380,6 +385,7 @@ UCHAR sstatus; PSGL psgl; ULONG ResidCnt, xferCnt; + UCHAR dstate = 0; sstatus = *psstatus; @@ -391,10 +397,9 @@ if( sstatus & COUNT_2_ZERO ) { int ctr = 5000000; /* only try for about a tenth of a second */ - while( --ctr && !(DC390_read8 (DMA_Status) & DMA_XFER_DONE) && pSRB->SGToBeXferLen ) - DC390_write8 (DMA_Status, DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT); /* clear */ - if (!ctr) printk (KERN_CRIT "DC390: DataOut_0: DMA aborted unfinished: %06x bytes remain!\n", DC390_read32 (DMA_Wk_ByteCntr)); - DC390_write8 (DMA_Status, DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT); /* clear */ + while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen ); + if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr)); + dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24; pSRB->TotalXferredLen += pSRB->SGToBeXferLen; pSRB->SGIndex++; if( pSRB->SGIndex < pSRB->SGcount ) @@ -443,15 +448,14 @@ { int ctr = 5000000; /* only try for about a tenth of a second */ int dstate = 0; - while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen ) - DC390_write8 (DMA_Status, DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT); /* clear */ - if (!ctr) printk (KERN_CRIT "DC390: DataIn_0: DMA aborted unfinished: %06x bytes remain!\n", DC390_read32 (DMA_Wk_ByteCntr)); + while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen ); + if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr)); if (!ctr) printk (KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate); + dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24; DEBUG1(ResidCnt = ((ULONG) DC390_read8 (CtcReg_High) << 16) \ + ((ULONG) DC390_read8 (CtcReg_Mid) << 8) \ + ((ULONG) DC390_read8 (CtcReg_Low));) - DEBUG1(printk ("Count_2_Zero (ResidCnt=%li,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen);) - DC390_write8 (DMA_Status, DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT); /* clear */ + DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%li,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen);) DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */ @@ -474,7 +478,7 @@ bval = DC390_read8 (Current_Fifo); while( bval & 0x1f ) { - DEBUG1(printk ("Check for residuals,");) + DEBUG1(printk (KERN_DEBUG "Check for residuals,");) if( (bval & 0x1f) == 1 ) { for(i=0; i < 0x100; i++) @@ -494,17 +498,18 @@ } din_1: DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_BLAST_CMD); - for (i=0; i<0x8000; i++) + for (i = 0xa000; i; i--) { bval = DC390_read8 (DMA_Status); - DC390_write8 (DMA_Status, BLAST_COMPLETE | DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT); /* clear */ if (bval & BLAST_COMPLETE) break; } - if (i == 0x8000) printk (KERN_CRIT "DC390: DMA Blast aborted unfinished!!\n"); + /* It seems a DMA Blast abort isn't that bad ... */ + if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n"); //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */ + dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24; - DEBUG1(printk ("Blast: Read %i times DMA_Status %02x", i, bval);) + DEBUG1(printk (KERN_DEBUG "Blast: Read %li times DMA_Status %02x", 0xa000-i, bval);) ResidCnt = (ULONG) DC390_read8 (CtcReg_High); ResidCnt <<= 8; ResidCnt |= (ULONG) DC390_read8 (CtcReg_Mid); @@ -525,7 +530,7 @@ pSRB->TotalXferredLen++; pSRB->SGToBeXferLen--; } - DEBUG1(printk ("Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,\ + DEBUG1(printk (KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,\ pSRB->TotalXferredLen, pSRB->SGToBeXferLen);) } @@ -558,164 +563,278 @@ //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); } -void -dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) + +static void __inline__ +dc390_reprog (PACB pACB, PDCB pDCB) { - UCHAR bval; - USHORT wval, wval1; - PDCB pDCB; - PSRB psrb; + DC390_write8 (Sync_Period, pDCB->SyncPeriod); + DC390_write8 (Sync_Offset, pDCB->SyncOffset); + DC390_write8 (CtrlReg3, pDCB->CtrlR3); + DC390_write8 (CtrlReg4, pDCB->CtrlR4); + dc390_SetXferRate (pACB, pDCB); +}; - pDCB = pACB->pActiveDCB; - bval = DC390_read8 (ScsiFifo); - if( !(pSRB->SRBState & SRB_MSGIN_MULTI) ) +#ifdef DC390_DEBUG0 +static void +dc390_printMsg (UCHAR *MsgBuf, UCHAR len) +{ + int i; + printk (" %02x", MsgBuf[0]); + for (i = 1; i < len; i++) + printk (" %02x", MsgBuf[i]); + printk ("\n"); +}; +#endif + +#define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD) + +/* reject_msg */ +static void __inline__ +dc390_MsgIn_reject (PACB pACB, PSRB pSRB) +{ + pSRB->MsgOutBuf[0] = MSG_REJECT_; + pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT; + DEBUG0 (printk (KERN_INFO "DC390: Reject message\n");) +} + +/* abort command */ +static void __inline__ +dc390_EnableMsgOut_Abort ( PACB pACB, PSRB pSRB ) +{ + pSRB->MsgOutBuf[0] = MSG_ABORT; + pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT; + pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_; +} + +static PSRB +dc390_MsgIn_QTag (PACB pACB, PDCB pDCB, UCHAR tag) +{ + PSRB lastSRB = pDCB->pGoingLast; + PSRB pSRB = pDCB->pGoingSRB; + + if (pSRB) { - if(bval == MSG_DISCONNECT) - { - pSRB->SRBState = SRB_DISCONNECT; - } - else if( bval == MSG_SAVE_PTR ) - goto min6; - else if( (bval == MSG_EXTENDED) || ((bval >= MSG_SIMPLE_QTAG) && - (bval <= MSG_ORDER_QTAG)) ) + for( ;pSRB ; ) { - pSRB->SRBState |= SRB_MSGIN_MULTI; - pSRB->MsgInBuf[0] = bval; - pSRB->MsgCnt = 1; - pSRB->pMsgPtr = &(pSRB->MsgInBuf[1]); + if (pSRB->TagNumber == tag) break; + if (pSRB == lastSRB) goto mingx0; + pSRB = pSRB->pNextSRB; } - else if(bval == MSG_REJECT_) + + if( pDCB->DCBFlag & ABORT_DEV_ ) { - DC390_write8 (ScsiCmd, RESET_ATN_CMD); - pDCB->NegoPeriod = 50; - if( pSRB->SRBState & DO_SYNC_NEGO) - goto set_async; + pSRB->SRBState = SRB_ABORT_SENT; + dc390_EnableMsgOut_Abort( pACB, pSRB ); } - else if( bval == MSG_RESTORE_PTR) - goto min6; - else - goto min6; + + if( !(pSRB->SRBState & SRB_DISCONNECT) ) + goto mingx0; + + pDCB->pActiveSRB = pSRB; + pSRB->SRBState = SRB_DATA_XFER; } - else - { /* minx: */ + else + { + mingx0: + pSRB = pACB->pTmpSRB; + pSRB->SRBState = SRB_UNEXPECT_RESEL; + pDCB->pActiveSRB = pSRB; + pSRB->MsgOutBuf[0] = MSG_ABORT_TAG; + pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT; + } + return pSRB; +} - *pSRB->pMsgPtr = bval; - pSRB->MsgCnt++; - pSRB->pMsgPtr++; - if( (pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG) && - (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG) ) - { - if( pSRB->MsgCnt == 2) - { - pSRB->SRBState = 0; - bval = pSRB->MsgInBuf[1]; - pSRB = pDCB->pGoingSRB; - psrb = pDCB->pGoingLast; - if( pSRB ) - { - for( ;pSRB ; ) - { - if(pSRB->TagNumber != bval) - { - if( pSRB == psrb ) - goto mingx0; - pSRB = pSRB->pNextSRB; - } - else - break; - } - if( pDCB->DCBFlag & ABORT_DEV_ ) - { - pSRB->SRBState = SRB_ABORT_SENT; - dc390_EnableMsgOut( pACB, pSRB ); - } - if( !(pSRB->SRBState & SRB_DISCONNECT) ) - goto mingx0; - pDCB->pActiveSRB = pSRB; - pSRB->SRBState = SRB_DATA_XFER; - } - else - { -mingx0: - pSRB = pACB->pTmpSRB; - pSRB->SRBState = SRB_UNEXPECT_RESEL; - pDCB->pActiveSRB = pSRB; - pSRB->MsgOutBuf[0] = MSG_ABORT_TAG; - dc390_EnableMsgOut2( pACB, pSRB ); - } - } - } - else if( (pSRB->MsgInBuf[0] == MSG_EXTENDED) && (pSRB->MsgCnt == 5) ) - { /* Note: This will fail for target initiated SDTR ? */ - pSRB->SRBState &= ~(SRB_MSGIN_MULTI); - if( (pSRB->MsgInBuf[1] != 3) || (pSRB->MsgInBuf[2] != EXTENDED_SDTR) ) - { /* reject_msg: */ - pSRB->MsgCnt = 1; - pSRB->MsgInBuf[0] = MSG_REJECT_; - DC390_write8 (ScsiCmd, SET_ATN_CMD); - } - else if( !(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4]) ) - { -set_async: - pDCB = pSRB->pSRBDCB; - if (!(pSRB->SRBState & DO_SYNC_NEGO)) - printk ("DC390: Target (%i,%i) initiates Non-Sync?\n", pDCB->UnitSCSIID, pDCB->UnitSCSILUN); - pSRB->SRBState &= ~DO_SYNC_NEGO; - pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE); - pDCB->SyncPeriod = 0; - pDCB->SyncOffset = 0; - pDCB->CtrlR3 = FAST_CLK; /* fast clock / normal scsi */ - pDCB->CtrlR4 &= 0x3f; - pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */ - goto re_prog; - } - else - { /* set_sync: */ - pDCB = pSRB->pSRBDCB; - if (!(pSRB->SRBState & DO_SYNC_NEGO)) - printk ("DC390: Target (%i,%i) initiates Sync: %ins %i ?\n", - pDCB->UnitSCSIID, pDCB->UnitSCSILUN, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]); - pSRB->SRBState &= ~DO_SYNC_NEGO; - pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE; - pDCB->SyncOffset &= 0x0f0; - pDCB->SyncOffset |= pSRB->MsgInBuf[4]; - pDCB->NegoPeriod = pSRB->MsgInBuf[3]; - wval = (USHORT) pSRB->MsgInBuf[3]; - wval = wval << 2; wval -= 3; wval1 = wval / 25; /* compute speed */ - if( (wval1 * 25) != wval) - wval1++; - bval = FAST_CLK+FAST_SCSI; /* fast clock / fast scsi */ - pDCB->CtrlR4 &= 0x3f; /* Glitch eater: 12ns less than normal */ - if (pACB->glitch_cfg != NS_TO_GLITCH(0)) - pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1)); - else - pDCB->CtrlR4 |= NS_TO_GLITCH(0); - if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */ - if (wval1 >= 8) - { - wval1--; /* Timing computation differs by 1 from FAST_SCSI */ - bval = FAST_CLK; /* fast clock / normal scsi */ - pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */ - } - pDCB->CtrlR3 = bval; - pDCB->SyncPeriod = (UCHAR)wval1; -re_prog: - DC390_write8 (Sync_Period, pDCB->SyncPeriod); - DC390_write8 (Sync_Offset, pDCB->SyncOffset); - DC390_write8 (CtrlReg3, pDCB->CtrlR3); - DC390_write8 (CtrlReg4, pDCB->CtrlR4); - dc390_SetXferRate (pACB, pDCB); - } +/* set async transfer mode */ +static void +dc390_MsgIn_set_async (PACB pACB, PSRB pSRB) +{ + PDCB pDCB = pSRB->pSRBDCB; + if (!(pSRB->SRBState & DO_SYNC_NEGO)) + printk ("DC390: Target %i initiates Non-Sync?\n", pDCB->UnitSCSIID); + pSRB->SRBState &= ~DO_SYNC_NEGO; + pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE); + pDCB->SyncPeriod = 0; + pDCB->SyncOffset = 0; + //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */ + pDCB->CtrlR3 = FAST_CLK; /* fast clock / normal scsi */ + pDCB->CtrlR4 &= 0x3f; + pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */ + dc390_reprog (pACB, pDCB); +} + +/* set sync transfer mode */ +static void +dc390_MsgIn_set_sync (PACB pACB, PSRB pSRB) +{ + UCHAR bval; + USHORT wval, wval1; + PDCB pDCB = pSRB->pSRBDCB; + UCHAR oldsyncperiod = pDCB->SyncPeriod; + UCHAR oldsyncoffset = pDCB->SyncOffset; + + if (!(pSRB->SRBState & DO_SYNC_NEGO)) + { + printk ("DC390: Target %i initiates Sync: %ins %i ... answer ...\n", + pDCB->UnitSCSIID, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]); + + /* reject */ + //dc390_MsgIn_reject (pACB, pSRB); + //return dc390_MsgIn_set_async (pACB, pSRB); + + /* Reply with corrected SDTR Message */ + if (pSRB->MsgInBuf[4] > 15) + { + printk ("DC390: Lower Sync Offset to 15\n"); + pSRB->MsgInBuf[4] = 15; } + if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod) + { + printk ("DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2); + pSRB->MsgInBuf[3] = pDCB->NegoPeriod; + }; + memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5); + pSRB->MsgCnt = 5; + DC390_ENABLE_MSGOUT; + }; + + pSRB->SRBState &= ~DO_SYNC_NEGO; + pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE; + pDCB->SyncOffset &= 0x0f0; + pDCB->SyncOffset |= pSRB->MsgInBuf[4]; + pDCB->NegoPeriod = pSRB->MsgInBuf[3]; + + wval = (USHORT) pSRB->MsgInBuf[3]; + wval = wval << 2; wval -= 3; wval1 = wval / 25; /* compute speed */ + if( (wval1 * 25) != wval) wval1++; + bval = FAST_CLK+FAST_SCSI; /* fast clock / fast scsi */ + + pDCB->CtrlR4 &= 0x3f; /* Glitch eater: 12ns less than normal */ + if (pACB->glitch_cfg != NS_TO_GLITCH(0)) + pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1)); + else + pDCB->CtrlR4 |= NS_TO_GLITCH(0); + if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */ + + if (wval1 >= 8) + { + wval1--; /* Timing computation differs by 1 from FAST_SCSI */ + bval = FAST_CLK; /* fast clock / normal scsi */ + pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */ } -min6: + + pDCB->CtrlR3 = bval; + pDCB->SyncPeriod = (UCHAR)wval1; + + if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->UnitSCSILUN == 0) + { + if (! (bval & FAST_SCSI)) wval1++; + printk ("DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->UnitSCSIID, + 40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f); + } + + dc390_reprog (pACB, pDCB); +}; + + +/* According to the docs, the AM53C974 reads the message and + * generates a Succesful Operation IRQ before asserting ACK for + * the last byte (how does it know whether it's the last ?) */ +/* The old code handled it in another way, indicating, that on + * every message byte an IRQ is generated and every byte has to + * be manually ACKed. Hmmm ? (KG, 98/11/28) */ +/* The old implementation was correct. Sigh! */ + +/* Check if the message is complete */ +static UCHAR __inline__ +dc390_MsgIn_complete (UCHAR *msgbuf, ULONG len) +{ + if (*msgbuf == MSG_EXTENDED) + { + if (len < 2) return 0; + if (len < msgbuf[1] + 2) return 0; + } + else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f) // two byte messages + if (len < 2) return 0; + return 1; +} + + + +/* read and eval received messages */ +void +dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) +{ + PDCB pDCB = pACB->pActiveDCB; + + /* Read the msg */ + + pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8 (ScsiFifo); + //pSRB->SRBState = 0; + + /* Msg complete ? */ + if (dc390_MsgIn_complete (pSRB->MsgInBuf, pACB->MsgLen)) + { + DEBUG0 (printk (KERN_INFO "DC390: MsgIn:"); dc390_printMsg (pSRB->MsgInBuf, pACB->MsgLen);) + /* Now eval the msg */ + switch (pSRB->MsgInBuf[0]) + { + case MSG_DISCONNECT: + pSRB->SRBState = SRB_DISCONNECT; break; + + case MSG_SIMPLE_QTAG: + case MSG_HEAD_QTAG: + case MSG_ORDER_QTAG: + pSRB = dc390_MsgIn_QTag (pACB, pDCB, pSRB->MsgInBuf[1]); + break; + + case MSG_REJECT_: + DC390_write8 (ScsiCmd, RESET_ATN_CMD); + pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */ + if( pSRB->SRBState & DO_SYNC_NEGO) + dc390_MsgIn_set_async (pACB, pSRB); + break; + + case MSG_EXTENDED: + /* reject every extended msg but SDTR */ + if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR) + dc390_MsgIn_reject (pACB, pSRB); + else + { + if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0) + dc390_MsgIn_set_async (pACB, pSRB); + else + dc390_MsgIn_set_sync (pACB, pSRB); + }; + + // nothing has to be done + case MSG_COMPLETE: break; + + // SAVE POINTER my be ignored as we have the PSRB associated with the + // scsi command. Thanks, Gerard, for pointing it out. + case MSG_SAVE_PTR: break; + // The device might want to restart transfer with a RESTORE + case MSG_RESTORE_PTR: + printk ("DC390: RESTORE POINTER message received ... reject\n"); + // fall through + + // reject unknown messages + default: dc390_MsgIn_reject (pACB, pSRB); + } + + /* Clear counter and MsgIn state */ + pSRB->SRBState &= ~SRB_MSGIN; + pACB->MsgLen = 0; + }; + *psstatus = SCSI_NOP0; DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD); //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); } + void dc390_DataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir) { @@ -730,10 +849,10 @@ psgl = pSRB->pSegmentList; pSRB->SGBusAddr = virt_to_bus( psgl->address ); pSRB->SGToBeXferLen = (ULONG) psgl->length; - DEBUG1(printk (" DC390: Next SG segment.");) + DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment.");) } lval = pSRB->SGToBeXferLen; - DEBUG1(printk (" DC390: Transfer %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr);) + DEBUG1(printk (KERN_DEBUG " DC390: Transfer %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr);) DC390_write8 (CtcReg_Low, (UCHAR) lval); lval >>= 8; DC390_write8 (CtcReg_Mid, (UCHAR) lval); @@ -749,21 +868,22 @@ DC390_write8 (ScsiCmd, DMA_COMMAND+INFO_XFER_CMD); DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT); - //DEBUG1(printk ("DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status));) + //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);) + //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status));) + //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);) } else /* xfer pad */ { - UCHAR bval = 0; if( pSRB->SGcount ) { pSRB->AdaptStatus = H_OVER_UNDER_RUN; pSRB->SRBStatus |= OVER_RUN; - DEBUG0(printk (" DC390: Overrun -");) + DEBUG0(printk (KERN_WARNING " DC390: Overrun -");) } - DEBUG0(printk (" Clear transfer pad \n");) - DC390_write8 (CtcReg_Low, bval); - DC390_write8 (CtcReg_Mid, bval); - DC390_write8 (CtcReg_High, bval); + DEBUG0(printk (KERN_WARNING " Clear transfer pad \n");) + DC390_write8 (CtcReg_Low, 0); + DC390_write8 (CtcReg_Mid, 0); + DC390_write8 (CtcReg_High, 0); pSRB->SRBState |= SRB_XFERPAD; DC390_write8 (ScsiCmd, DMA_COMMAND+XFER_PAD_BYTE); @@ -1017,7 +1137,7 @@ dc390_SRBdone( pACB, pDCB, pSRB); } } - return; + pACB->MsgLen = 0; } @@ -1032,7 +1152,7 @@ DEBUG0(printk(KERN_INFO "RSEL,");) pDCB = pACB->pActiveDCB; if( pDCB ) - { /* Arbitration lost but Reselection win */ + { /* Arbitration lost but Reselection won */ DEBUG0(printk ("(ActiveDCB != 0)");) pSRB = pDCB->pActiveSRB; if( !( pACB->scan_devices ) ) @@ -1075,23 +1195,23 @@ printk (KERN_ERR "DC390: Reselect without outstanding cmnd (ID %02x, LUN %02x)\n", wval & 0xff, (wval & 0xff00) >> 8); pDCB->pActiveSRB = pSRB; - dc390_EnableMsgOut( pACB, pSRB ); + dc390_EnableMsgOut_Abort ( pACB, pSRB ); } else { if( pDCB->DCBFlag & ABORT_DEV_ ) { pSRB->SRBState = SRB_ABORT_SENT; - printk (KERN_NOTICE "DC390: Reselect: Abort (ID %02x, LUN %02x)\n", + printk (KERN_INFO "DC390: Reselect: Abort (ID %02x, LUN %02x)\n", wval & 0xff, (wval & 0xff00) >> 8); - dc390_EnableMsgOut( pACB, pSRB ); + dc390_EnableMsgOut_Abort( pACB, pSRB ); } else pSRB->SRBState = SRB_DATA_XFER; } } - DEBUG1(printk ("Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber);) + DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber);) pSRB->ScsiPhase = SCSI_NOP0; DC390_write8 (Scsi_Dest_ID, pDCB->UnitSCSIID); DC390_write8 (Sync_Period, pDCB->SyncPeriod); @@ -1244,7 +1364,7 @@ else pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) | SCSI_STAT_CHECKCOND; - REMOVABLEDEBUG(printk("Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB->CmdBlock[0],\ + REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB->CmdBlock[0],\ (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);) goto ckc_e; } @@ -1260,7 +1380,7 @@ { pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) | SCSI_STAT_CHECKCOND; - REMOVABLEDEBUG(printk("Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->CmdBlock[0],\ + REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->CmdBlock[0],\ (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);) goto ckc_e; } @@ -1299,7 +1419,7 @@ swlval += ptr2->length; ptr2++; } - REMOVABLEDEBUG(printk("XferredLen=%08x,NotXferLen=%08x\n",\ + REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08x\n",\ (UINT) pSRB->TotalXferredLen, (UINT) swlval);) } dc390_RequestSense( pACB, pDCB, pSRB ); @@ -1586,22 +1706,6 @@ dc390_RewaitSRB( pDCB, pSRB ); } - -static void __inline__ -dc390_EnableMsgOut2( PACB pACB, PSRB pSRB ) -{ - pSRB->MsgCnt = 1; - DC390_write8 (ScsiCmd, SET_ATN_CMD); -} - - -static void __inline__ -dc390_EnableMsgOut( PACB pACB, PSRB pSRB ) -{ - pSRB->MsgOutBuf[0] = MSG_ABORT; - dc390_EnableMsgOut2( pACB, pSRB ); - pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_; -} static void __inline__ diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/st.c linux/drivers/scsi/st.c --- v2.1.132/linux/drivers/scsi/st.c Mon Sep 28 10:51:34 1998 +++ linux/drivers/scsi/st.c Sun Dec 27 10:18:55 1998 @@ -11,7 +11,7 @@ Copyright 1992 - 1998 Kai Makisara email Kai.Makisara@metla.fi - Last modified: Sun Sep 6 09:34:49 1998 by root@home + Last modified: Thu Dec 3 20:27:46 1998 by makisara@home Some small formal changes - aeb, 950809 */ @@ -707,7 +707,7 @@ STp->density = 0; /* Clear the erroneous "residue" */ STp->write_prot = 0; STp->block_size = 0; - STp->ps[0].drv_file = STp->ps[0].drv_block = 0; + STp->ps[0].drv_file = STp->ps[0].drv_block = (-1); STp->partition = STp->new_partition = 0; STp->door_locked = ST_UNLOCKED; STp->in_use = 1; @@ -785,6 +785,7 @@ !enlarge_buffer(STp->buffer, STp->block_size, STp->restr_dma)) { printk(KERN_NOTICE "st%d: Blocksize %d too large for buffer.\n", dev, STp->block_size); + scsi_release_command(SCpnt); (STp->buffer)->in_use = 0; STp->buffer = NULL; if (scsi_tapes[dev].device->host->hostt->module) @@ -3414,8 +3415,8 @@ STps->eof = ST_NOEOF; STps->at_sm = 0; STps->last_block_valid = FALSE; - STps->drv_block = 0; - STps->drv_file = 0; + STps->drv_block = (-1); + STps->drv_file = (-1); } tpnt->current_mode = 0; diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/tmscsim.c linux/drivers/scsi/tmscsim.c --- v2.1.132/linux/drivers/scsi/tmscsim.c Sun Nov 8 14:03:02 1998 +++ linux/drivers/scsi/tmscsim.c Fri Dec 25 16:41:39 1998 @@ -5,9 +5,11 @@ * Bus Master Host Adapter * * (C)Copyright 1995-1996 Tekram Technology Co., Ltd. * ***********************************************************************/ -/* $Id: tmscsim.c,v 2.4 1998/10/24 08:50:47 garloff Exp $ */ +/* (C) Copyright: put under GNU GPL in 10/96 * +*************************************************************************/ +/* $Id: tmscsim.c,v 2.16 1998/12/25 17:54:44 garloff Exp $ */ /* Enhancements and bugfixes by * - * Kurt Garloff * + * Kurt Garloff * ***********************************************************************/ /* HISTORY: * * * @@ -90,6 +92,11 @@ * bios_param() now respects part. table. * * 2.0b 98/10/24 KG Docu fixes. Timeout Msg in DMA Blast. * * Disallow illegal idx in INQUIRY/REMOVE * + * 2.0c 98/11/19 KG Cleaned up detect/init for SMP boxes, * + * Write Erase DMA (1.20t) caused problems * + * 2.0d 98/12/25 KG Christmas release ;-) Message handling * + * competely reworked. Handle target ini- * + * tiated SDTR correctly. * ***********************************************************************/ /* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */ @@ -206,9 +213,9 @@ # if USE_SPINLOCKS == 3 /* both */ # if defined (__SMP__) || DEBUG_SPINLOCKS > 0 -# define DC390_LOCK_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; }; +# define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; }; # else -# define DC390_LOCK_INIT +# define DC390_LOCKA_INIT # endif spinlock_t dc390_drvlock = SPIN_LOCK_UNLOCKED; @@ -228,16 +235,16 @@ # define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags) # define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock)) # define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock)) -//# define DC390_LOCK_INIT spin_lock_init (&(pACB->lock)) +//# define DC390_LOCKA_INIT spin_lock_init (&(pACB->lock)) # else # if USE_SPINLOCKS == 2 /* adapter specific locks */ # if defined (__SMP__) || DEBUG_SPINLOCKS > 0 -# define DC390_LOCK_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; }; +# define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; }; # else -# define DC390_LOCK_INIT +# define DC390_LOCKA_INIT # endif spinlock_t dc390_drvlock = SPIN_LOCK_UNLOCKED; # define DC390_AFLAGS unsigned long aflags; @@ -253,7 +260,7 @@ # define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags) # define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock)) # define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock)) -//# define DC390_LOCK_INIT spin_lock_init (&(pACB->lock)) +//# define DC390_LOCKA_INIT spin_lock_init (&(pACB->lock)) # else /* USE_SPINLOCKS == 1: global lock io_request_lock */ @@ -271,7 +278,7 @@ # define DC390_UNLOCK_ACB /* DC390_UNLOCK_IO */ # define DC390_LOCK_ACB_NI /* spin_lock (&(pACB->lock)) */ # define DC390_UNLOCK_ACB_NI /* spin_unlock (&(pACB->lock)) */ -# define DC390_LOCK_INIT /* DC390_LOCK_INIT */ +# define DC390_LOCKA_INIT /* DC390_LOCKA_INIT */ # endif /* 2 */ # endif /* 3 */ @@ -291,7 +298,7 @@ # define DC390_UNLOCK_ACB restore_flags (aflags) # define DC390_LOCK_ACB_NI # define DC390_UNLOCK_ACB_NI -# define DC390_LOCK_INIT +# define DC390_LOCKA_INIT #endif /* def */ @@ -365,9 +372,8 @@ static void dc390_ScsiRstDetect( PACB pACB ); static void dc390_ResetSCSIBus( PACB pACB ); static void __inline__ dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB ); -static void __inline__ dc390_EnableMsgOut2( PACB pACB, PSRB pSRB ); -static void __inline__ dc390_EnableMsgOut( PACB pACB, PSRB pSRB ); static void __inline__ dc390_InvalidCmd( PACB pACB ); +static void __inline__ dc390_EnableMsgOut_Abort (PACB, PSRB); static void dc390_remove_dev (PACB pACB, PDCB pDCB); void do_DC390_Interrupt( int, void *, struct pt_regs *); @@ -481,9 +487,190 @@ S_IFDIR | S_IRUGO | S_IXUGO, 2 }; + /*********************************************************************** + * Functions for access to DC390 EEPROM + * and some to emulate it * - * + **********************************************************************/ + + +static void __init dc390_EnDisableCE( UCHAR mode, PDEVDECL, PUCHAR regval ) +{ + UCHAR bval; + + bval = 0; + if(mode == ENABLE_CE) + *regval = 0xc0; + else + *regval = 0x80; + PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); + if(mode == DISABLE_CE) + PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); + udelay(160); +} + +#ifndef CONFIG_SCSI_DC390T_NOGENSUPP +static void __init dc390_EEpromDefaults (UCHAR index) +{ + PUCHAR ptr; + UCHAR id; + ptr = (PUCHAR) dc390_eepromBuf[index]; + + /* Adapter Settings */ + ptr[EE_ADAPT_SCSI_ID] = (UCHAR)tmscsim[0]; /* Adapter ID */ + ptr[EE_MODE2] = (UCHAR)tmscsim[3]; + ptr[EE_DELAY] = 0; /* ?? */ + ptr[EE_TAG_CMD_NUM] = (UCHAR)tmscsim[4]; /* Tagged Comds */ + + /* Device Settings */ + for (id = 0; id < MAX_SCSI_ID; id++) + { + ptr[id<<2] = (UCHAR)tmscsim[2]; /* EE_MODE1 */ + ptr[(id<<2) + 1] = (UCHAR)tmscsim[1]; /* EE_Speed */ + }; + dc390_adapname = "AM53C974"; +} + +static void __init dc390_checkparams (void) +{ + PARSEDEBUG(printk(KERN_INFO "DC390: setup %08x %08x %08x %08x %08x\n", tmscsim[0],\ + tmscsim[1], tmscsim[2], tmscsim[3], tmscsim[4]);) + if (tmscsim[0] < 0 || tmscsim[0] > 7) /* modules-2.0.0 passes -1 as string */ + { + tmscsim[0] = 7; tmscsim[1] = 4; + tmscsim[2] = 9; tmscsim[3] = 15; + tmscsim[4] = 2; + printk (KERN_INFO "DC390: Using safe settings.\n"); + } + else + { + /* if (tmscsim[0] < 0 || tmscsim[0] > 7) tmscsim[0] = 7; */ + if (tmscsim[1] < 0 || tmscsim[1] > 7) tmscsim[1] = 4; + if (tmscsim[4] < 0 || tmscsim[4] > 5) tmscsim[4] = 4; + }; +}; +/* Override defaults on cmdline: + * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped) + */ +void __init dc390_setup (char *str, int *ints) +{ + int i; + for (i = 0; i < ints[0]; i++) + tmscsim[i] = ints[i+1]; + if (ints[0] > 5) + printk (KERN_NOTICE "DC390: ignore extra params!\n"); + /* dc390_checkparams (); */ +}; +#endif /* CONFIG_SCSI_DC390T_NOGENSUPP */ + + +static void __init dc390_EEpromOutDI( PDEVDECL, PUCHAR regval, UCHAR Carry ) +{ + UCHAR bval; + + bval = 0; + if(Carry) + { + bval = 0x40; + *regval = 0x80; + PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); + } + udelay(160); + bval |= 0x80; + PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); + udelay(160); + bval = 0; + PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); + udelay(160); +} + + +static UCHAR __init dc390_EEpromInDO( PDEVDECL ) +{ + UCHAR bval; + + PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x80); + udelay(160); + PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x40); + udelay(160); + PCI_READ_CONFIG_BYTE(PDEV, 0x00, &bval); + if(bval == 0x22) + return(1); + else + return(0); +} + + +static USHORT __init dc390_EEpromGetData1( PDEVDECL ) +{ + UCHAR i; + UCHAR carryFlag; + USHORT wval; + + wval = 0; + for(i=0; i<16; i++) + { + wval <<= 1; + carryFlag = dc390_EEpromInDO(PDEV); + wval |= carryFlag; + } + return(wval); +} + + +static void __init dc390_Prepare( PDEVDECL, PUCHAR regval, UCHAR EEpromCmd ) +{ + UCHAR i,j; + UCHAR carryFlag; + + carryFlag = 1; + j = 0x80; + for(i=0; i<9; i++) + { + dc390_EEpromOutDI(PDEV,regval,carryFlag); + carryFlag = (EEpromCmd & j) ? 1 : 0; + j >>= 1; + } +} + + +static void __init dc390_ReadEEprom( PDEVDECL, PUSHORT ptr) +{ + UCHAR regval,cmd; + UCHAR i; + + cmd = EEPROM_READ; + for(i=0; i<0x40; i++) + { + dc390_EnDisableCE(ENABLE_CE, PDEV, ®val); + dc390_Prepare(PDEV, ®val, cmd++); + *ptr++ = dc390_EEpromGetData1(PDEV); + dc390_EnDisableCE(DISABLE_CE, PDEV, ®val); + } +} + + +static UCHAR __init dc390_CheckEEpromCheckSum( PDEVDECL, UCHAR index ) +{ + UCHAR i; + char EEbuf[128]; + USHORT wval, *ptr = (PUSHORT)EEbuf; + + dc390_ReadEEprom( PDEV, ptr ); + memcpy (dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID); + memcpy (&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID], + &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID); + wval = 0; + for(i=0; i<0x40; i++, ptr++) + wval += *ptr; + return (wval == 0x1234 ? 0 : 1); +} + + +/*********************************************************************** + * Functions for the management of the internal structures + * (DCBs, SRBs, Queueing) * **********************************************************************/ static PDCB __inline__ dc390_findDCB ( PACB pACB, Scsi_Cmnd *cmd) @@ -494,7 +681,7 @@ pDCB = pDCB->pNextDCB; if (pDCB == pACB->pLinkDCB) { - printk (KERN_ERR "DC390: DCB not found (DCB=%08x, DCBmap[%2x]=%2x)\n", + printk (KERN_WARNING "DC390: DCB not found (DCB=%08x, DCBmap[%2x]=%2x)\n", (int)pDCB, cmd->target, pACB->DCBmap[cmd->target]); return 0; } @@ -578,7 +765,7 @@ UCHAR bval; pDCB->GoingSRBCnt--; pDCB->pDCBACB->SelLost++; - DEBUG0(printk("DC390: RewaitSRB (%p, %p) pid = %li\n", pDCB, pSRB, pSRB->pcmd->pid);) + DEBUG0(printk(KERN_INFO "DC390: RewaitSRB (%p, %p) pid = %li\n", pDCB, pSRB, pSRB->pcmd->pid);) psrb1 = pDCB->pGoingSRB; if( pSRB == psrb1 ) { @@ -678,6 +865,13 @@ } +/*********************************************************************** + * Function: static void dc390_SendSRB (PACB pACB, PSRB pSRB) + * + * Purpose: Send SCSI Request Block (pSRB) to adapter (pACB) + * + ***********************************************************************/ + static void dc390_SendSRB( PACB pACB, PSRB pSRB ) { PDCB pDCB; @@ -720,6 +914,14 @@ return; } +/*********************************************************************** + * Function: static void dc390_BuildSRB (Scsi_Cmd *pcmd, PDCB pDCB, + * PSRB pSRB) + * + * Purpose: Prepare SRB for being sent to Device DCB w/ command *pcmd + * + ***********************************************************************/ + static void dc390_BuildSRB (Scsi_Cmnd* pcmd, PDCB pDCB, PSRB pSRB) { pSRB->pSRBDCB = pDCB; @@ -790,7 +992,7 @@ DEBUG0(/* if(pACB->scan_devices) */ \ - printk(KERN_DEBUG "DC390: Queue Cmd=%02x,ID=%d,LUN=%d (pid=%li)\n",\ + printk(KERN_INFO "DC390: Queue Cmd=%02x,ID=%d,LUN=%d (pid=%li)\n",\ cmd->cmnd[0],cmd->target,cmd->lun,cmd->pid);) DC390_LOCK_ACB; @@ -1056,15 +1258,17 @@ printk (" %02x %02x %02x %02x %02x %02x\n", DC390_read8(INT_Status), DC390_read8(Current_Fifo), DC390_read8(CtrlReg1), DC390_read8(CtrlReg2), DC390_read8(CtrlReg3), DC390_read8(CtrlReg4)); + DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT); printk ("DC390: Register dump: DMA engine:\n"); printk ("DC390: Cmd STrCnt SBusA WrkBC WrkAC Stat SBusCtrl\n"); printk ("DC390: %02x %08x %08x %08x %08x %02x %08x\n", DC390_read8(DMA_Cmd), DC390_read32(DMA_XferCnt), DC390_read32(DMA_XferAddr), DC390_read32(DMA_Wk_ByteCntr), DC390_read32(DMA_Wk_AddrCntr), DC390_read8(DMA_Status), DC390_read32(DMA_ScsiBusCtrl)); + DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT); PDEVSET1; PCI_READ_CONFIG_WORD(PDEV, PCI_STATUS, &pstat); printk ("DC390: Register dump: PCI Status: %04x\n", pstat); - printk ("DC390: Please report driver trouble to K.Garloff@ping.de\n"); + printk ("DC390: In case of driver trouble read linux/drivers/scsi/README.tmscsim\n"); }; @@ -1076,6 +1280,8 @@ * Inputs : cmd - command to abort * * Returns : 0 on success, -1 on failure. + * + * Status: Buggy ! ***********************************************************************/ int DC390_abort (Scsi_Cmnd *cmd) @@ -1347,13 +1553,13 @@ /*********************************************************************** - * Function : static void dc390_initDCB + * Function : static void dc390_initDCB() * * Purpose : initialize the internal structures for a given DCB * * Inputs : cmd - pointer to this scsi cmd request block structure - * ***********************************************************************/ + void dc390_initDCB( PACB pACB, PDCB *ppDCB, PSCSICMD cmd ) { PEEprom prom; @@ -1412,11 +1618,11 @@ } /*********************************************************************** - * Function : static void dc390_updateDCB + * Function : static void dc390_updateDCB() * * Purpose : Set the configuration dependent DCB parameters - * ***********************************************************************/ + void dc390_updateDCB (PACB pACB, PDCB pDCB) { pDCB->IdentifyMsg = IDENTIFY (pDCB->DevMode & EN_DISCONNECT_, pDCB->UnitSCSILUN); @@ -1441,11 +1647,11 @@ /*********************************************************************** - * Function : static void dc390_updateDCBs + * Function : static void dc390_updateDCBs () * * Purpose : Set the configuration dependent DCB params for all DCBs - * ***********************************************************************/ + static void dc390_updateDCBs (PACB pACB) { int i; @@ -1459,13 +1665,13 @@ /*********************************************************************** - * Function : static void dc390_initSRB + * Function : static void dc390_initSRB() * * Purpose : initialize the internal structures for a given SRB * * Inputs : psrb - pointer to this scsi request block structure - * ***********************************************************************/ + static void __inline__ dc390_initSRB( PSRB psrb ) { /* psrb->PhysSRB = virt_to_phys( psrb ); */ @@ -1489,13 +1695,14 @@ /*********************************************************************** - * Function : static void dc390_initACB + * Function : static void dc390_initACB () * * Purpose : initialize the internal structures for a given SCSI host * * Inputs : psh - pointer to this host adapter's structure - * + * io_port, Irq, index: Resources and adapter index ***********************************************************************/ + void __init dc390_initACB (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index) { PACB pACB; @@ -1510,14 +1717,14 @@ psh->irq = Irq; pACB = (PACB) psh->hostdata; - DC390_LOCK_INIT; + DC390_LOCKA_INIT; DC390_LOCK_ACB; pACB->pScsiHost = psh; pACB->IOPortBase = (USHORT) io_port; pACB->IRQLevel = Irq; - DEBUG0(printk (KERN_DEBUG "DC390: Adapter index %i, ID %i, IO 0x%08x, IRQ 0x%02x\n", \ + DEBUG0(printk (KERN_INFO "DC390: Adapter index %i, ID %i, IO 0x%08x, IRQ 0x%02x\n", \ index, psh->this_id, (int)io_port, Irq);) psh->max_id = 8; @@ -1541,6 +1748,8 @@ pACB->TagMaxNum = 2 << dc390_eepromBuf[index][EE_TAG_CMD_NUM]; pACB->ACBFlag = 0; pACB->scan_devices = 1; + pACB->MsgLen = 0; + pACB->Ignore_IRQ = 0; pACB->Gmode2 = dc390_eepromBuf[index][EE_MODE2]; dc390_linkSRB( pACB ); pACB->pTmpSRB = &pACB->TmpSRB; @@ -1554,33 +1763,44 @@ /*********************************************************************** - * Function : static int dc390_initAdapter + * Function : static int dc390_initAdapter () * * Purpose : initialize the SCSI chip ctrl registers * * Inputs : psh - pointer to this host adapter's structure + * io_port, Irq, index: Resources * + * Outputs: 0 on success, -1 on error ***********************************************************************/ + int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index) { - PACB pACB, pacb; + PACB pACB, pACB2; UCHAR used_irq = 0, dstate; int i; + + pACB = (PACB) psh->hostdata; + + for ( pACB2 = dc390_pACB_start; pACB2 ; ) + { + if( pACB2->IRQLevel == Irq ) + { + used_irq = 1; + break; + } + else + pACB2 = pACB2->pNextACB; + } - pacb = dc390_pACB_start; - if( pacb != NULL ) - { - for ( ; (pacb != (PACB) -1) ; ) + if (check_region (io_port, psh->n_io_port)) { - if( pacb->IRQLevel == Irq ) - { - used_irq = 1; - break; - } - else - pacb = pacb->pNextACB; + printk(KERN_ERR "DC390: register IO ports error!\n"); + return( -1 ); } - } + else + request_region (io_port, psh->n_io_port, "tmscsim"); + + DC390_read8_ (INT_Status, io_port); /* Reset Pending INT */ if( !used_irq ) { @@ -1591,18 +1811,22 @@ } } - if (check_region (io_port, psh->n_io_port)) - { - printk(KERN_ERR "DC390: register IO ports error!\n"); - return( -1 ); - } + if( !dc390_pACB_start ) + { + pACB2 = NULL; + dc390_pACB_start = pACB; + dc390_pACB_current = pACB; + pACB->pNextACB = NULL; + } else - request_region (io_port, psh->n_io_port, "tmscsim"); - - pACB = (PACB) psh->hostdata; - /* pACB->IOPortBase = (USHORT) io_port; */ + { + pACB2 = dc390_pACB_current; + dc390_pACB_current->pNextACB = pACB; + dc390_pACB_current = pACB; + pACB->pNextACB = NULL; + }; - DC390_write8_ (CtrlReg1, DIS_INT_ON_SCSI_RST | psh->this_id, io_port); /* Disable SCSI bus reset interrupt */ + DC390_write8 (CtrlReg1, DIS_INT_ON_SCSI_RST | psh->this_id); /* Disable SCSI bus reset interrupt */ if (pACB->Gmode2 & RST_SCSI_BUS) { @@ -1612,6 +1836,7 @@ udelay(1000); }; pACB->ACBFlag = 0; + DC390_read8 (INT_Status); /* Reset Pending INT */ DC390_write8 (Scsi_TimeOut, SEL_TIMEOUT); /* 250ms selection timeout */ DC390_write8 (Clk_Factor, CLK_FREQ_40MHZ); /* Conversion factor = 0 , 40MHz clock */ @@ -1622,7 +1847,7 @@ (dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION) ? NEGATE_REQACKDATA : 0); /* Negation */ DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); - DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT); + DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT); dstate = DC390_read8 (DMA_Status); DC390_write8 (DMA_Status, dstate); /* clear */ @@ -1630,194 +1855,24 @@ } -static void __init dc390_EnDisableCE( UCHAR mode, PDEVDECL, PUCHAR regval ) -{ - UCHAR bval; - - bval = 0; - if(mode == ENABLE_CE) - *regval = 0xc0; - else - *regval = 0x80; - PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); - if(mode == DISABLE_CE) - PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); - udelay(160); -} - -#ifndef CONFIG_SCSI_DC390T_NOGENSUPP -static void __init dc390_EEpromDefaults (UCHAR index) -{ - PUCHAR ptr; - UCHAR id; - ptr = (PUCHAR) dc390_eepromBuf[index]; - - /* Adapter Settings */ - ptr[EE_ADAPT_SCSI_ID] = (UCHAR)tmscsim[0]; /* Adapter ID */ - ptr[EE_MODE2] = (UCHAR)tmscsim[3]; - ptr[EE_DELAY] = 0; /* ?? */ - ptr[EE_TAG_CMD_NUM] = (UCHAR)tmscsim[4]; /* Tagged Comds */ - - /* Device Settings */ - for (id = 0; id < MAX_SCSI_ID; id++) - { - ptr[id<<2] = (UCHAR)tmscsim[2]; /* EE_MODE1 */ - ptr[(id<<2) + 1] = (UCHAR)tmscsim[1]; /* EE_Speed */ - }; - dc390_adapname = "AM53C974"; -} - -static void __init dc390_checkparams (void) -{ - PARSEDEBUG(printk(KERN_INFO "DC390: setup %08x %08x %08x %08x %08x\n", tmscsim[0],\ - tmscsim[1], tmscsim[2], tmscsim[3], tmscsim[4]);) - if (tmscsim[0] < 0 || tmscsim[0] > 7) /* modules-2.0.0 passes -1 as string */ - { - tmscsim[0] = 7; tmscsim[1] = 4; - tmscsim[2] = 9; tmscsim[3] = 15; - tmscsim[4] = 2; - printk (KERN_INFO "DC390: Using safe settings.\n"); - } - else - { - /* if (tmscsim[0] < 0 || tmscsim[0] > 7) tmscsim[0] = 7; */ - if (tmscsim[1] < 0 || tmscsim[1] > 7) tmscsim[1] = 4; - if (tmscsim[4] < 0 || tmscsim[4] > 5) tmscsim[4] = 4; - }; -}; -/* Override defaults on cmdline: - * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped) - */ -void __init dc390_setup (char *str, int *ints) -{ - int i; - for (i = 0; i < ints[0]; i++) - tmscsim[i] = ints[i+1]; - if (ints[0] > 5) - printk (KERN_NOTICE "DC390: ignore extra params!\n"); - /* dc390_checkparams (); */ -}; -#endif /* CONFIG_SCSI_DC390T_NOGENSUPP */ - - -static void __init dc390_EEpromOutDI( PDEVDECL, PUCHAR regval, UCHAR Carry ) -{ - UCHAR bval; - - bval = 0; - if(Carry) - { - bval = 0x40; - *regval = 0x80; - PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); - } - udelay(160); - bval |= 0x80; - PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); - udelay(160); - bval = 0; - PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval); - udelay(160); -} - - -static UCHAR __init dc390_EEpromInDO( PDEVDECL ) -{ - UCHAR bval; - - PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x80); - udelay(160); - PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x40); - udelay(160); - PCI_READ_CONFIG_BYTE(PDEV, 0x00, &bval); - if(bval == 0x22) - return(1); - else - return(0); -} - - -static USHORT __init dc390_EEpromGetData1( PDEVDECL ) -{ - UCHAR i; - UCHAR carryFlag; - USHORT wval; - - wval = 0; - for(i=0; i<16; i++) - { - wval <<= 1; - carryFlag = dc390_EEpromInDO(PDEV); - wval |= carryFlag; - } - return(wval); -} - - -static void __init dc390_Prepare( PDEVDECL, PUCHAR regval, UCHAR EEpromCmd ) -{ - UCHAR i,j; - UCHAR carryFlag; - - carryFlag = 1; - j = 0x80; - for(i=0; i<9; i++) - { - dc390_EEpromOutDI(PDEV,regval,carryFlag); - carryFlag = (EEpromCmd & j) ? 1 : 0; - j >>= 1; - } -} - - -static void __init dc390_ReadEEprom( PDEVDECL, PUSHORT ptr) -{ - UCHAR regval,cmd; - UCHAR i; - - cmd = EEPROM_READ; - for(i=0; i<0x40; i++) - { - dc390_EnDisableCE(ENABLE_CE, PDEV, ®val); - dc390_Prepare(PDEV, ®val, cmd++); - *ptr++ = dc390_EEpromGetData1(PDEV); - dc390_EnDisableCE(DISABLE_CE, PDEV, ®val); - } -} - - -static UCHAR __init dc390_CheckEEpromCheckSum( PDEVDECL, UCHAR index ) -{ - UCHAR i; - char EEbuf[128]; - USHORT wval, *ptr = (PUSHORT)EEbuf; - - dc390_ReadEEprom( PDEV, ptr ); - memcpy (dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID); - memcpy (&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID], - &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID); - wval = 0; - for(i=0; i<0x40; i++, ptr++) - wval += *ptr; - return (wval == 0x1234 ? 0 : 1); -} - - /*********************************************************************** - * Function : static int DC390_init (struct Scsi_Host *host) + * Function : static int DC390_init (struct Scsi_Host *host, ...) * * Purpose : initialize the internal structures for a given SCSI host * - * Inputs : host - pointer to this host adapter's structure/ + * Inputs : host - pointer to this host adapter's structure + * io_port - IO ports mapped to this adapter + * Irq - IRQ assigned to this adpater + * PDEVDECL - PCI access handle + * index - Adapter index * - * Preconditions : when this function is called, the chip_type - * field of the pACB structure MUST have been set. + * Outputs: 0 on success, -1 on error * * Note: written in capitals, because the locking is only done here, * not in DC390_detect, called from outside ***********************************************************************/ -static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, PDEVDECL, int index) +static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, PDEVDECL, UCHAR index) { PSH psh; PACB pACB; @@ -1846,7 +1901,7 @@ if( !psh ) return( -1 ); pACB = (PACB) psh->hostdata; - DC390_LOCK_INIT; + DC390_LOCKA_INIT; DC390_LOCK_ACB; #if 0 @@ -1862,37 +1917,21 @@ } #endif - DEBUG0(printk("DC390: pSH = %8x,", (UINT) psh);) - DEBUG0(printk("DC390: Index %02i,", index);) + DEBUG0(printk(KERN_INFO "DC390: pSH = %8x,", (UINT) psh);) + DEBUG0(printk(" Index %02i,", index);) dc390_initACB( psh, io_port, Irq, index ); + pACB = (PACB) psh->hostdata; + PDEVSET; - DC390_read8_ (INT_Status, io_port); /* Reset Pending INT */ - if( !dc390_initAdapter( psh, io_port, Irq, index ) ) { - pACB = (PACB) psh->hostdata; - if( !dc390_pACB_start ) - { - dc390_pACB_start = pACB; - dc390_pACB_current = pACB; - pACB->pNextACB = (PACB) -1; - } - else - { - dc390_pACB_current->pNextACB = pACB; - dc390_pACB_current = pACB; - pACB->pNextACB = (PACB) -1; - } - - DEBUG0(printk("DC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\ + DEBUG0(printk("\nDC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\ (UINT) pACB, (UINT) pACB->DCBmap, (UINT) pACB->SRB_array);) DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\ sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) );) - DC390_read8_ (INT_Status, io_port); /* Reset Pending INT */ - DC390_UNLOCK_ACB; return (0); } @@ -1960,7 +1999,6 @@ PDEVDECL0; UCHAR irq; UINT io_port; - UCHAR adaptCnt = 0; /* Number of boards detected */ DC390_IFLAGS DC390_DFLAGS DC390_LOCK_DRV; @@ -1972,29 +2010,36 @@ { DC390_LOCK_IO; /* Remove this when going to new eh */ PCI_GET_IO_AND_IRQ; - DEBUG0(printk(KERN_DEBUG "DC390(%i): IO_PORT=%04x,IRQ=%x\n", adaptCnt, (UINT) io_port, irq);) + DEBUG0(printk(KERN_INFO "DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt, (UINT) io_port, irq);) - if( !DC390_init(psht, io_port, irq, PDEV, adaptCnt)) + if( !DC390_init(psht, io_port, irq, PDEV, dc390_adapterCnt)) { PCI_SET_MASTER; dc390_set_pci_cfg (PDEV); - adaptCnt++; + dc390_adapterCnt++; }; DC390_UNLOCK_IO; /* Remove when going to new eh */ } else printk (KERN_ERR "DC390: No PCI BIOS found!\n"); - if (adaptCnt) + if (dc390_adapterCnt) psht->proc_dir = &DC390_proc_scsi_tmscsim; - printk(KERN_INFO "DC390: %i adapters found\n", adaptCnt); - dc390_adapterCnt = adaptCnt; + printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt); DC390_UNLOCK_DRV; - return( adaptCnt ); + return( dc390_adapterCnt ); } +/*********************************************************************** + * Functions: dc390_inquiry(), dc390_inquiry_done() + * + * Purpose: When changing speed etc., we have to issue an INQUIRY + * command to make sure, we agree upon the nego parameters + * with the device + ***********************************************************************/ + static void dc390_inquiry_done (Scsi_Cmnd* cmd) { printk (KERN_INFO "DC390: INQUIRY (ID %02x LUN %02x) returned %08x\n", @@ -2211,7 +2256,7 @@ /* NegoPeriod */ if (*pos != '-') { - SCANF (pos, p0, dum, 76, 800); + SCANF (pos, p0, dum, 72, 800); pDCB->NegoPeriod = dum >> 2; if (pDCB->NegoPeriod != olddevmode) needs_inquiry++; if (!pos) goto ok; @@ -2367,8 +2412,6 @@ * ********************************************************************/ -/* KG: proc_info taken from driver aha152x.c */ - #undef SPRINTF #define SPRINTF(args...) pos += sprintf(pos, ## args) @@ -2529,14 +2572,14 @@ if (host->irq != IRQ_NONE) { for (irq_count = 0, pACB = dc390_pACB_start; - pACB && pACB != (PACB)-1; pACB = pACB->pNextACB) + pACB; pACB = pACB->pNextACB) { if ( pACB->IRQLevel == host->irq ) ++irq_count; } if (irq_count == 1) { - DEBUG0(printk(KERN_DEBUG "DC390: Free IRQ %i\n",host->irq);) + DEBUG0(printk(KERN_INFO "DC390: Free IRQ %i\n",host->irq);) free_irq(host->irq,NULL); } } diff -u --recursive --new-file v2.1.132/linux/drivers/scsi/tmscsim.h linux/drivers/scsi/tmscsim.h --- v2.1.132/linux/drivers/scsi/tmscsim.h Sun Nov 8 14:03:02 1998 +++ linux/drivers/scsi/tmscsim.h Fri Dec 25 16:41:39 1998 @@ -3,7 +3,7 @@ ;* TEKRAM DC-390(T) PCI SCSI Bus Master Host Adapter * ;* Device Driver * ;***********************************************************************/ -/* $Id: tmscsim.h,v 2.1 1998/10/14 10:31:48 garloff Exp $ */ +/* $Id: tmscsim.h,v 2.4 1998/12/25 17:33:27 garloff Exp $ */ #ifndef _TMSCSIM_H #define _TMSCSIM_H @@ -95,15 +95,13 @@ /* 0x48: */ SGL Segmentx; /* make a one entry of S/G list table */ -PUCHAR pMsgPtr; - UCHAR ScsiCmdLen; UCHAR ScsiPhase; UCHAR AdaptStatus; UCHAR TargetStatus; -/* 0x5c: */ +/* 0x58: */ UCHAR MsgCnt; UCHAR EndMessage; UCHAR RetryCnt; @@ -115,7 +113,7 @@ UCHAR SRBStatus; //UCHAR IORBFlag; /*;81h-Reset, 2-retry */ -/* 0x64: */ +/* 0x60: */ }; @@ -218,14 +216,16 @@ UCHAR sel_timeout; UCHAR glitch_cfg; -UCHAR reserved[2]; /* alignment */ +UCHAR MsgLen; +UCHAR Ignore_IRQ; /* Not used */ PDEVDECL1; /* Pointer to PCI cfg. space */ -/* 0x44/0x40: */ +/* 0x40/0x3c: */ ULONG Cmds; ULONG CmdInQ; ULONG CmdOutOfSRB; ULONG SelLost; + /* 0x50/0x4c: */ DC390_SRB TmpSRB; diff -u --recursive --new-file v2.1.132/linux/drivers/sound/Config.in linux/drivers/sound/Config.in --- v2.1.132/linux/drivers/sound/Config.in Tue Dec 22 14:16:56 1998 +++ linux/drivers/sound/Config.in Sun Dec 27 10:53:45 1998 @@ -131,7 +131,7 @@ int 'PSS MIDI IRQ 3, 4, 5, 7, 9, 10, 11, 12' CONFIG_PSS_MPU_IRQ 9 bool ' Have DSPxxx.LD firmware file' CONFIG_PSS_HAVE_BOOT if [ "$CONFIG_PSS_HAVE_BOOT" = "y" ]; then - string ' Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE + string ' Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld fi fi if [ "$CONFIG_SOUND_PSS" = "y" -o "$CONFIG_SOUND_PSS" = "m" ]; then @@ -168,7 +168,7 @@ int 'TRIX SB DMA 1 or 3' CONFIG_TRIX_SB_DMA 1 bool ' Have TRXPRO.HEX firmware file' CONFIG_TRIX_HAVE_BOOT if [ "$CONFIG_TRIX_HAVE_BOOT" = "y" ]; then - string ' Full pathname of TRXPRO.HEX firmware file' CONFIG_TRIX_BOOT_FILE + string ' Full pathname of TRXPRO.HEX firmware file' CONFIG_TRIX_BOOT_FILE /etc/sound/trxpro.hex fi fi @@ -185,7 +185,7 @@ int 'MAD16 MIDI IRQ 5, 7, 9 or 10' CONFIG_MAD16_MPU_IRQ 9 fi - dep_tristate 'Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS + dep_tristate 'Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m if [ "$CONFIG_SOUND_WAVEFRONT" = "y" ]; then hex 'I/O base for WaveFront 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_WAVEFRONT_BASE 330 int 'WaveFront IRQ 5, 9, 12 or 15' CONFIG_WAVEFRONT_IRQ 9 @@ -218,7 +218,7 @@ int 'Maui IRQ 5, 9, 12 or 15' CONFIG_MAUI_IRQ 9 bool ' Have OSWF.MOT firmware file' CONFIG_MAUI_HAVE_BOOT if [ "$CONFIG_MAUI_HAVE_BOOT" = "y" ]; then - string ' Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE + string ' Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE /etc/sound/oswf.mot fi fi diff -u --recursive --new-file v2.1.132/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c --- v2.1.132/linux/drivers/sound/ad1848.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/sound/ad1848.c Sun Dec 27 10:53:45 1998 @@ -71,6 +71,7 @@ #define MD_4232 5 #define MD_C930 6 #define MD_IWAVE 7 +#define MD_4235 8 /* Crystal Audio CS4235 */ /* Mixer parameters */ int recmask; @@ -111,7 +112,7 @@ #endif -static int ad_format_mask[8 /*devc->model */ ] = +static int ad_format_mask[9 /*devc->model */ ] = { 0, AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW, @@ -120,7 +121,8 @@ AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW, /* AD1845 */ AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM, AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM, - AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM + AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM, + AFMT_U8 | AFMT_S16_LE /* CS4235 */ }; static ad1848_info adev_info[MAX_AUDIO_DEV]; @@ -1594,103 +1596,107 @@ ad_write(devc, 25, ~tmp1); /* Invert all bits */ if ((ad_read(devc, 25) & 0xe7) == (tmp1 & 0xe7)) { - int id, full_id; + int id; /* * It's at least CS4231 */ - devc->chip_name = "CS4231"; - devc->model = MD_4231; - /* * It could be an AD1845 or CS4231A as well. * CS4231 and AD1845 report the same revision info in I25 * while the CS4231A reports different. */ - id = ad_read(devc, 25) & 0xe7; - full_id = ad_read(devc, 25); - if (id == 0x80) /* Device busy??? */ - id = ad_read(devc, 25) & 0xe7; - if (id == 0x80) /* Device still busy??? */ - id = ad_read(devc, 25) & 0xe7; + id = ad_read(devc, 25); + if ((id & 0xe7) == 0x80) /* Device busy??? */ + id = ad_read(devc, 25); + if ((id & 0xe7) == 0x80) /* Device still busy??? */ + id = ad_read(devc, 25); DDB(printk("ad1848_detect() - step J (%02x/%02x)\n", id, ad_read(devc, 25))); - switch (id) + if ((id & 0xe7) == 0x80) { + /* + * It must be a CS4231 or AD1845. The register I23 of + * CS4231 is undefined and it appears to be read only. + * AD1845 uses I23 for setting sample rate. Assume + * the chip is AD1845 if I23 is changeable. + */ + + unsigned char tmp = ad_read(devc, 23); + ad_write(devc, 23, ~tmp); + + if (interwave) + { + devc->model = MD_IWAVE; + devc->chip_name = "IWave"; + } + else if (ad_read(devc, 23) != tmp) /* AD1845 ? */ + { + devc->chip_name = "AD1845"; + devc->model = MD_1845; + } + else if (cs4248_flag) + { + if (ad_flags) + *ad_flags |= AD_F_CS4248; + devc->chip_name = "CS4248"; + devc->model = MD_1848; + ad_write(devc, 12, ad_read(devc, 12) & ~0x40); /* Mode2 off */ + } + ad_write(devc, 23, tmp); /* Restore */ + } + else { - - case 0xa0: - devc->chip_name = "CS4231A"; - devc->model = MD_4231A; + switch (id & 0x1f) { + case 3: /* CS4236/CS4235 */ + { + int xid; + ad_write(devc, 12, ad_read(devc, 12) | 0x60); /* switch to mode 3 */ + ad_write(devc, 23, 0x9c); /* select extended register 25 */ + xid = inb(io_Indexed_Data(devc)); + ad_write(devc, 12, ad_read(devc, 12) & ~0x60); /* back to mode 0 */ + if ((xid & 0x1f) == 0x1d) { + devc->chip_name = "CS4235"; + devc->model = MD_4235; + } else { + devc->chip_name = "CS4236"; + devc->model = MD_4232; + } + } break; - case 0xa2: + case 2: /* CS4232/CS4232A */ devc->chip_name = "CS4232"; devc->model = MD_4232; break; - - case 0xb2: - devc->chip_name = "CS4232A"; - devc->model = MD_4232; - break; - - case 0x03: - case 0x83: - devc->chip_name = "CS4236"; - devc->model = MD_4232; - break; - - case 0x41: - devc->chip_name = "CS4236B"; - devc->model = MD_4232; - break; - - case 0x80: + + case 0: + if ((id & 0xe0) == 0xa0) { - /* - * It must be a CS4231 or AD1845. The register I23 of - * CS4231 is undefined and it appears to be read only. - * AD1845 uses I23 for setting sample rate. Assume - * the chip is AD1845 if I23 is changeable. - */ - - unsigned char tmp = ad_read(devc, 23); - ad_write(devc, 23, ~tmp); - - if (interwave) - { - devc->model = MD_IWAVE; - devc->chip_name = "IWave"; - } - else if (ad_read(devc, 23) != tmp) /* AD1845 ? */ - { - devc->chip_name = "AD1845"; - devc->model = MD_1845; - } - else if (cs4248_flag) - { - if (ad_flags) - *ad_flags |= AD_F_CS4248; - devc->chip_name = "CS4248"; - devc->model = MD_1848; - ad_write(devc, 12, ad_read(devc, 12) & ~0x40); /* Mode2 off */ - } - ad_write(devc, 23, tmp); /* Restore */ + devc->chip_name = "CS4231A"; + devc->model = MD_4231A; + } + else + { + devc->chip_name = "CS4321"; + devc->model = MD_4231; } break; - default: /* Assume CS4231 or OPTi 82C930 */ + default: /* maybe */ DDB(printk("ad1848: I25 = %02x/%02x\n", ad_read(devc, 25), ad_read(devc, 25) & 0xe7)); - if (optiC930) - { - devc->chip_name = "82C930"; - devc->model = MD_C930; - } + if (optiC930) + { + devc->chip_name = "82C930"; + devc->model = MD_C930; + } else { + devc->chip_name = "CS4231"; devc->model = MD_4231; } + } } } ad_write(devc, 25, tmp1); /* Restore bits */ diff -u --recursive --new-file v2.1.132/linux/drivers/sound/cs4232.c linux/drivers/sound/cs4232.c --- v2.1.132/linux/drivers/sound/cs4232.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/sound/cs4232.c Sun Dec 27 10:53:45 1998 @@ -369,9 +369,6 @@ cfg.dma = dma; cfg.dma2 = dma2; - if (probe_cs4232(&cfg) == 0) - return -ENODEV; - mpu_cfg.io_base = -1; mpu_cfg.irq = -1; @@ -380,6 +377,9 @@ mpu_cfg.irq = mpuirq; probe_cs4232_mpu(&mpu_cfg); /* Bug always returns 0 not OK -- AC */ } + + if (probe_cs4232(&cfg) == 0) + return -ENODEV; attach_cs4232(&cfg); diff -u --recursive --new-file v2.1.132/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c --- v2.1.132/linux/drivers/sound/es1370.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/sound/es1370.c Sun Dec 27 10:53:45 1998 @@ -80,6 +80,7 @@ * 08.10.98 0.14 Joystick support fixed * -- Oliver Neukum * 10.12.98 0.15 Fix drain_dac trying to wait on not yet initialized DMA + * 16.12.98 0.16 Don't wake up app until there are fragsize bytes to read/write * * some important things missing in Ensoniq documentation: * @@ -603,17 +604,14 @@ diff = get_hwptr(s, &s->dma_adc, ES1370_REG_ADC_FRAMECNT); s->dma_adc.total_bytes += diff; s->dma_adc.count += diff; - if (s->dma_adc.mapped) { - if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) - wake_up(&s->dma_adc.wait); - } else { + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + wake_up(&s->dma_adc.wait); + if (!s->dma_adc.mapped) { if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { s->ctrl &= ~CTRL_ADC_EN; outl(s->ctrl, s->io+ES1370_REG_CONTROL); s->dma_adc.error++; } - if (s->dma_adc.count > 0) - wake_up(&s->dma_adc.wait); } } /* update DAC1 pointer */ @@ -635,7 +633,7 @@ s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80); s->dma_dac1.endcleared = 1; } - if (s->dma_dac1.count < (signed)s->dma_dac1.dmasize) + if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize) wake_up(&s->dma_dac1.wait); } } @@ -658,7 +656,7 @@ s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80); s->dma_dac2.endcleared = 1; } - if (s->dma_dac2.count < (signed)s->dma_dac2.dmasize) + if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize) wake_up(&s->dma_dac2.wait); } } @@ -1186,20 +1184,15 @@ spin_lock_irqsave(&s->lock, flags); es1370_update_ptr(s); if (file->f_mode & FMODE_READ) { - if (s->dma_adc.mapped) { - if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) - mask |= POLLIN | POLLRDNORM; - } else { - if (s->dma_adc.count > 0) - mask |= POLLIN | POLLRDNORM; - } + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + mask |= POLLIN | POLLRDNORM; } if (file->f_mode & FMODE_WRITE) { if (s->dma_dac2.mapped) { if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) mask |= POLLOUT | POLLWRNORM; } else { - if ((signed)s->dma_dac2.dmasize > s->dma_dac2.count) + if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize) mask |= POLLOUT | POLLWRNORM; } } @@ -1704,7 +1697,7 @@ if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize) mask |= POLLOUT | POLLWRNORM; } else { - if ((signed)s->dma_dac1.dmasize > s->dma_dac1.count) + if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize) mask |= POLLOUT | POLLWRNORM; } spin_unlock_irqrestore(&s->lock, flags); @@ -2277,7 +2270,7 @@ if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1370: version v0.15 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "es1370: version v0.16 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) { if (pcidev->base_address[0] == 0 || diff -u --recursive --new-file v2.1.132/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c --- v2.1.132/linux/drivers/sound/es1371.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/sound/es1371.c Mon Dec 28 11:06:11 1998 @@ -50,6 +50,8 @@ * 27.10.98 0.5 Fix joystick support * -- Oliver Neukum (c188@org.chemie.uni-muenchen.de) * 10.12.98 0.6 Fix drain_dac trying to wait on not yet initialized DMA + * 23.12.98 0.7 Fix a few f_file & FMODE_ bugs + * Don't wake up app until there are fragsize bytes to read/write * */ @@ -837,17 +839,14 @@ diff = get_hwptr(s, &s->dma_adc, ES1371_REG_ADC_FRAMECNT); s->dma_adc.total_bytes += diff; s->dma_adc.count += diff; - if (s->dma_adc.mapped) { - if (s->dma_adc.count >= s->dma_adc.fragsize) - wake_up(&s->dma_adc.wait); - } else { + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + wake_up(&s->dma_adc.wait); + if (!s->dma_adc.mapped) { if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { s->ctrl &= ~CTRL_ADC_EN; outl(s->ctrl, s->io+ES1371_REG_CONTROL); s->dma_adc.error++; } - if (s->dma_adc.count > 0) - wake_up(&s->dma_adc.wait); } } /* update DAC1 pointer */ @@ -869,7 +868,7 @@ s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80); s->dma_dac1.endcleared = 1; } - if (s->dma_dac1.count < (signed)s->dma_dac1.dmasize) + if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize) wake_up(&s->dma_dac1.wait); } } @@ -892,7 +891,7 @@ s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80); s->dma_dac2.endcleared = 1; } - if (s->dma_dac2.count < (signed)s->dma_dac2.dmasize) + if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize) wake_up(&s->dma_dac2.wait); } } @@ -1625,27 +1624,22 @@ unsigned int mask = 0; VALIDATE_STATE(s); - if (file->f_flags & FMODE_WRITE) + if (file->f_mode & FMODE_WRITE) poll_wait(file, &s->dma_dac2.wait, wait); - if (file->f_flags & FMODE_READ) + if (file->f_mode & FMODE_READ) poll_wait(file, &s->dma_adc.wait, wait); spin_lock_irqsave(&s->lock, flags); es1371_update_ptr(s); - if (file->f_flags & FMODE_READ) { - if (s->dma_adc.mapped) { + if (file->f_mode & FMODE_READ) { if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) mask |= POLLIN | POLLRDNORM; - } else { - if (s->dma_adc.count > 0) - mask |= POLLIN | POLLRDNORM; - } } - if (file->f_flags & FMODE_WRITE) { + if (file->f_mode & FMODE_WRITE) { if (s->dma_dac2.mapped) { if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) mask |= POLLOUT | POLLWRNORM; } else { - if ((signed)s->dma_dac2.dmasize > s->dma_dac2.count) + if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize) mask |= POLLOUT | POLLWRNORM; } } @@ -2046,11 +2040,11 @@ if (file->f_mode & FMODE_WRITE) drain_dac2(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); - if (file->f_flags & FMODE_WRITE) { + if (file->f_mode & FMODE_WRITE) { stop_dac2(s); dealloc_dmabuf(&s->dma_dac2); } - if (file->f_flags & FMODE_READ) { + if (file->f_mode & FMODE_READ) { stop_adc(s); dealloc_dmabuf(&s->dma_adc); } @@ -2150,7 +2144,7 @@ if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize) mask |= POLLOUT | POLLWRNORM; } else { - if ((signed)s->dma_dac1.dmasize > s->dma_dac1.count) + if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize) mask |= POLLOUT | POLLWRNORM; } spin_unlock_irqrestore(&s->lock, flags); @@ -2540,16 +2534,16 @@ unsigned int mask = 0; VALIDATE_STATE(s); - if (file->f_flags & FMODE_WRITE) + if (file->f_mode & FMODE_WRITE) poll_wait(file, &s->midi.owait, wait); - if (file->f_flags & FMODE_READ) + if (file->f_mode & FMODE_READ) poll_wait(file, &s->midi.iwait, wait); spin_lock_irqsave(&s->lock, flags); - if (file->f_flags & FMODE_READ) { + if (file->f_mode & FMODE_READ) { if (s->midi.icnt > 0) mask |= POLLIN | POLLRDNORM; } - if (file->f_flags & FMODE_WRITE) { + if (file->f_mode & FMODE_WRITE) { if (s->midi.ocnt < MIDIOUTBUF) mask |= POLLOUT | POLLWRNORM; } @@ -2684,7 +2678,7 @@ /* --------------------------------------------------------------------- */ -static const struct initvol { +static struct initvol { int mixch; int vol; } initvol[] __initdata = { @@ -2716,7 +2710,7 @@ if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1371: version v0.6 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "es1371: version v0.7 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) { if (pcidev->base_address[0] == 0 || diff -u --recursive --new-file v2.1.132/linux/drivers/sound/lowlevel/Config.in linux/drivers/sound/lowlevel/Config.in --- v2.1.132/linux/drivers/sound/lowlevel/Config.in Tue Jun 9 11:57:30 1998 +++ linux/drivers/sound/lowlevel/Config.in Sun Dec 27 10:53:45 1998 @@ -6,6 +6,7 @@ dep_tristate 'Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 $CONFIG_SOUND_OSS if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then hex ' I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 + hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330 fi if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then @@ -23,9 +24,9 @@ bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then comment 'Audio Excel DSP 16 [Sound Blaster Pro]' - hex 'I/O base for Audio Excel DSP 16 220, 240' CONFIG_AEDSP16_BASE $CONFIG_SB_BASE - int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ - int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA + hex 'I/O base for Audio Excel DSP 16 220, 240' CONFIG_AEDSP16_BASE $CONFIG_SB_BASE 220 + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ 5 + int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA 0 fi fi fi @@ -36,8 +37,8 @@ if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then comment 'Audio Excel DSP 16 [Microsoft Sound System]' hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220 - int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ - int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ 5 + int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA 1 fi fi fi diff -u --recursive --new-file v2.1.132/linux/drivers/sound/mad16.c linux/drivers/sound/mad16.c --- v2.1.132/linux/drivers/sound/mad16.c Thu Nov 12 16:21:22 1998 +++ linux/drivers/sound/mad16.c Mon Dec 28 11:06:11 1998 @@ -65,6 +65,8 @@ * Improved debugging support. 16-May-1998 * Fixed bug. 16-Jun-1998 * + * Torsten Duwe Made Opti924 PnP support non-destructive + * 1998-12-23 */ #include "sound_config.h" @@ -279,19 +281,21 @@ if ((mad_read(MC0_PORT+13) & 0x80) == 0) return 1; +#if 0 /* Force off PnP mode. This is not recommended because * the PnP bios will not recognize the chip on the next * warm boot and may assignd different resources to other * PnP/PCI cards. */ mad_write(MC0_PORT+17, 0x04); +#endif return 1; } static int detect_mad16(void) { - unsigned char tmp, tmp2; - int i; + unsigned char tmp, tmp2, bit; + int i, port; /* * Check that reading a register doesn't return bus float (0xff) @@ -323,14 +327,19 @@ DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2)); return 0; } - mad_write(MC1_PORT, tmp ^ 0x80); /* Toggle a bit */ - if ((tmp2 = mad_read(MC1_PORT)) != (tmp ^ 0x80)) /* Compare the bit */ + + bit = (c924pnp) ? 0x20 : 0x80; + port = (c924pnp) ? MC2_PORT : MC1_PORT; + + tmp = mad_read(port); + mad_write(port, tmp ^ bit); /* Toggle a bit */ + if ((tmp2 = mad_read(port)) != (tmp ^ bit)) /* Compare the bit */ { - mad_write(MC1_PORT, tmp); /* Restore */ + mad_write(port, tmp); /* Restore */ DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2)); return 0; } - mad_write(MC1_PORT, tmp); /* Restore */ + mad_write(port, tmp); /* Restore */ return 1; /* Bingo */ } @@ -456,14 +465,8 @@ DDB(printk("Detect using password = 0xE5\n")); - if (!detect_mad16()) { - c924pnp++; - DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n")); - } - if (!detect_mad16()) /* No luck. Try different model */ { - c924pnp=0; board_type = C928; DDB(printk("Detect using password = 0xE2\n")); @@ -493,10 +496,19 @@ for (i = 0xf8d; i <= 0xf93; i++) DDB(printk("port %03x = %02x\n", i, mad_read(i))); - if (!detect_mad16()) - return 0; - - DDB(printk("mad16.c: 82C930 detected\n")); + if (!detect_mad16()) { + board_type = C924; + c924pnp++; + DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n")); + if (!detect_mad16()) { + c924pnp=0; + return 0; + } + + DDB(printk("mad16.c: 82C924 PnP detected\n")); + } + else + DDB(printk("mad16.c: 82C930 detected\n")); } else DDB(printk("mad16.c: 82C929 detected\n")); } else { diff -u --recursive --new-file v2.1.132/linux/drivers/sound/sb.h linux/drivers/sound/sb.h --- v2.1.132/linux/drivers/sound/sb.h Thu Nov 12 16:21:22 1998 +++ linux/drivers/sound/sb.h Mon Dec 28 11:06:11 1998 @@ -48,6 +48,7 @@ #define MDL_ES1868MIDI 14 /* MIDI port of ESS1868 */ #define MDL_AEDSP 15 /* Audio Excel DSP 16 */ +#define SUBMDL_ES188X 0x10 /* Subtype ES188X for specific handling */ #define SUBMDL_ALS007 42 /* ALS-007 differs from SB16 only in mixer */ /* register assignment */ /* diff -u --recursive --new-file v2.1.132/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c --- v2.1.132/linux/drivers/sound/sb_common.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/sound/sb_common.c Mon Dec 28 11:06:11 1998 @@ -13,6 +13,8 @@ /* * Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts * for full duplex support ( only sb16 by now ) + * Rolf Fokkens: Added (BETA?) support for ES188x chips. + * (fokkensr@vertis.nl) Which means: You can adjust the recording levels. */ #include #include @@ -484,6 +486,24 @@ #endif } +/* + * ESS technology describes a detection scheme in their docs. It involves + * fiddling with the bits in certain mixer registers. ess_probe is supposed + * to help. + */ +static int ess_probe (sb_devc * devc, int reg, int xorval) +{ + int val1, val2, val3; + + val1 = sb_getmixer (devc, reg); + val2 = val1 ^ xorval; + sb_setmixer (devc, reg, val2); + val3 = sb_getmixer (devc, reg); + sb_setmixer (devc, reg, val1); + + return (val2 == val3); +} + static int ess_init(sb_devc * devc, struct address_info *hw_config) { unsigned char cfg, irq_bits = 0, dma_bits = 0; @@ -522,12 +542,31 @@ devc->model = MDL_SBPRO; return 1; } - else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) + + /* + * This the detection heuristic of ESS technology, though somewhat + * changed to actually make it work. + * This is the most BETA part of the software: Will the detection + * always work? + */ + devc->model = MDL_ESS; + devc->submodel = ess_minor & 0x0f; + + if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) { char *chip = "ES688"; - if ((ess_minor & 0x0f) >= 8) - chip = "ES1688"; + if ((ess_minor & 0x0f) >= 8) { + if ( !ess_probe (devc, 0x64, (1 << 3)) + && ess_probe (devc, 0x70, 0x7f)) { + chip = "ES188x"; + devc->submodel = SUBMDL_ES188X; + } else { + chip = "ES1688"; + }; + } else { + chip = "ES688"; + }; sprintf(name,"ESS %s AudioDrive (rev %d)", chip, ess_minor & 0x0f); @@ -535,8 +574,6 @@ else strcpy(name, "Jazz16"); - devc->model = MDL_ESS; - devc->submodel = ess_minor & 0x0f; hw_config->name = name; sb_dsp_reset(devc); /* Turn on extended mode */ @@ -998,19 +1035,28 @@ /* * Mixer access routines + * + * ES188x modifications: some mixer registers reside in the + * range above 0xa0. These must be accessed in another way. */ void sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value) { unsigned long flags; + /* MDB(printk("ESS: write port %x: %x\n", port, value)); */ + save_flags(flags); cli(); - outb(((unsigned char) (port & 0xff)), MIXER_ADDR); - - udelay(20); - outb(((unsigned char) (value & 0xff)), MIXER_DATA); - udelay(20); + if (devc->model == MDL_ESS && port >= 0xa0 && port <= 0xbf) { + ess_write (devc, port, value); + } else { + outb(((unsigned char) (port & 0xff)), MIXER_ADDR); + + udelay(20); + outb(((unsigned char) (value & 0xff)), MIXER_DATA); + udelay(20); + }; restore_flags(flags); } diff -u --recursive --new-file v2.1.132/linux/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c --- v2.1.132/linux/drivers/sound/sb_mixer.c Fri Oct 23 22:01:22 1998 +++ linux/drivers/sound/sb_mixer.c Mon Dec 28 11:06:11 1998 @@ -13,6 +13,24 @@ * * * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) + * Rolf Fokkens : ES188x recording level support + */ + +/* + * About ES188x support: + * + * The standard ES1688 support doesn't take care of the ES188x recording + * levels very well. Whenever a device is selected (recmask) for recording + * it's recording level is loud, and it cannot be changed. + * + * The ES188x has separate registers to control the recording levels. The + * ES188x specific software makes these level the same as their corresponding + * playback levels, unless recmask says they aren't recorded. In the latter + * case the recording volumes are 0. + * + * Now recording levels of inputs can be controlled, by changing the playback + * levels. Futhermore several devices can be recorded together (which is not + * possible with the ES1688. */ #include @@ -78,22 +96,62 @@ sb_mixer_reset(devc); } -static int smw_mixer_set(sb_devc * devc, int dev, int value) +static int common_mixer_set(sb_devc * devc, int dev, int left, int right) { - int left = value & 0x000000ff; - int right = (value & 0x0000ff00) >> 8; - int reg, val; + int regoffs; + unsigned char val; - if (left > 100) - left = 100; - if (right > 100) - right = 100; + regoffs = (*devc->iomap)[dev][LEFT_CHN].regno; - if (dev > 31) + if (regoffs == 0) return -EINVAL; - if (!(devc->supported_devices & (1 << dev))) /* Not supported */ - return -EINVAL; + val = sb_getmixer(devc, regoffs); + change_bits(devc, &val, dev, LEFT_CHN, left); + + devc->levels[dev] = left | (left << 8); + + if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /* + * Change register + */ + { + sb_setmixer(devc, regoffs, val); /* + * Save the old one + */ + regoffs = (*devc->iomap)[dev][RIGHT_CHN].regno; + + if (regoffs == 0) + return left | (left << 8); /* + * Just left channel present + */ + + val = sb_getmixer(devc, regoffs); /* + * Read the new one + */ + } + change_bits(devc, &val, dev, RIGHT_CHN, right); + + sb_setmixer(devc, regoffs, val); + + devc->levels[dev] = left | (right << 8); + return left | (right << 8); +} + +/* + * Changing playback levels at ES188x means having to take care of recording + * levels of recorded inputs (devc->recmask) too! + */ +static int es188x_mixer_set(sb_devc * devc, int dev, int left, int right) +{ + if (devc->recmask & (1 << dev)) { + common_mixer_set(devc, dev + ES188X_MIXER_RECDIFF, left, right); + } + return common_mixer_set(devc, dev, left, right); +} + +static int smw_mixer_set(sb_devc * devc, int dev, int left, int right) +{ + int reg, val; switch (dev) { @@ -134,12 +192,6 @@ int left = value & 0x000000ff; int right = (value & 0x0000ff00) >> 8; - int regoffs; - unsigned char val; - - if (devc->model == MDL_SMW) - return smw_mixer_set(devc, dev, value); - if (left > 100) left = 100; if (right > 100) @@ -153,47 +205,60 @@ */ return -EINVAL; - regoffs = (*devc->iomap)[dev][LEFT_CHN].regno; - - if (regoffs == 0) - return -EINVAL; - - val = sb_getmixer(devc, regoffs); - change_bits(devc, &val, dev, LEFT_CHN, left); - - devc->levels[dev] = left | (left << 8); - - if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /* - * Change register - */ - { - sb_setmixer(devc, regoffs, val); /* - * Save the old one - */ - regoffs = (*devc->iomap)[dev][RIGHT_CHN].regno; - - if (regoffs == 0) - return left | (left << 8); /* - * Just left channel present - */ - - val = sb_getmixer(devc, regoffs); /* - * Read the new one - */ + /* Differentiate dependong on the chipsets */ + switch (devc->model) { + case MDL_SMW: + return smw_mixer_set(devc, dev, left, right); + break; + case MDL_ESS: + if (devc->submodel == SUBMDL_ES188X) { + return es188x_mixer_set(devc, dev, left, right); + } + break; } - change_bits(devc, &val, dev, RIGHT_CHN, right); - sb_setmixer(devc, regoffs, val); - - devc->levels[dev] = left | (right << 8); - return left | (right << 8); + return common_mixer_set(devc, dev, left, right); } +/* + * set_recsrc doesn't apply to ES188x + */ static void set_recsrc(sb_devc * devc, int src) { sb_setmixer(devc, RECORD_SRC, (sb_getmixer(devc, RECORD_SRC) & ~7) | (src & 0x7)); } +/* + * Changing the recmask on a ES188x means: + * (1) Find the differences + * (2) For "turned-on" inputs: make the recording level the playback level + * (3) For "turned-off" inputs: make the recording level zero + */ +static int es188x_set_recmask(sb_devc * devc, int mask) +{ + int i, i_mask, cur_mask, diff_mask; + int value, left, right; + + cur_mask = devc->recmask; + diff_mask = (cur_mask ^ mask); + + for (i = 0; i < 32; i++) { + i_mask = (1 << i); + if (diff_mask & i_mask) { /* Difference? (1) */ + if (mask & i_mask) { /* Turn it on (2) */ + value = devc->levels[i]; + left = value & 0x000000ff; + right = (value & 0x0000ff00) >> 8; + } else { /* Turn it off (3) */ + left = 0; + right = 0; + } + common_mixer_set(devc, i + ES188X_MIXER_RECDIFF, left, right); + } + } + return mask; +} + static int set_recmask(sb_devc * devc, int mask) { int devmask, i; @@ -207,6 +272,14 @@ case MDL_ESS: case MDL_JAZZ: case MDL_SMW: + if (devc->model == MDL_ESS && + devc->submodel == SUBMDL_ES188X) { + /* + * ES188x needs a separate approach + */ + devmask = es188x_set_recmask(devc, devmask); + break; + }; if (devmask != SOUND_MASK_MIC && devmask != SOUND_MASK_LINE && @@ -423,7 +496,7 @@ static void sb_mixer_reset(sb_devc * devc) { char name[32]; - int i; + int i, regval; extern int sm_games; sprintf(name, "SB_%d", devc->sbmixnum); @@ -435,6 +508,24 @@ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) sb_mixer_set(devc, i, devc->levels[i]); + + /* + * Separate actions for ES188x: + * Change registers 7a and 1c to make the record mixer the + * actual recording source. + * Then call set_recmask twice to do extra ES188x initializations + */ + if (devc->model == MDL_ESS && devc->submodel == SUBMDL_ES188X) { + regval = sb_getmixer(devc, 0x7a); + regval = (regval & 0xe7) | 0x08; + sb_setmixer(devc, 0x7a, regval); + regval = sb_getmixer(devc, 0x1c); + regval = (regval & 0xf8) | 0x07; + sb_setmixer(devc, 0x1c, regval); + + set_recmask(devc, ES188X_RECORDING_DEVICES); + set_recmask(devc, 0); + } set_recmask(devc, SOUND_MASK_MIC); } @@ -464,9 +555,26 @@ case MDL_ESS: devc->mixer_caps = SOUND_CAP_EXCL_INPUT; - devc->supported_devices = ES688_MIXER_DEVICES; - devc->supported_rec_devices = ES688_RECORDING_DEVICES; - devc->iomap = &es688_mix; + + /* + * Take care of ES188x specifics... + */ + switch (devc->submodel) { + case SUBMDL_ES188X: + devc->supported_devices + = ES188X_MIXER_DEVICES; + devc->supported_rec_devices + = ES188X_RECORDING_DEVICES; + devc->iomap = &es188x_mix; + break; + default: + devc->supported_devices + = ES688_MIXER_DEVICES; + devc->supported_rec_devices + = ES688_RECORDING_DEVICES; + devc->iomap = &es688_mix; + } + break; case MDL_SMW: diff -u --recursive --new-file v2.1.132/linux/drivers/sound/sb_mixer.h linux/drivers/sound/sb_mixer.h --- v2.1.132/linux/drivers/sound/sb_mixer.h Thu Nov 12 16:21:22 1998 +++ linux/drivers/sound/sb_mixer.h Mon Dec 28 11:06:11 1998 @@ -15,7 +15,11 @@ * Modified: * Hunyue Yau Jan 6 1994 * Added defines for the Sound Galaxy NX Pro mixer. - * + * + * Rolf Fokkens Dec 20 1998 + * Added (BETA?) support for ES188x chips. + * Which means: you can adjust the recording levels. + * */ #include #include "legacy.h" @@ -47,6 +51,10 @@ #define ES688_RECORDING_DEVICES SBPRO_RECORDING_DEVICES #define ES688_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_LINE2|SOUND_MASK_SPEAKER) +#define ES188X_RECORDING_DEVICES (ES688_RECORDING_DEVICES | SOUND_MASK_LINE2 \ + |SOUND_MASK_SYNTH) +#define ES188X_MIXER_DEVICES (ES688_MIXER_DEVICES) + #define SB16_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \ SOUND_MASK_CD | \ SOUND_MASK_IGAIN | SOUND_MASK_OGAIN | \ @@ -110,6 +118,31 @@ #define RIGHT_CHN 1 /* + * Mixer registers of ES188x + * + * These register specifically take care of recording levels. To make the + * mapping from playback devices to recording devices every recording + * devices = playback device + ES188X_MIXER_RECDIFF + */ +#define ES188X_MIXER_RECBASE (SOUND_MIXER_LINE3 + 1) +#define ES188X_MIXER_RECDIFF (ES188X_MIXER_RECBASE - SOUND_MIXER_SYNTH) + +#define ES188X_MIXER_RECSYNTH (SOUND_MIXER_SYNTH + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECPCM (SOUND_MIXER_PCM + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECSPEAKER (SOUND_MIXER_SPEAKER + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECLINE (SOUND_MIXER_LINE + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECMIC (SOUND_MIXER_MIC + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECCD (SOUND_MIXER_CD + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECIMIX (SOUND_MIXER_IMIX + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECALTPCM (SOUND_MIXER_ALTPCM + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECRECLEV (SOUND_MIXER_RECLEV + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECIGAIN (SOUND_MIXER_IGAIN + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECOGAIN (SOUND_MIXER_OGAIN + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECLINE1 (SOUND_MIXER_LINE1 + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECLINE2 (SOUND_MIXER_LINE2 + ES188X_MIXER_RECDIFF) +#define ES188X_MIXER_RECLINE3 (SOUND_MIXER_LINE3 + ES188X_MIXER_RECDIFF) + +/* * Mixer registers of ALS007 */ #define ALS007_RECORD_SRC 0x6c @@ -152,6 +185,50 @@ MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0), MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4), MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0) +}; + +/* + * The ES188x specifics. + * Note that de master volume unlike ES688 is now controlled by two 6 bit + * registers. These seem to work OK on 1868 too, but I have no idea if it's + * compatible to 688 or 1688.... + * Also Note that the recording levels (ES188X_MIXER_REC...) have own + * entries as if they were playback devices. They are used internally in the + * driver only! + */ +static mixer_tab es188x_mix = { +MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6), +MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4), +MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4), +MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4), +MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4), +MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4), +MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4), +MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(ES188X_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4), +MIX_ENT(ES188X_MIXER_RECPCM, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(ES188X_MIXER_RECSPEAKER,0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(ES188X_MIXER_RECLINE, 0x6e, 7, 4, 0x6e, 3, 4), +MIX_ENT(ES188X_MIXER_RECMIC, 0x68, 7, 4, 0x68, 3, 4), +MIX_ENT(ES188X_MIXER_RECCD, 0x6a, 7, 4, 0x6a, 3, 4), + +MIX_ENT(ES188X_MIXER_RECIMIX, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(ES188X_MIXER_RECALTPCM, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(ES188X_MIXER_RECRECLEV, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(ES188X_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(ES188X_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(ES188X_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(ES188X_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4), +MIX_ENT(ES188X_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0) }; #ifdef __SGNXPRO__ diff -u --recursive --new-file v2.1.132/linux/drivers/sound/softoss_rs.c linux/drivers/sound/softoss_rs.c --- v2.1.132/linux/drivers/sound/softoss_rs.c Thu May 14 19:47:42 1998 +++ linux/drivers/sound/softoss_rs.c Sun Dec 27 10:53:45 1998 @@ -49,7 +49,7 @@ #endif /* Interpolation (resolution of 512 steps) */ { - int fract = v->ptr & 0x1f; /* 9 bits */ + int fract = v->ptr & 0x1ff; /* 9 bits */ /* This method works with less arithmetic operations */ register int v1 = v->wave[ix]; diff -u --recursive --new-file v2.1.132/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c --- v2.1.132/linux/drivers/sound/sonicvibes.c Tue Dec 22 14:16:56 1998 +++ linux/drivers/sound/sonicvibes.c Sun Dec 27 10:53:45 1998 @@ -48,6 +48,7 @@ * "OSS documented" and "OSS actual" behaviour * 31.08.98 0.7 Fix realplayer problems - dac.count issues * 10.12.98 0.8 Fix drain_dac trying to wait on not yet initialized DMA + * 16.12.98 0.9 Fix a few f_file & FMODE_ bugs * */ @@ -764,17 +765,14 @@ s->dma_adc.hwptr = hwptr; s->dma_adc.total_bytes += diff; s->dma_adc.count += diff; - if (s->dma_adc.mapped) { - if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) - wake_up(&s->dma_adc.wait); - } else { + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + wake_up(&s->dma_adc.wait); + if (!s->dma_adc.mapped) { if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { s->enable &= ~SV_CENABLE_RE; wrindir(s, SV_CIENABLE, s->enable); s->dma_adc.error++; } - if (s->dma_adc.count > 0) - wake_up(&s->dma_adc.wait); } } /* update DAC pointer */ @@ -797,7 +795,7 @@ clear_advance(s); s->dma_dac.endcleared = 1; } - if (s->dma_dac.count < (signed)s->dma_dac.dmasize) + if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) wake_up(&s->dma_dac.wait); } } @@ -1382,27 +1380,22 @@ unsigned int mask = 0; VALIDATE_STATE(s); - if (file->f_flags & FMODE_WRITE) + if (file->f_mode & FMODE_WRITE) poll_wait(file, &s->dma_dac.wait, wait); - if (file->f_flags & FMODE_READ) + if (file->f_mode & FMODE_READ) poll_wait(file, &s->dma_adc.wait, wait); spin_lock_irqsave(&s->lock, flags); sv_update_ptr(s); - if (file->f_flags & FMODE_READ) { - if (s->dma_adc.mapped) { - if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) - mask |= POLLIN | POLLRDNORM; - } else { - if (s->dma_adc.count > 0) - mask |= POLLIN | POLLRDNORM; - } + if (file->f_mode & FMODE_READ) { + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + mask |= POLLIN | POLLRDNORM; } - if (file->f_flags & FMODE_WRITE) { + if (file->f_mode & FMODE_WRITE) { if (s->dma_dac.mapped) { if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) mask |= POLLOUT | POLLWRNORM; } else { - if ((signed)s->dma_dac.dmasize > s->dma_dac.count) + if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize) mask |= POLLOUT | POLLWRNORM; } } @@ -1786,11 +1779,11 @@ if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); - if (file->f_flags & FMODE_WRITE) { + if (file->f_mode & FMODE_WRITE) { stop_dac(s); dealloc_dmabuf(&s->dma_dac); } - if (file->f_flags & FMODE_READ) { + if (file->f_mode & FMODE_READ) { stop_adc(s); dealloc_dmabuf(&s->dma_adc); } @@ -1923,16 +1916,16 @@ unsigned int mask = 0; VALIDATE_STATE(s); - if (file->f_flags & FMODE_WRITE) + if (file->f_mode & FMODE_WRITE) poll_wait(file, &s->midi.owait, wait); - if (file->f_flags & FMODE_READ) + if (file->f_mode & FMODE_READ) poll_wait(file, &s->midi.iwait, wait); spin_lock_irqsave(&s->lock, flags); - if (file->f_flags & FMODE_READ) { + if (file->f_mode & FMODE_READ) { if (s->midi.icnt > 0) mask |= POLLIN | POLLRDNORM; } - if (file->f_flags & FMODE_WRITE) { + if (file->f_mode & FMODE_WRITE) { if (s->midi.ocnt < MIDIOUTBUF) mask |= POLLOUT | POLLWRNORM; } @@ -2278,7 +2271,7 @@ if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "sv: version v0.8 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "sv: version v0.9 time " __TIME__ " " __DATE__ "\n"); #if 0 if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT))) printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n"); diff -u --recursive --new-file v2.1.132/linux/drivers/sound/trix.c linux/drivers/sound/trix.c --- v2.1.132/linux/drivers/sound/trix.c Thu Sep 17 17:53:37 1998 +++ linux/drivers/sound/trix.c Sun Dec 27 10:53:45 1998 @@ -26,6 +26,7 @@ #ifdef CONFIG_TRIX #ifdef INCLUDE_TRIX_BOOT +#include #include "trix_boot.h" #else static unsigned char *trix_boot = NULL; diff -u --recursive --new-file v2.1.132/linux/fs/Config.in linux/fs/Config.in --- v2.1.132/linux/fs/Config.in Thu Nov 19 09:56:28 1998 +++ linux/fs/Config.in Sun Dec 27 10:50:12 1998 @@ -5,23 +5,53 @@ comment 'Filesystems' bool 'Quota support' CONFIG_QUOTA +tristate 'Kernel automounter support' CONFIG_AUTOFS_FS -tristate 'Minix fs support' CONFIG_MINIX_FS -tristate 'Second extended fs support' CONFIG_EXT2_FS + +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS +fi +tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS +tristate 'Apple Macintosh filesystem support (experimental)' CONFIG_HFS_FS +# msdos filesystems +tristate 'DOS FAT fs support' CONFIG_FAT_FS +dep_tristate ' MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS +dep_tristate ' UMSDOS: Unix-like filesystem on top of standard MSDOS filesystem' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS +dep_tristate ' VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS tristate 'ISO 9660 CDROM filesystem support' CONFIG_ISO9660_FS if [ "$CONFIG_ISO9660_FS" != "n" ]; then bool 'Microsoft Joliet CDROM extensions' CONFIG_JOLIET fi -# msdos filesystems -tristate 'DOS FAT fs support' CONFIG_FAT_FS -dep_tristate 'MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS -dep_tristate 'UMSDOS: Unix-like filesystem on top of standard MSDOS filesystem' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS -dep_tristate 'VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS - +tristate 'Minix fs support' CONFIG_MINIX_FS +tristate 'NTFS filesystem support (read only)' CONFIG_NTFS_FS +if [ "$CONFIG_NTFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' NTFS read-write support (experimental)' CONFIG_NTFS_RW +fi +tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS bool '/proc filesystem support' CONFIG_PROC_FS +if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then + tristate '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS +fi +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'QNX filesystem support (EXPERIMENTAL)' CONFIG_QNX4FS_FS + if [ "$CONFIG_QNX4FS_FS" != "n" ]; then + bool ' QNXFS read-write support (FOR TESTING ONLY)' CONFIG_QNX4FS_RW + fi +fi +tristate 'ROM filesystem support' CONFIG_ROMFS_FS +tristate 'Second extended fs support' CONFIG_EXT2_FS +tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS +tristate 'UFS filesystem support' CONFIG_UFS_FS + + + +mainmenu_option next_comment +comment 'Network File Systems' + if [ "$CONFIG_INET" = "y" ]; then + tristate 'Coda filesystem support (advanced network fs)' CONFIG_CODA_FS tristate 'NFS filesystem support' CONFIG_NFS_FS if [ "$CONFIG_NFS_FS" = "y" -a "$CONFIG_IP_PNP" = "y" ]; then bool ' Root file system on NFS' CONFIG_ROOT_NFS @@ -42,7 +72,6 @@ define_bool CONFIG_LOCKD n fi fi - tristate 'Coda filesystem support (advanced network fs)' CONFIG_CODA_FS tristate 'SMB filesystem support (to mount WfW shares etc.)' CONFIG_SMB_FS if [ "$CONFIG_SMB_FS" != "n" ]; then bool 'SMB Win95 bug work-around' CONFIG_SMB_WIN95 @@ -54,34 +83,23 @@ source fs/ncpfs/Config.in fi fi -tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS -tristate 'NTFS filesystem support (read only)' CONFIG_NTFS_FS -if [ "$CONFIG_NTFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' NTFS read-write support (experimental)' CONFIG_NTFS_RW -fi +endmenu -tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS -tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS -tristate 'Apple Macintosh filesystem support (experimental)' CONFIG_HFS_FS -tristate 'ROM filesystem support' CONFIG_ROMFS_FS -tristate 'Kernel automounter support' CONFIG_AUTOFS_FS if [ "$CONFIG_AFFS_FS" != "n" ]; then define_bool CONFIG_AMIGA_PARTITION y fi -tristate 'UFS filesystem support' CONFIG_UFS_FS + +mainmenu_option next_comment +comment 'Partition Types' + bool 'BSD disklabel (BSD partition tables) support' CONFIG_BSD_DISKLABEL +bool 'Macintosh partition map support' CONFIG_MAC_PARTITION bool 'SMD disklabel (Sun partition tables) support' CONFIG_SMD_DISKLABEL bool 'Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION -if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then - tristate '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS -fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS - tristate 'QNX filesystem support (EXPERIMENTAL)' CONFIG_QNX4FS_FS - if [ "$CONFIG_QNX4FS_FS" != "n" ]; then - bool ' QNXFS read-write support (FOR TESTING ONLY)' CONFIG_QNX4FS_RW - fi + bool 'Unixware slices support (EXPERIMENTAL)' CONFIG_UNIXWARE_DISKLABEL fi -bool 'Macintosh partition map support' CONFIG_MAC_PARTITION +endmenu + endmenu diff -u --recursive --new-file v2.1.132/linux/fs/autofs/waitq.c linux/fs/autofs/waitq.c --- v2.1.132/linux/fs/autofs/waitq.c Thu Nov 19 09:56:28 1998 +++ linux/fs/autofs/waitq.c Mon Dec 28 00:47:48 1998 @@ -103,6 +103,10 @@ struct autofs_wait_queue *wq; int status; + /* In catatonic mode, we don't wait for nobody */ + if ( sbi->catatonic ) + return -ENOENT; + for ( wq = sbi->queues ; wq ; wq = wq->next ) { if ( wq->hash == name->hash && wq->len == name->len && @@ -137,6 +141,15 @@ wq->wait_ctr++; /* wq->name is NULL if and only if the lock is already released */ + + if ( sbi->catatonic ) { + /* We might have slept, so check again for catatonic mode */ + wq->status = -ENOENT; + if ( wq->name ) { + kfree(wq->name); + wq->name = NULL; + } + } if ( wq->name ) { /* Block all but "shutdown" signals while waiting */ diff -u --recursive --new-file v2.1.132/linux/fs/binfmt_misc.c linux/fs/binfmt_misc.c --- v2.1.132/linux/fs/binfmt_misc.c Wed Aug 26 11:37:40 1998 +++ linux/fs/binfmt_misc.c Sun Dec 27 10:52:09 1998 @@ -15,6 +15,7 @@ * 1997-08-09 removed extension stripping, locking cleanup */ +#include #include #include @@ -451,7 +452,9 @@ */ static void entry_proc_cleanup(struct binfmt_entry *e) { +#ifdef CONFIG_PROC_FS remove_proc_entry(e->proc_name, bm_dir); +#endif } /* @@ -459,6 +462,7 @@ */ static int entry_proc_setup(struct binfmt_entry *e) { +#ifdef CONFIG_PROC_FS if (!(e->proc_dir = create_proc_entry(e->proc_name, S_IFREG | S_IRUGO | S_IWUSR, bm_dir))) return -ENOMEM; @@ -466,7 +470,7 @@ e->proc_dir->data = (void *) (e->id); e->proc_dir->read_proc = proc_read_status; e->proc_dir->write_proc = proc_write_status; - +#endif return 0; } @@ -490,8 +494,9 @@ int __init init_misc_binfmt(void) { - struct proc_dir_entry *status = NULL, *reg; int error = -ENOMEM; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *status = NULL, *reg; bm_dir = create_proc_entry("sys/fs/binfmt_misc", S_IFDIR, NULL); if (!bm_dir) @@ -511,6 +516,7 @@ if (!reg) goto cleanup_status; reg->write_proc = proc_write_register; +#endif /* CONFIG_PROC_FS */ error = register_binfmt(&misc_format); out: diff -u --recursive --new-file v2.1.132/linux/fs/buffer.c linux/fs/buffer.c --- v2.1.132/linux/fs/buffer.c Tue Dec 22 14:16:57 1998 +++ linux/fs/buffer.c Wed Dec 23 09:44:41 1998 @@ -1836,7 +1836,8 @@ if (buffer_locked(bh) || !buffer_dirty(bh)) continue; ndirty++; - if(bh->b_flushtime > jiffies) continue; + if(time_before(jiffies, bh->b_flushtime)) + continue; nwritten++; next->b_count++; bh->b_count++; diff -u --recursive --new-file v2.1.132/linux/fs/dcache.c linux/fs/dcache.c --- v2.1.132/linux/fs/dcache.c Tue Dec 22 14:16:57 1998 +++ linux/fs/dcache.c Mon Dec 28 00:35:12 1998 @@ -592,9 +592,10 @@ struct list_head *head = d_hash(parent,hash); struct list_head *tmp = head->next; - while (tmp != head) { + for (;;) { struct dentry * dentry = list_entry(tmp, struct dentry, d_hash); - + if (tmp == head) + break; tmp = tmp->next; if (dentry->d_name.hash != hash) continue; diff -u --recursive --new-file v2.1.132/linux/fs/devices.c linux/fs/devices.c --- v2.1.132/linux/fs/devices.c Wed Aug 26 11:37:40 1998 +++ linux/fs/devices.c Wed Dec 23 11:39:49 1998 @@ -210,11 +210,11 @@ return 0; printk(KERN_DEBUG "VFS: Disk change detected on device %s\n", - kdevname(dev)); + bdevname(dev)); sb = get_super(dev); if (sb && invalidate_inodes(sb)) - printk("VFS: busy inodes on changed media..\n"); + printk("VFS: busy inodes on changed media.\n"); invalidate_buffers(dev); @@ -338,13 +338,35 @@ }; /* - * Print device name (in decimal, hexadecimal or symbolic) - - * at present hexadecimal only. + * Print device name (in decimal, hexadecimal or symbolic) * Note: returns pointer to static data! */ char * kdevname(kdev_t dev) { static char buffer[32]; sprintf(buffer, "%02x:%02x", MAJOR(dev), MINOR(dev)); + return buffer; +} + +char * bdevname(kdev_t dev) +{ + static char buffer[32]; + const char * name = blkdevs[MAJOR(dev)].name; + + if (!name) + name = "unknown-block"; + + sprintf(buffer, "%s(%d,%d)", name, MAJOR(dev), MINOR(dev)); + return buffer; +} + +char * cdevname(kdev_t dev) +{ + static char buffer[32]; + const char * name = chrdevs[MAJOR(dev)].name; + + if (!name) + name = "unknown-char"; + sprintf(buffer, "%s(%d,%d)", name, MAJOR(dev), MINOR(dev)); return buffer; } diff -u --recursive --new-file v2.1.132/linux/fs/fat/file.c linux/fs/fat/file.c --- v2.1.132/linux/fs/fat/file.c Wed Aug 26 11:37:40 1998 +++ linux/fs/fat/file.c Sun Dec 27 10:47:18 1998 @@ -375,6 +375,12 @@ *ppos = inode->i_size; if (count == 0) return 0; + if (*ppos + count > 0x7FFFFFFFLL) { + count = 0x7FFFFFFFLL-*ppos; + if (!count) + return -EFBIG; + } + error = carry = 0; for (start = buf; count || carry; count -= size) { while (!(sector = fat_smap(inode,*ppos >> SECTOR_BITS))) diff -u --recursive --new-file v2.1.132/linux/fs/fat/inode.c linux/fs/fat/inode.c --- v2.1.132/linux/fs/fat/inode.c Thu Nov 19 09:56:28 1998 +++ linux/fs/fat/inode.c Mon Dec 28 13:56:29 1998 @@ -428,7 +428,7 @@ MSDOS_SB(sb)->fat_bits,opts.name_check, opts.conversion,opts.fs_uid,opts.fs_gid,opts.fs_umask, MSDOS_CAN_BMAP(MSDOS_SB(sb)) ? ",bmap" : ""); - printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d," + printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%ld,ds=%ld,de=%d,data=%ld," "se=%d,ts=%ld,ls=%d,rc=%ld,fc=%u]\n", b->media,MSDOS_SB(sb)->cluster_size, MSDOS_SB(sb)->fats,MSDOS_SB(sb)->fat_start, diff -u --recursive --new-file v2.1.132/linux/fs/file_table.c linux/fs/file_table.c --- v2.1.132/linux/fs/file_table.c Thu Nov 19 09:56:28 1998 +++ linux/fs/file_table.c Wed Dec 23 11:57:17 1998 @@ -20,7 +20,7 @@ /* Free list management, if you are here you must have f_count == 0 */ static struct file * free_filps = NULL; -void insert_file_free(struct file *file) +static void insert_file_free(struct file *file) { if((file->f_next = free_filps) != NULL) free_filps->f_pprev = &file->f_next; @@ -40,6 +40,15 @@ file->f_pprev = &inuse_filps; } +/* It does not matter which list it is on. */ +static inline void remove_filp(struct file *file) +{ + if(file->f_next) + file->f_next->f_pprev = file->f_pprev; + *file->f_pprev = file->f_next; +} + + void __init file_table_init(void) { filp_cache = kmem_cache_create("filp", sizeof(struct file), @@ -115,4 +124,26 @@ return filp->f_op->open(dentry->d_inode, filp); else return 0; +} + +void fput(struct file *file) +{ + int count = file->f_count-1; + + if (!count) { + locks_remove_flock(file); + __fput(file); + file->f_count = 0; + remove_filp(file); + insert_file_free(file); + } else + file->f_count = count; +} + +void put_filp(struct file *file) +{ + if(--file->f_count == 0) { + remove_filp(file); + insert_file_free(file); + } } diff -u --recursive --new-file v2.1.132/linux/fs/hfs/ChangeLog linux/fs/hfs/ChangeLog --- v2.1.132/linux/fs/hfs/ChangeLog Fri Nov 27 13:09:28 1998 +++ linux/fs/hfs/ChangeLog Wed Dec 23 14:10:36 1998 @@ -1,3 +1,24 @@ +1998-12-20 a sun + + * bdelete.c (del_root): assign bthLNode and bthFNode only if the + root node becomes a leaf node. Disk First Aid no longer + complains. Norton Utilities, of course, has decided that it + doesn't like the root node number. bleah. i think that it might be + due to Norton Utilities not expecting the root node to have moved. + +1998-12-16 a sun + + * sysdep.c (hfs_revalidate_dentry): fix inode dates when there's a + timezone change. + +1998-12-15 root + + * extent.c (new_extent): expand block size variables to handle + u32. + + * mdb.c (hfs_mdb_get): AlBlkSiz shouldn't be capped at 65535. we + should be able to handle much larger volumes now. + 1998-11-21 a sun * hfs_sysdep.h, hfs_fs.h: added hfs_from_utc/to_utc to deal with diff -u --recursive --new-file v2.1.132/linux/fs/hfs/bdelete.c linux/fs/hfs/bdelete.c --- v2.1.132/linux/fs/hfs/bdelete.c Sun Jan 4 10:40:17 1998 +++ linux/fs/hfs/bdelete.c Wed Dec 23 14:10:36 1998 @@ -135,11 +135,16 @@ tree->bthRoot = child.bn->node; tree->root = child.bn; + + /* re-assign bthFNode and bthLNode if the new root is + a leaf node. */ + if (child.bn->ndType == ndLeafNode) { + tree->bthFNode = node; + tree->bthLNode = node; + } hfs_bnode_relse(&child); tree->bthRoot = node; - tree->bthFNode = node; - tree->bthLNode = node; --tree->bthDepth; tree->dirt = 1; if (!tree->bthDepth) { diff -u --recursive --new-file v2.1.132/linux/fs/hfs/extent.c linux/fs/hfs/extent.c --- v2.1.132/linux/fs/hfs/extent.c Thu Nov 19 09:56:28 1998 +++ linux/fs/hfs/extent.c Wed Dec 23 14:10:36 1998 @@ -354,7 +354,7 @@ * hfs_u16 ablock: the number of allocation blocks in 'fork'. * hfs_u16 start: first allocation block to add to 'fork'. * hfs_u16 len: the number of allocation blocks to add to 'fork'. - * hfs_u16 ablksz: number of sectors in an allocation block. + * hfs_u32 ablksz: number of sectors in an allocation block. * Output Variable(s): * NONE * Returns: @@ -471,7 +471,7 @@ struct hfs_mdb *mdb = fork->entry->mdb; struct hfs_extent *ext; int i, error, next, count; - hfs_u16 ablksz = mdb->alloc_blksz; + hfs_u32 ablksz = mdb->alloc_blksz; next = (fork->psize / ablksz) - 1; ext = find_ext(fork, next); @@ -530,7 +530,7 @@ struct hfs_extent *ext; int i, start, err; hfs_u16 need, len=0; - hfs_u16 ablksz = mdb->alloc_blksz; + hfs_u32 ablksz = mdb->alloc_blksz; hfs_u32 blocks, clumpablks; blocks = fork->psize; @@ -681,8 +681,7 @@ void hfs_extent_adj(struct hfs_fork *fork) { if (fork) { - hfs_u32 blks, ablocks; - hfs_u16 ablksz; + hfs_u32 blks, ablocks, ablksz; if (fork->lsize > HFS_FORK_MAX) { fork->lsize = HFS_FORK_MAX; diff -u --recursive --new-file v2.1.132/linux/fs/hfs/hfs.h linux/fs/hfs/hfs.h --- v2.1.132/linux/fs/hfs/hfs.h Sun Nov 8 14:03:06 1998 +++ linux/fs/hfs/hfs.h Wed Dec 23 14:10:36 1998 @@ -252,7 +252,7 @@ hfs_u16 free_ablocks; /* The number of unused allocation blocks in the filesystem */ - hfs_u16 alloc_blksz; /* The number of + hfs_u32 alloc_blksz; /* The number of 512-byte blocks per "allocation block" */ hfs_u16 attrib; /* Attribute word */ diff -u --recursive --new-file v2.1.132/linux/fs/hfs/inode.c linux/fs/hfs/inode.c --- v2.1.132/linux/fs/hfs/inode.c Sun Nov 8 14:03:06 1998 +++ linux/fs/hfs/inode.c Wed Dec 23 14:10:36 1998 @@ -260,6 +260,7 @@ memset(HFS_I(inode), 0, sizeof(struct hfs_inode_info)); HFS_I(inode)->magic = HFS_INO_MAGIC; HFS_I(inode)->entry = entry; + HFS_I(inode)->tz_secondswest = hfs_to_utc(0); hsb->s_ifill(inode, type); if (!hsb->s_afpd && (entry->type == HFS_CDR_FIL) && diff -u --recursive --new-file v2.1.132/linux/fs/hfs/mdb.c linux/fs/hfs/mdb.c --- v2.1.132/linux/fs/hfs/mdb.c Thu Nov 19 09:56:28 1998 +++ linux/fs/hfs/mdb.c Wed Dec 23 14:10:36 1998 @@ -118,7 +118,7 @@ mdb->buf = buf; bs = hfs_get_hl(raw->drAlBlkSiz); - if (!bs || bs > HFS_USHRT_MAX || (bs & (HFS_SECTOR_SIZE-1))) { + if (!bs || (bs & (HFS_SECTOR_SIZE-1))) { hfs_warn("hfs_fs: bad allocation block size %d != 512\n", bs); hfs_buffer_put(buf); HFS_DELETE(mdb); diff -u --recursive --new-file v2.1.132/linux/fs/hfs/sysdep.c linux/fs/hfs/sysdep.c --- v2.1.132/linux/fs/hfs/sysdep.c Sun Nov 8 14:03:06 1998 +++ linux/fs/hfs/sysdep.c Wed Dec 23 14:10:36 1998 @@ -18,12 +18,13 @@ #include #include +static int hfs_revalidate_dentry(struct dentry *); static int hfs_hash_dentry(struct dentry *, struct qstr *); static int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *); static void hfs_dentry_iput(struct dentry *, struct inode *); struct dentry_operations hfs_dentry_operations = { - NULL, /* d_validate(struct dentry *) */ + hfs_revalidate_dentry, /* d_revalidate(struct dentry *) */ hfs_hash_dentry, /* d_hash */ hfs_compare_dentry, /* d_compare */ NULL, /* d_delete(struct dentry *) */ @@ -86,4 +87,20 @@ entry->sys_entry[HFS_ITYPE_TO_INT(HFS_ITYPE(inode->i_ino))] = NULL; iput(inode); +} + +static int hfs_revalidate_dentry(struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + int diff; + + /* fix up inode on a timezone change */ + if (inode && + (diff = (hfs_to_utc(0) - HFS_I(inode)->tz_secondswest))) { + inode->i_ctime += diff; + inode->i_atime += diff; + inode->i_mtime += diff; + HFS_I(inode)->tz_secondswest += diff; + } + return 1; } diff -u --recursive --new-file v2.1.132/linux/fs/lockd/host.c linux/fs/lockd/host.c --- v2.1.132/linux/fs/lockd/host.c Wed Apr 23 19:01:26 1997 +++ linux/fs/lockd/host.c Wed Dec 23 09:44:42 1998 @@ -92,7 +92,7 @@ /* Lock hash table */ down(&nlm_host_sema); - if (next_gc < jiffies) + if (time_after(jiffies, next_gc)) nlm_gc_hosts(); for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) { @@ -173,7 +173,7 @@ /* If we've already created an RPC client, check whether * RPC rebind is required */ if ((clnt = host->h_rpcclnt) != NULL) { - if (host->h_nextrebind < jiffies) { + if (time_after(jiffies, host->h_nextrebind)) { clnt->cl_port = 0; host->h_nextrebind = jiffies + NLM_HOST_REBIND; dprintk("lockd: next rebind in %ld jiffies\n", @@ -219,7 +219,7 @@ nlm_rebind_host(struct nlm_host *host) { dprintk("lockd: rebind host %s\n", host->h_name); - if (host->h_rpcclnt && host->h_nextrebind < jiffies) { + if (host->h_rpcclnt && time_after(jiffies, host->h_nextrebind)) { host->h_rpcclnt->cl_port = 0; host->h_nextrebind = jiffies + NLM_HOST_REBIND; } @@ -298,7 +298,7 @@ q = &nlm_hosts[i]; while ((host = *q) != NULL) { if (host->h_count || host->h_inuse - || host->h_expires >= jiffies) { + || time_before_eq(jiffies, host->h_expires)) { q = &host->h_next; continue; } diff -u --recursive --new-file v2.1.132/linux/fs/lockd/svc.c linux/fs/lockd/svc.c --- v2.1.132/linux/fs/lockd/svc.c Thu Nov 12 16:21:22 1998 +++ linux/fs/lockd/svc.c Wed Dec 23 09:44:42 1998 @@ -136,7 +136,7 @@ */ if (!nlmsvc_grace_period) { timeout = nlmsvc_retry_blocked(); - } else if (nlmsvc_grace_period < jiffies) + } else if (time_after(jiffies, nlmsvc_grace_period)) nlmsvc_grace_period = 0; /* diff -u --recursive --new-file v2.1.132/linux/fs/locks.c linux/fs/locks.c --- v2.1.132/linux/fs/locks.c Thu Nov 19 09:56:28 1998 +++ linux/fs/locks.c Wed Dec 23 12:11:45 1998 @@ -154,10 +154,10 @@ static inline void locks_free_lock(struct file_lock *fl) { if (waitqueue_active(&fl->fl_wait)) - panic("Aarggh: attempting to free lock with active wait queue - shoot Andy"); + panic("Attempting to free lock with active wait queue"); if (fl->fl_nextblock != NULL || fl->fl_prevblock != NULL) - panic("Aarggh: attempting to free lock with active block list - shoot Andy"); + panic("Attempting to free lock with active block list"); kfree(fl); return; diff -u --recursive --new-file v2.1.132/linux/fs/namei.c linux/fs/namei.c --- v2.1.132/linux/fs/namei.c Tue Dec 22 14:16:57 1998 +++ linux/fs/namei.c Wed Dec 23 12:52:39 1998 @@ -95,18 +95,6 @@ * [10-Sep-98 Alan Modra] Another symlink change. */ -static inline char * get_page(void) -{ - char * res; - res = (char*)__get_free_page(GFP_KERNEL); - return res; -} - -inline void putname(char * name) -{ - free_page((unsigned long) name); -} - /* In order to reduce some races, while at the same time doing additional * checking and hopefully speeding things up, we copy filenames to the * kernel data space before using them.. @@ -139,7 +127,7 @@ char *tmp, *result; result = ERR_PTR(-ENOMEM); - tmp = get_page(); + tmp = __getname(); if (tmp) { int retval = do_getname(filename, tmp); diff -u --recursive --new-file v2.1.132/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- v2.1.132/linux/fs/ncpfs/inode.c Mon Apr 6 17:41:01 1998 +++ linux/fs/ncpfs/inode.c Wed Dec 23 11:57:17 1998 @@ -382,7 +382,12 @@ out_no_server: printk(KERN_ERR "ncp_read_super: could not alloc ncp_server\n"); out_unlock: - put_filp(ncp_filp); + /* 23/12/1998 Marcin Dalecki : + * + * The previously used put_filp(ncp_filp); was bogous, since + * it doesn't proper unlocking. + */ + fput(ncp_filp); unlock_super(sb); goto out; diff -u --recursive --new-file v2.1.132/linux/fs/nfs/dir.c linux/fs/nfs/dir.c --- v2.1.132/linux/fs/nfs/dir.c Tue Dec 22 14:16:57 1998 +++ linux/fs/nfs/dir.c Mon Dec 28 13:18:10 1998 @@ -438,6 +438,7 @@ /* Ok, remeber that we successfully checked it.. */ nfs_renew_times(dentry); + nfs_refresh_inode(inode, &fattr); out_valid: return 1; @@ -571,11 +572,6 @@ error = 0; } } -#ifdef NFS_PARANOIA -if (error) -printk("nfs_lookup: %s/%s failed, error=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, error); -#endif out: return error; } diff -u --recursive --new-file v2.1.132/linux/fs/nfs/inode.c linux/fs/nfs/inode.c --- v2.1.132/linux/fs/nfs/inode.c Tue Dec 22 14:16:57 1998 +++ linux/fs/nfs/inode.c Mon Dec 28 13:40:23 1998 @@ -701,12 +701,6 @@ #endif goto out; } - if (fattr.mtime.seconds == NFS_OLDMTIME(inode)) { - /* Update attrtimeo value */ - if ((NFS_ATTRTIMEO(inode) <<= 1) > NFS_MAXATTRTIMEO(inode)) - NFS_ATTRTIMEO(inode) = NFS_MAXATTRTIMEO(inode); - } - NFS_OLDMTIME(inode) = fattr.mtime.seconds; dfprintk(PAGECACHE, "NFS: %s/%s revalidation complete\n", dentry->d_parent->d_name.name, dentry->d_name.name); out: @@ -791,6 +785,14 @@ if (invalid) goto out_invalid; + + /* Update attrtimeo value */ + if (fattr->mtime.seconds == NFS_OLDMTIME(inode)) { + if ((NFS_ATTRTIMEO(inode) <<= 1) > NFS_MAXATTRTIMEO(inode)) + NFS_ATTRTIMEO(inode) = NFS_MAXATTRTIMEO(inode); + } + NFS_OLDMTIME(inode) = fattr->mtime.seconds; + out: return error; diff -u --recursive --new-file v2.1.132/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c --- v2.1.132/linux/fs/nfsd/nfsfh.c Sun Nov 8 14:03:07 1998 +++ linux/fs/nfsd/nfsfh.c Wed Dec 23 09:44:42 1998 @@ -1001,7 +1001,7 @@ * Perform any needed housekeeping ... * N.B. move this into one of the daemons ... */ - if (jiffies >= nfsd_next_expire) { + if (time_after_eq(jiffies, nfsd_next_expire)) { expire_old(NFSD_FILE_CACHE, 5*HZ); expire_old(NFSD_DIR_CACHE , 60*HZ); nfsd_next_expire = jiffies + 5*HZ; diff -u --recursive --new-file v2.1.132/linux/fs/open.c linux/fs/open.c --- v2.1.132/linux/fs/open.c Wed Dec 16 10:32:56 1998 +++ linux/fs/open.c Wed Dec 23 13:02:05 1998 @@ -6,14 +6,11 @@ #include #include -#include -#include #include #include #include #include -#include asmlinkage int sys_statfs(const char * path, struct statfs * buf) { @@ -671,18 +668,6 @@ return ERR_PTR(error); } -/* should probably go into sys_open() */ -static int do_open(const char * filename, int flags, int mode, int fd) -{ - struct file * f; - - f = filp_open(filename, flags, mode); - if (IS_ERR(f)) - return PTR_ERR(f); - fd_install(fd, f); - return 0; -} - /* * Find an empty file descriptor entry, and mark it busy. */ @@ -727,24 +712,25 @@ char * tmp; int fd, error; - lock_kernel(); - fd = get_unused_fd(); - if (fd < 0) - goto out; - tmp = getname(filename); - error = PTR_ERR(tmp); - if (IS_ERR(tmp)) - goto out_fail; - error = do_open(tmp, flags, mode, fd); - putname(tmp); - if (error) - goto out_fail; + fd = PTR_ERR(tmp); + if (!IS_ERR(tmp)) { + lock_kernel(); + fd = get_unused_fd(); + if (fd >= 0) { + struct file * f = filp_open(tmp, flags, mode); + error = PTR_ERR(f); + if (IS_ERR(f)) + goto out_error; + fd_install(fd, f); + } out: - unlock_kernel(); + unlock_kernel(); + putname(tmp); + } return fd; -out_fail: +out_error: put_unused_fd(fd); fd = error; goto out; diff -u --recursive --new-file v2.1.132/linux/fs/read_write.c linux/fs/read_write.c --- v2.1.132/linux/fs/read_write.c Thu Nov 19 09:56:29 1998 +++ linux/fs/read_write.c Sun Dec 27 10:52:09 1998 @@ -215,7 +215,8 @@ tot_len += iov[i].iov_len; inode = file->f_dentry->d_inode; - ret = locks_verify_area((type == VERIFY_READ + /* VERIFY_WRITE actually means a read, as we write to user space */ + ret = locks_verify_area((type == VERIFY_WRITE ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), inode, file, file->f_pos, tot_len); if (ret) goto out; diff -u --recursive --new-file v2.1.132/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- v2.1.132/linux/fs/smbfs/inode.c Mon Apr 6 17:41:01 1998 +++ linux/fs/smbfs/inode.c Wed Dec 23 09:44:42 1998 @@ -260,7 +260,7 @@ /* * Check whether we've recently refreshed the inode. */ - if (jiffies < inode->u.smbfs_i.oldmtime + HZ/10) + if (time_before(jiffies, inode->u.smbfs_i.oldmtime + HZ/10)) { #ifdef SMBFS_DEBUG_VERBOSE printk("smb_revalidate_inode: up-to-date, jiffies=%lu, oldtime=%lu\n", diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/atomic.h linux/include/asm-alpha/atomic.h --- v2.1.132/linux/include/asm-alpha/atomic.h Tue May 13 22:41:15 1997 +++ linux/include/asm-alpha/atomic.h Sun Dec 27 15:21:50 1998 @@ -15,7 +15,7 @@ typedef struct { int counter; } atomic_t; #endif -#define ATOMIC_INIT(i) { (i) } +#define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) ((v)->counter = (i)) diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/core_apecs.h linux/include/asm-alpha/core_apecs.h --- v2.1.132/linux/include/asm-alpha/core_apecs.h Tue Aug 18 22:02:06 1998 +++ linux/include/asm-alpha/core_apecs.h Sun Dec 27 15:21:50 1998 @@ -458,7 +458,7 @@ __EXTERN_INLINE void apecs_outb(unsigned char b, unsigned long addr) { - unsigned int w; + unsigned long w; w = __kernel_insbl(b, addr & 3); *(vuip) ((addr << 5) + APECS_IO + 0x00) = w; @@ -473,7 +473,7 @@ __EXTERN_INLINE void apecs_outw(unsigned short b, unsigned long addr) { - unsigned int w; + unsigned long w; w = __kernel_inswl(b, addr & 3); *(vuip) ((addr << 5) + APECS_IO + 0x08) = w; diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/core_cia.h linux/include/asm-alpha/core_cia.h --- v2.1.132/linux/include/asm-alpha/core_cia.h Tue Aug 18 22:02:06 1998 +++ linux/include/asm-alpha/core_cia.h Sun Dec 27 15:21:50 1998 @@ -326,7 +326,7 @@ __EXTERN_INLINE void cia_outb(unsigned char b, unsigned long addr) { - unsigned int w = __kernel_insbl(b, addr & 3); + unsigned long w = __kernel_insbl(b, addr & 3); *(vuip) ((addr << 5) + CIA_IO + 0x00) = w; wmb(); } @@ -340,7 +340,7 @@ __EXTERN_INLINE void cia_outw(unsigned short b, unsigned long addr) { - unsigned int w = __kernel_inswl(b, addr & 3); + unsigned long w = __kernel_inswl(b, addr & 3); *(vuip) ((addr << 5) + CIA_IO + 0x08) = w; wmb(); } diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/core_lca.h linux/include/asm-alpha/core_lca.h --- v2.1.132/linux/include/asm-alpha/core_lca.h Tue Aug 18 22:02:06 1998 +++ linux/include/asm-alpha/core_lca.h Sun Dec 27 15:21:50 1998 @@ -262,7 +262,7 @@ __EXTERN_INLINE void lca_outb(unsigned char b, unsigned long addr) { - unsigned int w; + unsigned long w; w = __kernel_insbl(b, addr & 3); *(vuip) ((addr << 5) + LCA_IO + 0x00) = w; @@ -277,7 +277,7 @@ __EXTERN_INLINE void lca_outw(unsigned short b, unsigned long addr) { - unsigned int w; + unsigned long w; w = __kernel_inswl(b, addr & 3); *(vuip) ((addr << 5) + LCA_IO + 0x08) = w; @@ -340,7 +340,7 @@ __EXTERN_INLINE void lca_writeb(unsigned char b, unsigned long addr) { unsigned long msb; - unsigned int w; + unsigned long w; if (addr >= (1UL << 24)) { msb = addr & 0xf8000000; @@ -354,7 +354,7 @@ __EXTERN_INLINE void lca_writew(unsigned short b, unsigned long addr) { unsigned long msb; - unsigned int w; + unsigned long w; if (addr >= (1UL << 24)) { msb = addr & 0xf8000000; diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/core_mcpcia.h linux/include/asm-alpha/core_mcpcia.h --- v2.1.132/linux/include/asm-alpha/core_mcpcia.h Wed Sep 9 14:51:09 1998 +++ linux/include/asm-alpha/core_mcpcia.h Sun Dec 27 15:21:50 1998 @@ -264,7 +264,7 @@ { unsigned long addr = in_addr & 0xffffffffUL; unsigned long hose = (in_addr >> 32) & 3; - unsigned int w; + unsigned long w; w = __kernel_insbl(b, addr & 3); *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x00) = w; @@ -283,7 +283,7 @@ { unsigned long addr = in_addr & 0xffffffffUL; unsigned long hose = (in_addr >> 32) & 3; - unsigned int w; + unsigned long w; w = __kernel_inswl(b, addr & 3); *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x08) = w; diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/core_pyxis.h linux/include/asm-alpha/core_pyxis.h --- v2.1.132/linux/include/asm-alpha/core_pyxis.h Wed Sep 9 14:51:09 1998 +++ linux/include/asm-alpha/core_pyxis.h Sun Dec 27 15:21:50 1998 @@ -326,7 +326,7 @@ __EXTERN_INLINE void pyxis_outb(unsigned char b, unsigned long addr) { - unsigned int w; + unsigned long w; w = __kernel_insbl(b, addr & 3); *(vuip) ((addr << 5) + PYXIS_IO + 0x00) = w; @@ -341,7 +341,7 @@ __EXTERN_INLINE void pyxis_outw(unsigned short b, unsigned long addr) { - unsigned int w; + unsigned long w; w = __kernel_inswl(b, addr & 3); *(vuip) ((addr << 5) + PYXIS_IO + 0x08) = w; diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/core_t2.h linux/include/asm-alpha/core_t2.h --- v2.1.132/linux/include/asm-alpha/core_t2.h Tue Aug 18 22:02:06 1998 +++ linux/include/asm-alpha/core_t2.h Sun Dec 27 15:21:50 1998 @@ -378,7 +378,7 @@ __EXTERN_INLINE void t2_outw(unsigned short b, unsigned long addr) { - unsigned int w; + unsigned long w; w = __kernel_inswl(b, addr & 3); *(vuip) ((addr << 5) + T2_IO + 0x08) = w; diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/io.h linux/include/asm-alpha/io.h --- v2.1.132/linux/include/asm-alpha/io.h Fri Oct 23 22:01:22 1998 +++ linux/include/asm-alpha/io.h Sun Dec 27 15:21:50 1998 @@ -3,7 +3,6 @@ #include #include -#include /* We don't use IO slowdowns on the Alpha, but.. */ #define __SLOW_DOWN_IO do { } while (0) @@ -19,6 +18,7 @@ #endif #ifdef __KERNEL__ +#include /* * We try to avoid hae updates (thus the cache), but when we @@ -78,6 +78,7 @@ * There are different chipsets to interface the Alpha CPUs to the world. */ +#ifdef __KERNEL__ #ifdef CONFIG_ALPHA_GENERIC /* In a generic kernel, we always go through the machine vector. */ @@ -147,6 +148,7 @@ #undef __WANT_IO_DEF #endif /* GENERIC */ +#endif /* __KERNEL__ */ /* * The convention used for inb/outb etc. is that names starting with @@ -172,6 +174,7 @@ extern void _writel(unsigned int b, unsigned long addr); extern void _writeq(unsigned long b, unsigned long addr); +#ifdef __KERNEL__ /* * The platform header files may define some of these macros to use * the inlined versions where appropriate. These macros may also be @@ -216,6 +219,27 @@ # define outl_p outl #endif +#else + +/* Userspace declarations. */ + +extern unsigned int inb (unsigned long port); +extern unsigned int inw (unsigned long port); +extern unsigned int inl (unsigned long port); +extern void outb (unsigned char b,unsigned long port); +extern void outw (unsigned short w,unsigned long port); +extern void outl (unsigned int l,unsigned long port); +extern unsigned long readb(unsigned long addr); +extern unsigned long readw(unsigned long addr); +extern unsigned long readl(unsigned long addr); +extern void writeb(unsigned char b, unsigned long addr); +extern void writew(unsigned short b, unsigned long addr); +extern void writel(unsigned int b, unsigned long addr); + +#endif /* __KERNEL__ */ + +#ifdef __KERNEL__ + /* * The "address" in IO memory space is not clearly either an integer or a * pointer. We will accept both, thus the casts. @@ -256,8 +280,6 @@ #ifndef writeq # define writeq(v,a) _writeq((v),(unsigned long)(a)) #endif - -#ifdef __KERNEL__ /* * String version of IO memory access ops: diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/machvec.h linux/include/asm-alpha/machvec.h --- v2.1.132/linux/include/asm-alpha/machvec.h Fri Oct 23 22:01:22 1998 +++ linux/include/asm-alpha/machvec.h Sun Dec 27 10:52:10 1998 @@ -4,6 +4,12 @@ #include #include +/* + * This file gets pulled in by asm/io.h from user space. We don't + * want most of this escaping. + */ + +#ifdef __KERNEL__ /* The following structure vectors all of the I/O and IRQ manipulation from the generic kernel to the hardware specific backend. */ @@ -122,4 +128,5 @@ #endif #endif /* GENERIC */ +#endif #endif /* __ALPHA_MACHVEC_H */ diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h --- v2.1.132/linux/include/asm-alpha/pgtable.h Wed Sep 9 14:51:10 1998 +++ linux/include/asm-alpha/pgtable.h Sun Dec 27 10:52:10 1998 @@ -14,6 +14,7 @@ #include /* For TASK_SIZE */ #include #include +#include /* For the task lock */ /* Caches aren't brain-dead on the Alpha. */ diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/softirq.h linux/include/asm-alpha/softirq.h --- v2.1.132/linux/include/asm-alpha/softirq.h Wed Sep 9 14:51:10 1998 +++ linux/include/asm-alpha/softirq.h Sun Dec 27 15:20:32 1998 @@ -27,7 +27,7 @@ extern inline void init_bh(int nr, void (*routine)(void)) { bh_base[nr] = routine; - bh_mask_count[nr] = 0; + atomic_set(&bh_mask_count[nr], 0); bh_mask |= 1 << nr; } @@ -116,12 +116,13 @@ extern inline void disable_bh(int nr) { bh_mask &= ~(1 << nr); - bh_mask_count[nr]++; + atomic_inc(&bh_mask_count[nr]); + synchronize_bh(); } extern inline void enable_bh(int nr) { - if (!--bh_mask_count[nr]) + if (atomic_dec_and_test(&bh_mask_count[nr])) bh_mask |= 1 << nr; } diff -u --recursive --new-file v2.1.132/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h --- v2.1.132/linux/include/asm-alpha/spinlock.h Thu Nov 12 16:21:24 1998 +++ linux/include/asm-alpha/spinlock.h Sun Dec 27 10:52:10 1998 @@ -88,12 +88,12 @@ } spinlock_t; #if DEBUG_SPINLOCK -#define SPIN_LOCK_UNLOCKED {0, 1, 0, 0, 0, 0} +#define SPIN_LOCK_UNLOCKED (spinlock_t) {0, 1, 0, 0, 0, 0} #define spin_lock_init(x) \ ((x)->lock = 0, (x)->target_ipl = 0, (x)->debug_state = 1, \ (x)->previous = 0, (x)->task = 0) #else -#define SPIN_LOCK_UNLOCKED { 0 } +#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } #define spin_lock_init(x) ((x)->lock = 0) #endif @@ -163,7 +163,7 @@ typedef struct { volatile int write_lock:1, read_counter:31; } rwlock_t; -#define RW_LOCK_UNLOCKED { 0, 0 } +#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 } #if DEBUG_RWLOCK extern void write_lock(rwlock_t * lock); diff -u --recursive --new-file v2.1.132/linux/include/asm-i386/bitops.h linux/include/asm-i386/bitops.h --- v2.1.132/linux/include/asm-i386/bitops.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-i386/bitops.h Mon Dec 28 14:09:28 1998 @@ -127,6 +127,7 @@ */ extern __inline__ int find_first_zero_bit(void * addr, unsigned size) { + int d0, d1, d2; int res; if (!size) @@ -142,9 +143,8 @@ "1:\tsubl %%ebx,%%edi\n\t" "shll $3,%%edi\n\t" "addl %%edi,%%edx" - :"=d" (res) - :"c" ((size + 31) >> 5), "D" (addr), "b" (addr) - :"ax", "cx", "di"); + :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); return res; } diff -u --recursive --new-file v2.1.132/linux/include/asm-i386/checksum.h linux/include/asm-i386/checksum.h --- v2.1.132/linux/include/asm-i386/checksum.h Thu Sep 17 17:53:38 1998 +++ linux/include/asm-i386/checksum.h Sun Dec 27 10:39:50 1998 @@ -14,7 +14,7 @@ * * it's best to have buff aligned on a 32-bit boundary */ -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); +asmlinkage unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); /* * the same as csum_partial, but copies from src while it @@ -24,8 +24,8 @@ * better 64-bit) boundary */ -unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum, - int *src_err_ptr, int *dst_err_ptr); +asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum, + int *src_err_ptr, int *dst_err_ptr); /* * Note: when you get a NULL pointer exception here this means someone diff -u --recursive --new-file v2.1.132/linux/include/asm-i386/init.h linux/include/asm-i386/init.h --- v2.1.132/linux/include/asm-i386/init.h Wed Apr 23 19:01:27 1997 +++ linux/include/asm-i386/init.h Sun Dec 27 22:45:13 1998 @@ -11,4 +11,7 @@ #define __FINIT .previous #define __INITDATA .section ".data.init",#alloc,#write +#define __cacheline_aligned __attribute__ \ + ((__section__ (".data.cacheline_aligned"))) + #endif diff -u --recursive --new-file v2.1.132/linux/include/asm-i386/posix_types.h linux/include/asm-i386/posix_types.h --- v2.1.132/linux/include/asm-i386/posix_types.h Sun Jun 7 11:16:36 1998 +++ linux/include/asm-i386/posix_types.h Sun Dec 27 10:39:50 1998 @@ -59,10 +59,14 @@ #undef __FD_ZERO #define __FD_ZERO(fdsetp) \ - __asm__ __volatile__("cld ; rep ; stosl" \ - :"=m" (*(__kernel_fd_set *) (fdsetp)) \ - :"a" (0), "c" (__FDSET_LONGS), \ - "D" ((__kernel_fd_set *) (fdsetp)) :"cx","di") +do { \ + int __d0, __d1; \ + __asm__ __volatile__("cld ; rep ; stosl" \ + :"=m" (*(__kernel_fd_set *) (fdsetp)), \ + "=&c" (__d0), "=&D" (__d1) \ + :"a" (0), "1" (__FDSET_LONGS), \ + "2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \ +} while (0) #endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ diff -u --recursive --new-file v2.1.132/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h --- v2.1.132/linux/include/asm-i386/smp.h Tue Dec 22 14:16:58 1998 +++ linux/include/asm-i386/smp.h Mon Dec 28 14:11:18 1998 @@ -185,10 +185,6 @@ extern void smp_callin(void); extern void smp_boot_cpus(void); extern void smp_store_cpu_info(int id); /* Store per CPU info (like the initial udelay numbers */ -extern void smp_message_pass(int target, int msg, unsigned long data, int wait); - -extern volatile unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */ -extern volatile int smp_process_available; /* * APIC handlers: Note according to the Intel specification update @@ -237,9 +233,7 @@ * processes are run. */ -#define PROC_CHANGE_PENALTY 10 /* Schedule penalty */ +#define PROC_CHANGE_PENALTY 15 /* Schedule penalty */ -#define SMP_FROM_INT 1 -#define SMP_FROM_SYSCALL 2 #endif #endif diff -u --recursive --new-file v2.1.132/linux/include/asm-i386/smplock.h linux/include/asm-i386/smplock.h --- v2.1.132/linux/include/asm-i386/smplock.h Mon Aug 3 17:48:28 1998 +++ linux/include/asm-i386/smplock.h Mon Dec 28 14:11:20 1998 @@ -51,7 +51,7 @@ { __asm__ __volatile__( "decl %1\n\t" - "jns 9f\n" + "jns 9f\n\t" spin_unlock_string "\n9:" :"=m" (__dummy_lock(&kernel_flag)), diff -u --recursive --new-file v2.1.132/linux/include/asm-i386/system.h linux/include/asm-i386/system.h --- v2.1.132/linux/include/asm-i386/system.h Sun Nov 8 14:03:08 1998 +++ linux/include/asm-i386/system.h Mon Dec 28 14:09:28 1998 @@ -35,30 +35,30 @@ "a" (prev), "d" (next)); \ } while (0) -#define _set_base(addr,base) \ -__asm__("movw %%dx,%0\n\t" \ +#define _set_base(addr,base) do { unsigned long __pr; \ +__asm__ __volatile__ ("movw %%dx,%1\n\t" \ "rorl $16,%%edx\n\t" \ - "movb %%dl,%1\n\t" \ - "movb %%dh,%2" \ - : /* no output */ \ + "movb %%dl,%2\n\t" \ + "movb %%dh,%3" \ + :"=&d" (__pr) \ :"m" (*((addr)+2)), \ "m" (*((addr)+4)), \ "m" (*((addr)+7)), \ - "d" (base) \ - :"dx") + "0" (base) \ + ); } while(0) -#define _set_limit(addr,limit) \ -__asm__("movw %%dx,%0\n\t" \ +#define _set_limit(addr,limit) do { unsigned long __lr; \ +__asm__ __volatile__ ("movw %%dx,%1\n\t" \ "rorl $16,%%edx\n\t" \ - "movb %1,%%dh\n\t" \ + "movb %2,%%dh\n\t" \ "andb $0xf0,%%dh\n\t" \ "orb %%dh,%%dl\n\t" \ - "movb %%dl,%1" \ - : /* no output */ \ + "movb %%dl,%2" \ + :"=&d" (__lr) \ :"m" (*(addr)), \ "m" (*((addr)+6)), \ - "d" (limit) \ - :"dx") + "0" (limit) \ + ); } while(0) #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) ) #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 ) @@ -165,8 +165,19 @@ * Force strict CPU ordering. * And yes, this is required on UP too when we're talking * to devices. + * + * For now, "wmb()" doesn't actually do anything, as all + * Intel CPU's follow what Intel calls a *Processor Order*, + * in which all writes are seen in the program order even + * outside the CPU. + * + * I expect future Intel CPU's to have a weaker ordering, + * but I'd also expect them to finally get their act together + * and add some real memory barriers if so. */ #define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") +#define rmb() mb() +#define wmb() __asm__ __volatile__ ("": : :"memory") /* interrupt control.. */ #define __sti() __asm__ __volatile__ ("sti": : :"memory") diff -u --recursive --new-file v2.1.132/linux/include/asm-i386/timex.h linux/include/asm-i386/timex.h --- v2.1.132/linux/include/asm-i386/timex.h Fri May 8 23:14:54 1998 +++ linux/include/asm-i386/timex.h Mon Dec 28 11:41:06 1998 @@ -12,4 +12,34 @@ (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \ << (SHIFT_SCALE-SHIFT_HZ)) / HZ) +/* + * Standard way to access the cycle counter on i586+ CPUs. + * Currently only used on SMP. + * + * If you really have a SMP machine with i486 chips or older, + * compile for that, and this will just always return zero. + * That's ok, it just means that the nicer scheduling heuristics + * won't work for you. + * + * We only use the low 32 bits, and we'd simply better make sure + * that we reschedule before that wraps. Scheduling at least every + * four billion cycles just basically sounds like a good idea, + * regardless of how fast the machine is. + */ +typedef unsigned long cycles_t; + +extern cycles_t cacheflush_time; + +static inline cycles_t get_cycles (void) +{ +#if CPU < 586 + return 0; +#else + unsigned long eax, edx; + + __asm__("rdtsc":"=a" (eax), "=d" (edx)); + return eax; +#endif +} + #endif diff -u --recursive --new-file v2.1.132/linux/include/asm-i386/uaccess.h linux/include/asm-i386/uaccess.h --- v2.1.132/linux/include/asm-i386/uaccess.h Wed Aug 26 11:37:44 1998 +++ linux/include/asm-i386/uaccess.h Mon Dec 28 14:11:22 1998 @@ -250,13 +250,15 @@ /* Generic arbitrary sized copy. */ #define __copy_user(to,from,size) \ +do { \ + int __d0, __d1; \ __asm__ __volatile__( \ "0: rep; movsl\n" \ - " movl %1,%0\n" \ + " movl %3,%0\n" \ "1: rep; movsb\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ - "3: lea 0(%1,%0,4),%0\n" \ + "3: lea 0(%3,%0,4),%0\n" \ " jmp 2b\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ @@ -264,18 +266,21 @@ " .long 0b,3b\n" \ " .long 1b,2b\n" \ ".previous" \ - : "=&c"(size) \ - : "r"(size & 3), "0"(size / 4), "D"(to), "S"(from) \ - : "di", "si", "memory") + : "=&c"(size), "=&D" (__d0), "=&S" (__d1) \ + : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from) \ + : "memory"); \ +} while (0) #define __copy_user_zeroing(to,from,size) \ +do { \ + int __d0, __d1; \ __asm__ __volatile__( \ "0: rep; movsl\n" \ - " movl %1,%0\n" \ + " movl %3,%0\n" \ "1: rep; movsb\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ - "3: lea 0(%1,%0,4),%0\n" \ + "3: lea 0(%3,%0,4),%0\n" \ "4: pushl %0\n" \ " pushl %%eax\n" \ " xorl %%eax,%%eax\n" \ @@ -289,9 +294,10 @@ " .long 0b,3b\n" \ " .long 1b,4b\n" \ ".previous" \ - : "=&c"(size) \ - : "r"(size & 3), "0"(size / 4), "D"(to), "S"(from) \ - : "di", "si", "memory"); + : "=&c"(size), "=&D" (__d0), "=&S" (__d1) \ + : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from) \ + : "memory"); \ +} while (0) /* We let the __ versions of copy_from/to_user inline, because they're often * used in fast paths and have only a small space overhead. @@ -314,6 +320,7 @@ /* Optimize just a little bit when we know the size of the move. */ #define __constant_copy_user(to, from, size) \ do { \ + int __d0, __d1; \ switch (size & 3) { \ default: \ __asm__ __volatile__( \ @@ -327,9 +334,9 @@ " .align 4\n" \ " .long 0b,2b\n" \ ".previous" \ - : "=c"(size) \ - : "S"(from), "D"(to), "0"(size/4) \ - : "di", "si", "memory"); \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ break; \ case 1: \ __asm__ __volatile__( \ @@ -346,9 +353,9 @@ " .long 0b,3b\n" \ " .long 1b,4b\n" \ ".previous" \ - : "=c"(size) \ - : "S"(from), "D"(to), "0"(size/4) \ - : "di", "si", "memory"); \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ break; \ case 2: \ __asm__ __volatile__( \ @@ -365,9 +372,9 @@ " .long 0b,3b\n" \ " .long 1b,4b\n" \ ".previous" \ - : "=c"(size) \ - : "S"(from), "D"(to), "0"(size/4) \ - : "di", "si", "memory"); \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ break; \ case 3: \ __asm__ __volatile__( \ @@ -387,9 +394,9 @@ " .long 1b,5b\n" \ " .long 2b,6b\n" \ ".previous" \ - : "=c"(size) \ - : "S"(from), "D"(to), "0"(size/4) \ - : "di", "si", "memory"); \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ break; \ } \ } while (0) @@ -397,6 +404,7 @@ /* Optimize just a little bit when we know the size of the move. */ #define __constant_copy_user_zeroing(to, from, size) \ do { \ + int __d0, __d1; \ switch (size & 3) { \ default: \ __asm__ __volatile__( \ @@ -416,9 +424,9 @@ " .align 4\n" \ " .long 0b,2b\n" \ ".previous" \ - : "=c"(size) \ - : "S"(from), "D"(to), "0"(size/4) \ - : "di", "si", "memory"); \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ break; \ case 1: \ __asm__ __volatile__( \ @@ -448,9 +456,9 @@ " .long 0b,3b\n" \ " .long 1b,4b\n" \ ".previous" \ - : "=c"(size) \ - : "S"(from), "D"(to), "0"(size/4) \ - : "di", "si", "memory"); \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ break; \ case 2: \ __asm__ __volatile__( \ @@ -480,9 +488,9 @@ " .long 0b,3b\n" \ " .long 1b,4b\n" \ ".previous" \ - : "=c"(size) \ - : "S"(from), "D"(to), "0"(size/4) \ - : "di", "si", "memory"); \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ break; \ case 3: \ __asm__ __volatile__( \ @@ -522,9 +530,9 @@ " .long 1b,5b\n" \ " .long 2b,6b\n" \ ".previous" \ - : "=c"(size) \ - : "S"(from), "D"(to), "0"(size/4) \ - : "di", "si", "memory"); \ + : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ + : "1"(from), "2"(to), "0"(size/4) \ + : "memory"); \ break; \ } \ } while (0) diff -u --recursive --new-file v2.1.132/linux/include/asm-ppc/softirq.h linux/include/asm-ppc/softirq.h --- v2.1.132/linux/include/asm-ppc/softirq.h Mon Oct 5 13:13:43 1998 +++ linux/include/asm-ppc/softirq.h Wed Dec 23 07:20:09 1998 @@ -12,7 +12,7 @@ extern inline void init_bh(int nr, void (*routine)(void)) { bh_base[nr] = routine; - bh_mask_count[nr] = 0; + atomic_set(&bh_mask_count[nr], 0); bh_mask |= 1 << nr; } @@ -96,13 +96,13 @@ extern inline void disable_bh(int nr) { bh_mask &= ~(1 << nr); - bh_mask_count[nr]++; + atomic_inc(&bh_mask_count[nr]); synchronize_bh(); } extern inline void enable_bh(int nr) { - if (!--bh_mask_count[nr]) + if (atomic_dec_and_test(&bh_mask_count[nr])) bh_mask |= 1 << nr; } diff -u --recursive --new-file v2.1.132/linux/include/linux/atalk.h linux/include/linux/atalk.h --- v2.1.132/linux/include/linux/atalk.h Fri Jul 31 17:07:27 1998 +++ linux/include/linux/atalk.h Mon Dec 28 14:09:31 1998 @@ -10,7 +10,7 @@ #define ATPORT_FIRST 1 #define ATPORT_RESERVED 128 -#define ATPORT_LAST 255 +#define ATPORT_LAST 254 /* 254 is only legal on localtalk */ #define ATADDR_ANYNET (__u16)0 #define ATADDR_ANYNODE (__u8)0 #define ATADDR_ANYPORT (__u8)0 diff -u --recursive --new-file v2.1.132/linux/include/linux/file.h linux/include/linux/file.h --- v2.1.132/linux/include/linux/file.h Wed Aug 26 11:37:44 1998 +++ linux/include/linux/file.h Wed Dec 23 11:57:17 1998 @@ -6,7 +6,6 @@ #define __LINUX_FILE_H extern void __fput(struct file *); -extern void insert_file_free(struct file *file); /* * Check whether the specified task has the fd open. Since the task @@ -50,34 +49,23 @@ current->files->fd[fd] = file; } -/* It does not matter which list it is on. */ -extern inline void remove_filp(struct file *file) -{ - if(file->f_next) - file->f_next->f_pprev = file->f_pprev; - *file->f_pprev = file->f_next; -} - -extern inline void fput(struct file *file) -{ - int count = file->f_count-1; - - if (!count) { - locks_remove_flock(file); - __fput(file); - file->f_count = 0; - remove_filp(file); - insert_file_free(file); - } else - file->f_count = count; -} - -extern inline void put_filp(struct file *file) -{ - if(--file->f_count == 0) { - remove_filp(file); - insert_file_free(file); - } -} +/* + * 23/12/1998 Marcin Dalecki : + * + * Since those functions where calling other functions, it was compleatly + * bogous to make them all "extern inline". + * + * The removal of this pseudo optimization saved me scandaleous: + * + * 3756 (i386 arch) + * + * precious bytes from my kernel, even without counting all the code compiled + * as module! + * + * I suspect there are many other similiar "optimizations" across the + * kernel... + */ +extern void fput(struct file *file); +extern void put_filp(struct file *file); #endif diff -u --recursive --new-file v2.1.132/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.132/linux/include/linux/fs.h Tue Dec 22 14:16:58 1998 +++ linux/include/linux/fs.h Mon Dec 28 14:11:18 1998 @@ -466,7 +466,7 @@ } fl_u; }; -extern struct file_lock *file_lock_table; +extern struct file_lock *file_lock_table; #include @@ -692,7 +692,8 @@ extern struct file *filp_open(const char *, int, int); extern char * getname(const char * filename); -extern void putname(char * name); +#define __getname() ((char *) __get_free_page(GFP_KERNEL)) +#define putname(name) free_page((unsigned long)(name)) extern void kill_fasync(struct fasync_struct *fa, int sig); extern int register_blkdev(unsigned int, const char *, struct file_operations *); @@ -702,11 +703,16 @@ extern struct file_operations def_blk_fops; extern struct inode_operations blkdev_inode_operations; +/* fs/devices.c */ extern int register_chrdev(unsigned int, const char *, struct file_operations *); extern int unregister_chrdev(unsigned int major, const char * name); extern int chrdev_open(struct inode * inode, struct file * filp); extern struct file_operations def_chr_fops; extern struct inode_operations chrdev_inode_operations; +extern char * bdevname(kdev_t dev); +extern char * cdevname(kdev_t dev); +extern char * kdevname(kdev_t dev); + extern void init_fifo(struct inode * inode); extern struct inode_operations fifo_inode_operations; @@ -815,8 +821,6 @@ extern struct buffer_head * getblk(kdev_t, int, int); extern struct buffer_head * find_buffer(kdev_t dev, int block, int size); extern void ll_rw_block(int, int, struct buffer_head * bh[]); -extern void ll_rw_page(int, kdev_t, unsigned long, char *); -extern void ll_rw_swap_file(int, kdev_t, unsigned int *, int, char *); extern int is_read_only(kdev_t); extern void __brelse(struct buffer_head *); extern inline void brelse(struct buffer_head *buf) diff -u --recursive --new-file v2.1.132/linux/include/linux/genhd.h linux/include/linux/genhd.h --- v2.1.132/linux/include/linux/genhd.h Fri Oct 23 22:01:26 1998 +++ linux/include/linux/genhd.h Mon Dec 28 14:09:28 1998 @@ -108,12 +108,21 @@ #ifdef CONFIG_BSD_DISKLABEL /* * BSD disklabel support by Yossi Gottlieb + * updated by Marc Espie */ +#define FREEBSD_PARTITION 0xa5 /* FreeBSD Partition ID */ +#define OPENBSD_PARTITION 0xa6 /* OpenBSD Partition ID */ +#define NETBSD_PARTITION 0xa9 /* NetBSD Partition ID */ +#define BSDI_PARTITION 0xb7 /* BSDI Partition ID */ -#define BSD_PARTITION 0xa5 /* Partition ID */ +/* Ours is not to wonder why.. */ +#define BSD_PARTITION FREEBSD_PARTITION + +/* check against BSD src/sys/sys/disklabel.h for consistency */ #define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ #define BSD_MAXPARTITIONS 8 +#define OPENBSD_MAXPARTITIONS 16 #define BSD_FS_UNUSED 0 /* disklabel unused partition entry ID */ struct bsd_disklabel { __u32 d_magic; /* the magic number */ @@ -159,6 +168,62 @@ }; #endif /* CONFIG_BSD_DISKLABEL */ + +#ifdef CONFIG_UNIXWARE_DISKLABEL +/* + * Unixware slices support by Andrzej Krzysztofowicz + * and Krzysztof G. Baranowski + */ + +#define UNIXWARE_PARTITION 0x63 /* Partition ID, same as */ + /* GNU_HURD and SCO Unix */ +#define UNIXWARE_DISKMAGIC (0xCA5E600DUL) /* The disk magic number */ +#define UNIXWARE_DISKMAGIC2 (0x600DDEEEUL) /* The slice table magic nr */ +#define UNIXWARE_NUMSLICE 16 +#define UNIXWARE_FS_UNUSED 0 /* Unused slice entry ID */ + +struct unixware_slice { + __u16 s_label; /* label */ + __u16 s_flags; /* permission flags */ + __u32 start_sect; /* starting sector */ + __u32 nr_sects; /* number of sectors in slice */ +}; + +struct unixware_disklabel { + __u32 d_type; /* drive type */ + __u32 d_magic; /* the magic number */ + __u32 d_version; /* version number */ + char d_serial[12]; /* serial number of the device */ + __u32 d_ncylinders; /* # of data cylinders per device */ + __u32 d_ntracks; /* # of tracks per cylinder */ + __u32 d_nsectors; /* # of data sectors per track */ + __u32 d_secsize; /* # of bytes per sector */ + __u32 d_part_start; /* # of first sector of this partition */ + __u32 d_unknown1[12]; /* ? */ + __u32 d_alt_tbl; /* byte offset of alternate table */ + __u32 d_alt_len; /* byte length of alternate table */ + __u32 d_phys_cyl; /* # of physical cylinders per device */ + __u32 d_phys_trk; /* # of physical tracks per cylinder */ + __u32 d_phys_sec; /* # of physical sectors per track */ + __u32 d_phys_bytes; /* # of physical bytes per sector */ + __u32 d_unknown2; /* ? */ + __u32 d_unknown3; /* ? */ + __u32 d_pad[8]; /* pad */ + + struct unixware_vtoc { + __u32 v_magic; /* the magic number */ + __u32 v_version; /* version number */ + char v_name[8]; /* volume name */ + __u16 v_nslices; /* # of slices */ + __u16 v_unknown1; /* ? */ + __u32 v_reserved[10]; /* reserved */ + struct unixware_slice + v_slice[UNIXWARE_NUMSLICE]; /* slice headers */ + } vtoc; + +}; /* 408 */ + +#endif /* CONFIG_UNIXWARE_DISKLABEL */ extern struct gendisk *gendisk_head; /* linked list of disks */ diff -u --recursive --new-file v2.1.132/linux/include/linux/hfs_fs_i.h linux/include/linux/hfs_fs_i.h --- v2.1.132/linux/include/linux/hfs_fs_i.h Tue Mar 17 22:18:15 1998 +++ linux/include/linux/hfs_fs_i.h Wed Dec 23 14:10:36 1998 @@ -33,6 +33,9 @@ const struct hfs_hdr_layout *default_layout; struct hfs_hdr_layout *layout; + /* to deal with localtime ugliness */ + int tz_secondswest; + /* for dentry cleanup */ void (*d_drop_op)(struct dentry *, const ino_t); }; diff -u --recursive --new-file v2.1.132/linux/include/linux/ipc.h linux/include/linux/ipc.h --- v2.1.132/linux/include/linux/ipc.h Fri Jul 31 17:05:52 1998 +++ linux/include/linux/ipc.h Sun Dec 27 22:18:28 1998 @@ -21,6 +21,11 @@ #define IPC_EXCL 00002000 /* fail if key exists */ #define IPC_NOWAIT 00004000 /* return error on wait */ +/* these fields are used by the DIPC package so the kernel as standard + should avoid using them if possible */ + +#define IPC_DIPC 00010000 /* make it distributed */ +#define IPC_OWN 00020000 /* this machine is the DIPC owner */ /* * Control commands used with semctl, msgctl and shmctl diff -u --recursive --new-file v2.1.132/linux/include/linux/ipx.h linux/include/linux/ipx.h --- v2.1.132/linux/include/linux/ipx.h Fri Jul 31 17:07:27 1998 +++ linux/include/linux/ipx.h Mon Dec 28 14:11:23 1998 @@ -76,6 +76,7 @@ #define SIOCAIPXITFCRT (SIOCPROTOPRIVATE) #define SIOCAIPXPRISLT (SIOCPROTOPRIVATE+1) #define SIOCIPXCFGDATA (SIOCPROTOPRIVATE+2) +#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE+3) #ifdef __KERNEL__ #include diff -u --recursive --new-file v2.1.132/linux/include/linux/module.h linux/include/linux/module.h --- v2.1.132/linux/include/linux/module.h Fri Jul 31 17:05:53 1998 +++ linux/include/linux/module.h Mon Dec 28 14:09:29 1998 @@ -20,6 +20,7 @@ # endif #endif /* __GENKSYMS__ */ +#include /* Don't need to bring in all of uaccess.h just for this decl. */ struct exception_table_entry; @@ -54,7 +55,12 @@ const char *name; unsigned long size; - long usecount; + union + { + atomic_t usecount; + long pad; + } uc; /* Needs to keep its size - so says rth */ + unsigned long flags; /* AUTOCLEAN et al */ unsigned nsyms; @@ -80,10 +86,10 @@ struct module_info { - unsigned long addr; - unsigned long size; - unsigned long flags; - long usecount; + unsigned long addr; + unsigned long size; + unsigned long flags; + long usecount; }; /* Bits of module.flags. */ @@ -114,17 +120,17 @@ /* Backwards compatibility definition. */ -#define GET_USE_COUNT(module) ((module)->usecount) +#define GET_USE_COUNT(module) (atomic_read(&(module)->uc.usecount)) /* Poke the use count of a module. */ #define __MOD_INC_USE_COUNT(mod) \ - ((mod)->usecount++, (mod)->flags |= MOD_VISITED|MOD_USED_ONCE) + (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE) #define __MOD_DEC_USE_COUNT(mod) \ - ((mod)->usecount--, (mod)->flags |= MOD_VISITED) + (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED) #define __MOD_IN_USE(mod) \ (mod_member_present((mod), can_unload) && (mod)->can_unload \ - ? (mod)->can_unload() : (mod)->usecount) + ? (mod)->can_unload() : atomic_read(&(mod)->uc.usecount)) /* Indirect stringification. */ diff -u --recursive --new-file v2.1.132/linux/include/linux/msdos_fs_sb.h linux/include/linux/msdos_fs_sb.h --- v2.1.132/linux/include/linux/msdos_fs_sb.h Thu Jan 8 14:02:41 1998 +++ linux/include/linux/msdos_fs_sb.h Sun Dec 27 10:47:18 1998 @@ -35,9 +35,11 @@ struct msdos_sb_info { unsigned short cluster_size; /* sectors/cluster */ unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */ - unsigned short fat_start,fat_length; /* FAT start & length (sec.) */ - unsigned short dir_start,dir_entries; /* root dir start & entries */ - unsigned short data_start; /* first data sector */ + unsigned short fat_start; + unsigned long fat_length; /* FAT start & length (sec.) */ + unsigned long dir_start; + unsigned short dir_entries; /* root dir start & entries */ + unsigned long data_start; /* first data sector */ unsigned long clusters; /* number of clusters */ unsigned long root_cluster; /* first cluster of the root directory */ unsigned long fsinfo_offset; /* FAT32 fsinfo offset from start of disk */ diff -u --recursive --new-file v2.1.132/linux/include/linux/sched.h linux/include/linux/sched.h --- v2.1.132/linux/include/linux/sched.h Thu Nov 12 16:21:24 1998 +++ linux/include/linux/sched.h Mon Dec 28 14:11:20 1998 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -219,6 +220,7 @@ /* various fields */ long counter; long priority; + cycles_t avg_slice; /* SMP and runqueue state */ int has_cpu; int processor; @@ -336,7 +338,7 @@ */ #define INIT_TASK \ /* state etc */ { 0,0,0,KERNEL_DS,&default_exec_domain,0, \ -/* counter */ DEF_PRIORITY,DEF_PRIORITY, \ +/* counter */ DEF_PRIORITY,DEF_PRIORITY,0, \ /* SMP */ 0,0,0,-1, \ /* schedlink */ &init_task,&init_task, &init_task, &init_task, \ /* binfmt */ NULL, \ diff -u --recursive --new-file v2.1.132/linux/include/linux/sem.h linux/include/linux/sem.h --- v2.1.132/linux/include/linux/sem.h Fri Jul 31 17:05:53 1998 +++ linux/include/linux/sem.h Sun Dec 27 22:18:29 1998 @@ -92,6 +92,7 @@ struct semid_ds * sma; /* semaphore array for operations */ struct sembuf * sops; /* array of pending operations */ int nsops; /* number of operations */ + int alter; /* operation will alter semaphore */ }; /* Each task has a list of undo requests. They are executed automatically diff -u --recursive --new-file v2.1.132/linux/include/linux/smp.h linux/include/linux/smp.h --- v2.1.132/linux/include/linux/smp.h Thu Aug 6 14:06:34 1998 +++ linux/include/linux/smp.h Mon Dec 28 14:11:19 1998 @@ -11,12 +11,22 @@ #include /* - * main IPI interface, handles INIT, TLB flush, STOP, etc. (defined in asm header): - * - * extern void smp_message_pass(int target, int msg, unsigned long data, int wait); + * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc. + * (defined in asm header): */ /* + * stops all CPUs but the current one: + */ +extern void smp_send_stop(void); + +/* + * sends a 'reschedule' event to another CPU: + */ +extern void FASTCALL(smp_send_reschedule(int cpu)); + + +/* * Boot processor call to load the other CPU's */ extern void smp_boot_cpus(void); @@ -61,7 +71,6 @@ #define smp_num_cpus 1 #define smp_processor_id() 0 #define hard_smp_processor_id() 0 -#define smp_message_pass(t,m,d,w) #define smp_threads_ready 1 #define kernel_lock() #define cpu_logical_map(cpu) 0 diff -u --recursive --new-file v2.1.132/linux/include/linux/swap.h linux/include/linux/swap.h --- v2.1.132/linux/include/linux/swap.h Tue Dec 22 14:16:58 1998 +++ linux/include/linux/swap.h Mon Dec 28 14:09:30 1998 @@ -87,6 +87,7 @@ /* linux/mm/page_io.c */ extern void rw_swap_page(int, unsigned long, char *, int); extern void rw_swap_page_nocache(int, unsigned long, char *); +extern void rw_swap_page_nolock(int, unsigned long, char *, int); extern void swap_after_unlock_page (unsigned long entry); /* linux/mm/page_alloc.c */ diff -u --recursive --new-file v2.1.132/linux/include/linux/videodev.h linux/include/linux/videodev.h --- v2.1.132/linux/include/linux/videodev.h Tue Dec 22 14:16:58 1998 +++ linux/include/linux/videodev.h Sun Dec 27 10:49:06 1998 @@ -261,6 +261,8 @@ #define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */ #define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */ #define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */ +#define VID_HARDWARE_BROADWAY 17 /* Broadway project */ +#define VID_HARDWARE_GEMTEK 18 /* * Initialiser list diff -u --recursive --new-file v2.1.132/linux/include/net/sock.h linux/include/net/sock.h --- v2.1.132/linux/include/net/sock.h Sun Nov 8 14:03:12 1998 +++ linux/include/net/sock.h Mon Dec 28 14:11:23 1998 @@ -128,6 +128,11 @@ unsigned char node[IPX_NODE_LEN]; #endif unsigned short type; +/* + * To handle special ncp connection-handling sockets for mars_nwe, + * the connection number must be stored in the socket. + */ + unsigned short ipx_ncp_conn; }; #endif diff -u --recursive --new-file v2.1.132/linux/include/video/fbcon.h linux/include/video/fbcon.h --- v2.1.132/linux/include/video/fbcon.h Tue Dec 22 14:16:59 1998 +++ linux/include/video/fbcon.h Sun Dec 27 10:50:12 1998 @@ -441,6 +441,7 @@ static __inline__ void fast_memmove(void *d, const void *s, size_t count) { + int d0, d1, d2, d3; if (d < s) { __asm__ __volatile__ ( "cld\n\t" @@ -452,9 +453,9 @@ "movsw\n" "2:\trep\n\t" "movsl" - : /* no output */ - :"c"(count),"D"((long)d),"S"((long)s) - :"cx","di","si","memory"); + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0"(count),"1"((long)d),"2"((long)s) + :"memory"); } else { __asm__ __volatile__ ( "std\n\t" @@ -475,9 +476,9 @@ "2:\trep\n\t" "movsl\n\t" "cld" - : /* no output */ - :"c"(count),"D"(count-4+(long)d),"S"(count-4+(long)s) - :"ax","cx","di","si","memory"); + : "=&c" (d0), "=&D" (d1), "=&S" (d2), "=&a" (d3) + :"0"(count),"1"(count-4+(long)d),"2"(count-4+(long)s) + :"memory"); } } diff -u --recursive --new-file v2.1.132/linux/init/main.c linux/init/main.c --- v2.1.132/linux/init/main.c Tue Dec 22 14:16:59 1998 +++ linux/init/main.c Sun Dec 27 22:45:13 1998 @@ -1177,6 +1177,7 @@ */ smp_init(); kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + current->need_resched = 1; cpu_idle(NULL); } diff -u --recursive --new-file v2.1.132/linux/ipc/sem.c linux/ipc/sem.c --- v2.1.132/linux/ipc/sem.c Fri Nov 27 13:09:29 1998 +++ linux/ipc/sem.c Sun Dec 27 10:53:45 1998 @@ -29,6 +29,25 @@ * see a clean way to get the old behavior with the new design. * The POSIX standard and SVID should be consulted to determine * what behavior is mandated. + * + * Further notes on refinement (Christoph Rohland, December 1998): + * - The POSIX standard says, that the undo adjustments simply should + * redo. So the current implementation is o.K. + * - The previous code had two flaws: + * 1) It actively gave the semaphore to the next waiting process + * sleeping on the semaphore. Since this process did not have the + * cpu this led to many unnecessary context switches and bad + * performance. Now we only check which process should be able to + * get the semaphore and if this process wants to reduce some + * semaphore value we simply wake it up without doing the + * operation. So it has to try to get it later. Thus e.g. the + * running process may reaquire the semaphore during the current + * time slice. If it only waits for zero or increases the semaphore, + * we do the operation in advance and wake it up. + * 2) It did not wake up all zero waiting processes. We try to do + * better but only get the semops right which only wait for zero or + * increase. If there are decrement operations in the operations + * array we do the same as before. */ #include @@ -158,12 +177,26 @@ /* Manage the doubly linked list sma->sem_pending as a FIFO: * insert new queue elements at the tail sma->sem_pending_last. */ -static inline void insert_into_queue (struct semid_ds * sma, struct sem_queue * q) +static inline void append_to_queue (struct semid_ds * sma, + struct sem_queue * q) { *(q->prev = sma->sem_pending_last) = q; *(sma->sem_pending_last = &q->next) = NULL; } -static inline void remove_from_queue (struct semid_ds * sma, struct sem_queue * q) + +static inline void prepend_to_queue (struct semid_ds * sma, + struct sem_queue * q) +{ + q->next = sma->sem_pending; + *(q->prev = &sma->sem_pending) = q; + if (q->next) + q->next->prev = &q->next; + else /* sma->sem_pending_last == &sma->sem_pending */ + sma->sem_pending_last = &q->next; +} + +static inline void remove_from_queue (struct semid_ds * sma, + struct sem_queue * q) { *(q->prev) = q->next; if (q->next) @@ -173,112 +206,100 @@ q->prev = NULL; /* mark as removed */ } -/* Determine whether a sequence of semaphore operations would succeed +/* + * Determine whether a sequence of semaphore operations would succeed * all at once. Return 0 if yes, 1 if need to sleep, else return error code. */ -static int try_semop (struct semid_ds * sma, struct sembuf * sops, int nsops) -{ - int result = 0; - int i = 0; - while (i < nsops) { - struct sembuf * sop = &sops[i]; - struct sem * curr = &sma->sem_base[sop->sem_num]; - if (sop->sem_op + curr->semval > SEMVMX) { - result = -ERANGE; - break; - } - if (!sop->sem_op && curr->semval) { - if (sop->sem_flg & IPC_NOWAIT) - result = -EAGAIN; - else - result = 1; - break; - } - i++; - curr->semval += sop->sem_op; - if (curr->semval < 0) { - if (sop->sem_flg & IPC_NOWAIT) - result = -EAGAIN; - else - result = 1; - break; - } - } - while (--i >= 0) { - struct sembuf * sop = &sops[i]; - struct sem * curr = &sma->sem_base[sop->sem_num]; - curr->semval -= sop->sem_op; - } - return result; -} +static int try_atomic_semop (struct semid_ds * sma, struct sembuf * sops, + int nsops, struct sem_undo *un, int pid, + int do_undo) +{ + int result, sem_op; + struct sembuf *sop; + struct sem * curr; + + for (sop = sops; sop < sops + nsops; sop++) { + curr = sma->sem_base + sop->sem_num; + sem_op = sop->sem_op; -/* Actually perform a sequence of semaphore operations. Atomically. */ -/* This assumes that try_semop() already returned 0. */ -static int do_semop (struct semid_ds * sma, struct sembuf * sops, int nsops, - struct sem_undo * un, int pid) -{ - int i; + if (!sem_op && curr->semval) + goto would_block; - for (i = 0; i < nsops; i++) { - struct sembuf * sop = &sops[i]; - struct sem * curr = &sma->sem_base[sop->sem_num]; - if (sop->sem_op + curr->semval > SEMVMX) { - printk("do_semop: race\n"); - break; - } - if (!sop->sem_op) { - if (curr->semval) { - printk("do_semop: race\n"); - break; - } - } else { - curr->semval += sop->sem_op; - if (curr->semval < 0) { - printk("do_semop: race\n"); - break; - } - if (sop->sem_flg & SEM_UNDO) - un->semadj[sop->sem_num] -= sop->sem_op; - } - curr->sempid = pid; + curr->sempid = (curr->sempid << 16) | pid; + curr->semval += sem_op; + if (sop->sem_flg & SEM_UNDO) + un->semadj[sop->sem_num] -= sem_op; + + if (curr->semval < 0) + goto would_block; + if (curr->semval > SEMVMX) + goto out_of_range; } - sma->sem_otime = CURRENT_TIME; - /* Previous implementation returned the last semaphore's semval. - * This is wrong because we may not have checked read permission, - * only write permission. - */ + if (do_undo) + { + sop--; + result = 0; + goto undo; + } + + sma->sem_otime = CURRENT_TIME; return 0; + +out_of_range: + result = -ERANGE; + goto undo; + +would_block: + if (sop->sem_flg & IPC_NOWAIT) + result = -EAGAIN; + else + result = 1; + +undo: + while (sop >= sops) { + curr = sma->sem_base + sop->sem_num; + curr->semval -= sop->sem_op; + curr->sempid >>= 16; + + if (sop->sem_flg & SEM_UNDO) + un->semadj[sop->sem_num] += sop->sem_op; + sop--; + } + + return result; } /* Go through the pending queue for the indicated semaphore - * looking for tasks that can be completed. Keep cycling through - * the queue until a pass is made in which no process is woken up. + * looking for tasks that can be completed. */ static void update_queue (struct semid_ds * sma) { - int wokeup, error; + int error; struct sem_queue * q; - do { - wokeup = 0; - for (q = sma->sem_pending; q; q = q->next) { - error = try_semop(sma, q->sops, q->nsops); - /* Does q->sleeper still need to sleep? */ - if (error > 0) - continue; - /* Perform the operations the sleeper was waiting for */ - if (!error) - error = do_semop(sma, q->sops, q->nsops, q->undo, q->pid); - q->status = error; - /* Remove it from the queue */ - remove_from_queue(sma,q); - /* Wake it up */ - wake_up_interruptible(&q->sleeper); /* doesn't sleep! */ - wokeup++; - } - } while (wokeup); + for (q = sma->sem_pending; q; q = q->next) { + + if (q->status == 1) + return; /* wait for other process */ + + error = try_atomic_semop(sma, q->sops, q->nsops, + q->undo, q->pid, q->alter); + + /* Does q->sleeper still need to sleep? */ + if (error <= 0) { + /* Found one, wake it up */ + wake_up_interruptible(&q->sleeper); + if (error == 0 && q->alter) { + /* if q-> alter let it self try */ + q->status = 1; + return; + } + q->status = error; + remove_from_queue(sma,q); + } + } } /* The following counts are associated to each semaphore: @@ -460,7 +481,7 @@ goto out; switch (cmd) { case GETVAL : err = curr->semval; goto out; - case GETPID : err = curr->sempid; goto out; + case GETPID : err = curr->sempid & 0xffff; goto out; case GETNCNT: err = count_semncnt(sma,semnum); goto out; case GETZCNT: err = count_semzcnt(sma,semnum); goto out; case GETALL: @@ -582,11 +603,12 @@ asmlinkage int sys_semop (int semid, struct sembuf *tsops, unsigned nsops) { - int i, id, size, error = -EINVAL; + int id, size, error = -EINVAL; struct semid_ds *sma; struct sembuf sops[SEMOPM], *sop; struct sem_undo *un; - int undos = 0, alter = 0; + int undos = 0, decrease = 0, alter = 0; + struct sem_queue queue; lock_kernel(); if (nsops < 1 || semid < 0) @@ -595,8 +617,6 @@ if (nsops > SEMOPM) goto out; error = -EFAULT; - if (!tsops) - goto out; if (copy_from_user (sops, tsops, nsops * sizeof(*tsops))) goto out; id = (unsigned int) semid % SEMMNI; @@ -606,22 +626,23 @@ error = -EIDRM; if (sma->sem_perm.seq != (unsigned int) semid / SEMMNI) goto out; - for (i = 0; i < nsops; i++) { - sop = &sops[i]; + error = -EFBIG; + for (sop = sops; sop < sops + nsops; sop++) { if (sop->sem_num >= sma->sem_nsems) goto out; if (sop->sem_flg & SEM_UNDO) undos++; - if (sop->sem_op) - alter++; + if (sop->sem_op < 0) + decrease = 1; + if (sop->sem_op > 0) + alter = 1; } + alter |= decrease; + error = -EACCES; if (ipcperms(&sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) goto out; - error = try_semop(sma, sops, nsops); - if (error < 0) - goto out; if (undos) { /* Make sure we have an undo structure * for this process and this semaphore set. @@ -646,40 +667,59 @@ } } else un = NULL; - if (error == 0) { - /* the operations go through immediately */ - error = do_semop(sma, sops, nsops, un, current->pid); - /* maybe some queued-up processes were waiting for this */ - update_queue(sma); - goto out; - } else { - /* We need to sleep on this operation, so we put the current - * task into the pending queue and go to sleep. - */ - struct sem_queue queue; - queue.sma = sma; - queue.sops = sops; - queue.nsops = nsops; - queue.undo = un; - queue.pid = current->pid; - queue.status = 0; - insert_into_queue(sma,&queue); - queue.sleeper = NULL; - current->semsleeping = &queue; - interruptible_sleep_on(&queue.sleeper); - current->semsleeping = NULL; - /* When we wake up, either the operation is finished, - * or some kind of error happened. - */ - if (!queue.prev) { - /* operation is finished, update_queue() removed us */ - error = queue.status; - } else { - remove_from_queue(sma,&queue); - error = -EINTR; - } - } + error = try_atomic_semop (sma, sops, nsops, un, current->pid, 0); + if (error <= 0) + goto update; + + /* We need to sleep on this operation, so we put the current + * task into the pending queue and go to sleep. + */ + + queue.sma = sma; + queue.sops = sops; + queue.nsops = nsops; + queue.undo = un; + queue.pid = current->pid; + queue.alter = decrease; + current->semsleeping = &queue; + if (alter) + append_to_queue(sma ,&queue); + else + prepend_to_queue(sma ,&queue); + + for (;;) { + queue.status = -EINTR; + queue.sleeper = NULL; + interruptible_sleep_on(&queue.sleeper); + + /* + * If queue.status == 1 we where woken up and + * have to retry else we simply return. + * If an interrupt occured we have to clean up the + * queue + * + */ + if (queue.status == 1) + { + error = try_atomic_semop (sma, sops, nsops, un, + current->pid,0); + if (error <= 0) + break; + } else { + error = queue.status;; + if (queue.prev) /* got Interrupt */ + break; + /* Everything done by update_queue */ + current->semsleeping = NULL; + goto out; + } + } + current->semsleeping = NULL; + remove_from_queue(sma,&queue); +update: + if (alter) + update_queue (sma); out: unlock_kernel(); return error; diff -u --recursive --new-file v2.1.132/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.132/linux/kernel/ksyms.c Tue Dec 22 14:16:59 1998 +++ linux/kernel/ksyms.c Wed Dec 23 12:53:23 1998 @@ -109,7 +109,6 @@ EXPORT_SYMBOL(update_atime); EXPORT_SYMBOL(get_super); EXPORT_SYMBOL(getname); -EXPORT_SYMBOL(putname); EXPORT_SYMBOL(__fput); EXPORT_SYMBOL(iget); EXPORT_SYMBOL(iput); @@ -129,7 +128,7 @@ EXPORT_SYMBOL(__mark_inode_dirty); EXPORT_SYMBOL(get_empty_filp); EXPORT_SYMBOL(init_private_file); -EXPORT_SYMBOL(insert_file_free); +EXPORT_SYMBOL(fput); EXPORT_SYMBOL(check_disk_change); EXPORT_SYMBOL(invalidate_buffers); EXPORT_SYMBOL(invalidate_inodes); @@ -161,7 +160,6 @@ EXPORT_SYMBOL(posix_test_lock); EXPORT_SYMBOL(posix_block_lock); EXPORT_SYMBOL(posix_unblock_lock); -EXPORT_SYMBOL(locks_remove_flock); EXPORT_SYMBOL(dput); EXPORT_SYMBOL(get_cached_page); EXPORT_SYMBOL(put_cached_page); diff -u --recursive --new-file v2.1.132/linux/kernel/module.c linux/kernel/module.c --- v2.1.132/linux/kernel/module.c Fri Nov 27 13:09:30 1998 +++ linux/kernel/module.c Sun Dec 27 10:41:41 1998 @@ -5,6 +5,7 @@ #include #include #include +#include /* * Originally by Anonymous (as far as I know...) @@ -30,7 +31,7 @@ NULL, /* next */ "", /* name */ 0, /* size */ - 1, /* usecount */ + {ATOMIC_INIT(1)}, /* usecount */ MOD_RUNNING, /* flags */ 0, /* nsyms -- to filled in in init_modules */ 0, /* ndeps */ @@ -56,7 +57,7 @@ * Called at boot time */ -void init_modules(void) +__initfunc(void init_modules(void)) { kernel_module.nsyms = __stop___ksymtab - __start___ksymtab; @@ -328,13 +329,13 @@ put_mod_name(name); /* Initialize the module. */ - mod->usecount = 1; + atomic_set(&mod->uc.usecount,1); if (mod->init && mod->init() != 0) { - mod->usecount = 0; + atomic_set(&mod->uc.usecount,0); error = -EBUSY; goto err0; } - mod->usecount--; + atomic_dec(&mod->uc.usecount); /* And set it running. */ mod->flags |= MOD_RUNNING; @@ -614,7 +615,7 @@ info.size = mod->size; info.flags = mod->flags; info.usecount = (mod_member_present(mod, can_unload) - && mod->can_unload ? -1 : mod->usecount); + && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount)); if (copy_to_user(buf, &info, sizeof(struct module_info))) return -EFAULT; @@ -853,7 +854,7 @@ len = sprintf(tmpstr, "%4ld", (mod_member_present(mod, can_unload) && mod->can_unload - ? -1 : mod->usecount)); + ? -1L : (long)atomic_read(&mod->uc.usecount))); safe_copy_str(tmpstr, len); } diff -u --recursive --new-file v2.1.132/linux/kernel/panic.c linux/kernel/panic.c --- v2.1.132/linux/kernel/panic.c Fri Nov 27 13:09:30 1998 +++ linux/kernel/panic.c Sun Dec 27 22:45:13 1998 @@ -50,7 +50,7 @@ unblank_console(); #ifdef __SMP__ - smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0); + smp_send_stop(); #endif if (panic_timeout > 0) { diff -u --recursive --new-file v2.1.132/linux/kernel/sched.c linux/kernel/sched.c --- v2.1.132/linux/kernel/sched.c Fri Nov 27 13:09:30 1998 +++ linux/kernel/sched.c Mon Dec 28 10:54:09 1998 @@ -7,6 +7,12 @@ * 1996-12-23 Modified by Dave Grothe to fix bugs in semaphores and * make semaphores SMP safe * 1997-01-28 Modified by Finn Arne Gangstad to make timers scale better. + * 1998-11-19 Implemented schedule_timeout() and related stuff + * by Andrea Arcangeli + * 1998-12-24 Fixed a xtime SMP race (we need the xtime_lock rw spinlock to + * serialize accesses to xtime/lost_ticks). + * Copyright (C) 1998 Andrea Arcangeli + * 1998-12-28 Implemented better SMP scheduling by Ingo Molnar */ /* @@ -91,47 +97,111 @@ void scheduling_functions_start_here(void) { } -static inline void reschedule_idle(struct task_struct * p) +#ifdef __SMP__ +static void reschedule_idle_slow(struct task_struct * p) { +/* + * (see reschedule_idle() for an explanation first ...) + * + * Pass #2 + * + * We try to find another (idle) CPU for this woken-up process. + * + * On SMP, we mostly try to see if the CPU the task used + * to run on is idle.. but we will use another idle CPU too, + * at this point we already know that this CPU is not + * willing to reschedule in the near future. + * + * An idle CPU is definitely wasted, especially if this CPU is + * running long-timeslice processes. The following algorithm is + * pretty good at finding the best idle CPU to send this process + * to. + * + * [We can try to preempt low-priority processes on other CPUs in + * 2.3. Also we can try to use the avg_slice value to predict + * 'likely reschedule' events even on other CPUs.] + */ + int best_cpu = p->processor, this_cpu = smp_processor_id(); + struct task_struct **idle = task, *tsk, *target_tsk; + int i = smp_num_cpus; + + target_tsk = NULL; + do { + tsk = *idle; + idle++; + if (tsk->has_cpu) { + if (tsk->processor == this_cpu) + continue; + target_tsk = tsk; + if (tsk->processor == best_cpu) { + /* + * bingo, we couldnt get a better + * CPU, activate it. + */ + goto send; /* this one helps GCC ... */ + } + } + } while (--i > 0); /* - * For SMP, we try to see if the CPU the task used - * to run on is idle.. + * found any idle CPU? */ -#if 0 + if (target_tsk) { +send: + target_tsk->need_resched = 1; + smp_send_reschedule(target_tsk->processor); + return; + } +} +#endif /* __SMP__ */ + +static inline void reschedule_idle(struct task_struct * p) +{ + + if (p->policy != SCHED_OTHER || p->counter > current->counter + 3) { + current->need_resched = 1; + return; + } + +#ifdef __SMP__ /* - * Disable this for now. Ingo has some interesting - * code that looks too complex, and I have some ideas, - * but in the meantime.. One problem is that "wakeup()" - * can be (and is) called before we've even initialized - * SMP completely, so.. + * ("wakeup()" should not be called before we've initialized + * SMP completely. + * Basically a not-yet initialized SMP subsystem can be + * considered as a not-yet working scheduler, simply dont use + * it before it's up and running ...) + * + * SMP rescheduling is done in 2 passes: + * - pass #1: faster: 'quick decisions' + * - pass #2: slower: 'lets try and find another CPU' */ -#ifdef __SMP__ - int want_cpu = p->processor; /* - * Don't even try to find another CPU for us if the task - * ran on this one before.. + * Pass #1 + * + * There are two metrics here: + * + * first, a 'cutoff' interval, currently 0-200 usecs on + * x86 CPUs, depending on the size of the 'SMP-local cache'. + * If the current process has longer average timeslices than + * this, then we utilize the idle CPU. + * + * second, if the wakeup comes from a process context, + * then the two processes are 'related'. (they form a + * 'gang') + * + * An idle CPU is almost always a bad thing, thus we skip + * the idle-CPU utilization only if both these conditions + * are true. (ie. a 'process-gang' rescheduling with rather + * high frequency should stay on the same CPU). + * + * [We can switch to something more finegrained in 2.3.] */ - if (want_cpu != smp_processor_id()) { - struct task_struct **idle = task; - int i = smp_num_cpus; - - do { - struct task_struct *tsk = *idle; - idle++; - /* Something like this.. */ - if (tsk->has_cpu && tsk->processor == want_cpu) { - tsk->need_resched = 1; - smp_send_reschedule(want_cpu); - return; - } - } while (--i > 0); - } -#endif -#endif - if (p->policy != SCHED_OTHER || p->counter > current->counter + 3) - current->need_resched = 1; + if ((current->avg_slice < cacheflush_time) && !in_interrupt()) + return; + + reschedule_idle_slow(p); +#endif /* __SMP__ */ } /* @@ -149,6 +219,7 @@ init_task.next_run = p; p->next_run = next; next->prev_run = p; + nr_running++; } static inline void del_from_runqueue(struct task_struct * p) @@ -227,7 +298,6 @@ if (!p->next_run) { add_to_runqueue(p); reschedule_idle(p); - nr_running++; } spin_unlock_irqrestore(&runqueue_lock, flags); } @@ -437,23 +507,6 @@ struct timer_list timer; unsigned long expire; - /* - * PARANOID. - */ - if (current->state == TASK_UNINTERRUPTIBLE) - { - printk(KERN_WARNING "schedule_timeout: task not interrutible " - "from %p\n", __builtin_return_address(0)); - /* - * We don' t want to interrupt a not interruptible task - * risking to cause corruption. Better a a deadlock ;-). - */ - timeout = MAX_SCHEDULE_TIMEOUT; - } - - /* - * Here we start for real. - */ switch (timeout) { case MAX_SCHEDULE_TIMEOUT: @@ -501,6 +554,63 @@ } /* + * This one aligns per-CPU data on cacheline boundaries. + */ +static union { + struct schedule_data { + struct task_struct * prev; + long prevstate; + cycles_t last_schedule; + } schedule_data; + char __pad [L1_CACHE_BYTES]; +} aligned_data [NR_CPUS] __cacheline_aligned = { {{&init_task,0}}}; + + +static inline void __schedule_tail (void) +{ +#ifdef __SMP__ + struct schedule_data * sched_data; + + /* + * We might have switched CPUs: + */ + sched_data = & aligned_data[smp_processor_id()].schedule_data; + + /* + * Subtle. In the rare event that we got a wakeup to 'prev' just + * during the reschedule (this is possible, the scheduler is pretty + * parallel), we should do another reschedule in the next task's + * context. schedule() will do the right thing next time around. + * this is equivalent to 'delaying' the wakeup until the reschedule + * has finished. + */ + if (sched_data->prev->state != sched_data->prevstate) + current->need_resched = 1; + + /* + * Release the previous process ... + * + * We have dropped all locks, and we must make sure that we + * only mark the previous process as no longer having a CPU + * after all other state has been seen by other CPU's. Thus + * the write memory barrier! + */ + wmb(); + sched_data->prev->has_cpu = 0; +#endif /* __SMP__ */ +} + +/* + * schedule_tail() is getting called from the fork return path. This + * cleans up all remaining scheduler things, without impacting the + * common case. + */ +void schedule_tail (void) +{ + __schedule_tail(); +} + +/* * 'schedule()' is the scheduler function. It's a very simple and nice * scheduler: it's not perfect, but certainly works for most things. * @@ -512,11 +622,18 @@ */ asmlinkage void schedule(void) { + struct schedule_data * sched_data; struct task_struct * prev, * next; int this_cpu; prev = current; this_cpu = prev->processor; + /* + * 'sched_data' is protected by the fact that we can run + * only one process per CPU. + */ + sched_data = & aligned_data[this_cpu].schedule_data; + if (in_interrupt()) goto scheduling_in_interrupt; release_kernel_lock(prev, this_cpu); @@ -531,6 +648,7 @@ /* move an exhausted RR process to be last.. */ prev->need_resched = 0; + if (!prev->counter && prev->policy == SCHED_RR) { prev->counter = prev->priority; move_last_runqueue(prev); @@ -546,6 +664,9 @@ del_from_runqueue(prev); case TASK_RUNNING: } + + sched_data->prevstate = prev->state; + { struct task_struct * p = init_task.next_run; /* @@ -592,25 +713,49 @@ } } + /* + * maintain the per-process 'average timeslice' value. + * (this has to be recalculated even if we reschedule to + * the same process) Currently this is only used on SMP: + */ #ifdef __SMP__ - next->has_cpu = 1; - next->processor = this_cpu; -#endif + { + cycles_t t, this_slice; - if (prev != next) { - kstat.context_swtch++; - get_mmu_context(next); - switch_to(prev,next); - } + t = get_cycles(); + this_slice = t - sched_data->last_schedule; + sched_data->last_schedule = t; - spin_unlock(&scheduler_lock); + /* + * Simple, exponentially fading average calculation: + */ + prev->avg_slice = this_slice + prev->avg_slice; + prev->avg_slice >>= 1; + } /* - * At this point "prev" is "current", as we just - * switched into it (from an even more "previous" - * prev) + * We drop the scheduler lock early (it's a global spinlock), + * thus we have to lock the previous process from getting + * rescheduled during switch_to(). */ - reacquire_kernel_lock(prev); + prev->has_cpu = 1; + + next->has_cpu = 1; + next->processor = this_cpu; + spin_unlock(&scheduler_lock); +#endif /* __SMP__ */ + if (prev != next) { +#ifdef __SMP__ + sched_data->prev = prev; +#endif + kstat.context_swtch++; + get_mmu_context(next); + switch_to(prev,next); + + __schedule_tail(); + } + + reacquire_kernel_lock(current); return; scheduling_in_interrupt: @@ -618,7 +763,6 @@ *(int *)0 = 0; } - rwlock_t waitqueue_lock = RW_LOCK_UNLOCKED; /* @@ -1189,13 +1333,21 @@ volatile unsigned long lost_ticks = 0; static unsigned long lost_ticks_system = 0; +/* + * This spinlock protect us from races in SMP while playing with xtime. -arca + */ +rwlock_t xtime_lock = RW_LOCK_UNLOCKED; + static inline void update_times(void) { unsigned long ticks; - unsigned long flags; - save_flags(flags); - cli(); + /* + * update_times() is run from the raw timer_bh handler so we + * just know that the irqs are locally enabled and so we don't + * need to save/restore the flags of the local CPU here. -arca + */ + write_lock_irq(&xtime_lock); ticks = lost_ticks; lost_ticks = 0; @@ -1206,12 +1358,12 @@ calc_load(ticks); update_wall_time(ticks); - restore_flags(flags); + write_unlock_irq(&xtime_lock); update_process_times(ticks, system); } else - restore_flags(flags); + write_unlock_irq(&xtime_lock); } static void timer_bh(void) diff -u --recursive --new-file v2.1.132/linux/mm/page_io.c linux/mm/page_io.c --- v2.1.132/linux/mm/page_io.c Tue Dec 22 14:16:59 1998 +++ linux/mm/page_io.c Mon Dec 28 13:56:29 1998 @@ -7,6 +7,7 @@ * Asynchronous swapping added 30.12.95. Stephen Tweedie * Removed race in async swapping. 14.4.1996. Bruno Haible * Add swap of shared pages through the page cache. 20.2.1998. Stephen Tweedie + * Always use brw_page, life becomes simpler. 12 May 1998 Eric Biederman */ #include @@ -15,8 +16,6 @@ #include #include -#include -#include /* for copy_to/from_user */ #include static struct wait_queue * lock_queue = NULL; @@ -24,8 +23,6 @@ /* * Reads or writes a swap page. * wait=1: start I/O and wait for completion. wait=0: start asynchronous I/O. - * All IO to swap files (as opposed to swap partitions) is done - * synchronously. * * Important prevention of race condition: the caller *must* atomically * create a unique swap cache entry for this swap page before calling @@ -38,21 +35,22 @@ * that shared pages stay shared while being swapped. */ -void rw_swap_page(int rw, unsigned long entry, char * buf, int wait) +static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, int wait) { unsigned long type, offset; struct swap_info_struct * p; - struct page *page = mem_map + MAP_NR(buf); + int zones[PAGE_SIZE/512]; + int zones_used; + kdev_t dev = 0; + int block_size; #ifdef DEBUG_SWAP printk ("DebugVM: %s_swap_page entry %08lx, page %p (count %d), %s\n", (rw == READ) ? "read" : "write", - entry, buf, atomic_read(&page->count), + entry, (char *) page_address(page), atomic_read(&page->count), wait ? "wait" : "nowait"); #endif - if (page->inode && page->inode != &swapper_inode) - panic ("Tried to swap a non-swapper page"); type = SWP_TYPE(entry); if (type >= nr_swapfiles) { printk("Internal error: bad swap-device\n"); @@ -85,13 +83,27 @@ printk(KERN_ERR "VM: swap page is unlocked\n"); return; } - - /* Make sure we are the only process doing I/O with this swap page. */ - while (test_and_set_bit(offset,p->swap_lockmap)) { - run_task_queue(&tq_disk); - sleep_on(&lock_queue); + + if (PageSwapCache(page)) { + /* Make sure we are the only process doing I/O with this swap page. */ + while (test_and_set_bit(offset,p->swap_lockmap)) { + run_task_queue(&tq_disk); + sleep_on(&lock_queue); + } + + /* + * Make sure that we have a swap cache association for this + * page. We need this to find which swap page to unlock once + * the swap IO has completed to the physical page. If the page + * is not already in the cache, just overload the offset entry + * as if it were: we are not allowed to manipulate the inode + * hashing for locked pages. + */ + if (page->offset != entry) { + printk ("swap entry mismatch"); + return; + } } - if (rw == READ) { clear_bit(PG_uptodate, &page->flags); kstat.pswpin++; @@ -99,54 +111,25 @@ kstat.pswpout++; atomic_inc(&page->count); - /* - * Make sure that we have a swap cache association for this - * page. We need this to find which swap page to unlock once - * the swap IO has completed to the physical page. If the page - * is not already in the cache, just overload the offset entry - * as if it were: we are not allowed to manipulate the inode - * hashing for locked pages. - */ - if (!PageSwapCache(page)) { - printk(KERN_ERR "VM: swap page is not in swap cache\n"); - return; - } - if (page->offset != entry) { - printk (KERN_ERR "VM: swap entry mismatch\n"); - return; - } - if (p->swap_device) { - if (!wait) { - set_bit(PG_free_after, &page->flags); - set_bit(PG_decr_after, &page->flags); - set_bit(PG_swap_unlock_after, &page->flags); - atomic_inc(&nr_async_pages); - } - ll_rw_page(rw,p->swap_device,offset,buf); - /* - * NOTE! We don't decrement the page count if we - * don't wait - that will happen asynchronously - * when the IO completes. - */ - if (!wait) - return; - wait_on_page(page); + zones[0] = offset; + zones_used = 1; + dev = p->swap_device; + block_size = PAGE_SIZE; } else if (p->swap_file) { struct inode *swapf = p->swap_file->d_inode; - unsigned int zones[PAGE_SIZE/512]; int i; if (swapf->i_op->bmap == NULL && swapf->i_op->smap != NULL){ /* - With MS-DOS, we use msdos_smap which return + With MS-DOS, we use msdos_smap which returns a sector number (not a cluster or block number). It is a patch to enable the UMSDOS project. Other people are working on better solution. It sounds like ll_rw_swap_file defined - it operation size (sector size) based on - PAGE_SIZE and the number of block to read. + its operation size (sector size) based on + PAGE_SIZE and the number of blocks to read. So using bmap or smap should work even if smap will require more blocks. */ @@ -159,39 +142,72 @@ return; } } + block_size = 512; }else{ int j; unsigned int block = offset << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits); - for (i=0, j=0; j< PAGE_SIZE ; i++, j +=swapf->i_sb->s_blocksize) + block_size = swapf->i_sb->s_blocksize; + for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size) if (!(zones[i] = bmap(swapf,block++))) { printk("rw_swap_page: bad swap file\n"); return; } + zones_used = i; + dev = swapf->i_dev; } - ll_rw_swap_file(rw,swapf->i_dev, zones, i,buf); - /* Unlike ll_rw_page, ll_rw_swap_file won't unlock the - page for us. */ - clear_bit(PG_locked, &page->flags); - wake_up(&page->wait); - } else + } else { printk(KERN_ERR "rw_swap_page: no swap file or device\n"); - + /* Do some cleaning up so if this ever happens we can hopefully + * trigger controlled shutdown. + */ + if (PageSwapCache(page)) { + if (!test_and_clear_bit(offset,p->swap_lockmap)) + printk("swap_after_unlock_page: lock already cleared\n"); + wake_up(&lock_queue); + } + atomic_dec(&page->count); + return; + } + if (!wait) { + set_bit(PG_decr_after, &page->flags); + atomic_inc(&nr_async_pages); + } + if (PageSwapCache(page)) { + /* only lock/unlock swap cache pages! */ + set_bit(PG_swap_unlock_after, &page->flags); + } + set_bit(PG_free_after, &page->flags); + + /* block_size == PAGE_SIZE/zones_used */ + brw_page(rw, page, dev, zones, block_size, 0); + + /* Note! For consistency we do all of the logic, + * decrementing the page count, and unlocking the page in the + * swap lock map - in the IO completion handler. + */ + if (!wait) + return; + wait_on_page(page); /* This shouldn't happen, but check to be sure. */ - if (atomic_read(&page->count) == 1) + if (atomic_read(&page->count) == 0) printk(KERN_ERR "rw_swap_page: page unused while waiting!\n"); - atomic_dec(&page->count); - if (offset && !test_and_clear_bit(offset,p->swap_lockmap)) - printk(KERN_ERR "rw_swap_page: lock already cleared\n"); - wake_up(&lock_queue); + #ifdef DEBUG_SWAP printk ("DebugVM: %s_swap_page finished on page %p (count %d)\n", (rw == READ) ? "read" : "write", - buf, atomic_read(&page->count)); + (char *) page_adddress(page), + atomic_read(&page->count)); #endif } +/* Note: We could remove this totally asynchronous function, + * and improve swap performance, and remove the need for the swap lock map, + * by not removing pages from the swap cache until after I/O has been + * processed and letting remove_from_page_cache decrement the swap count + * just before it removes the page from the page cache. + */ /* This is run when asynchronous page I/O has completed. */ void swap_after_unlock_page (unsigned long entry) { @@ -214,6 +230,35 @@ wake_up(&lock_queue); } +/* A simple wrapper so the base function doesn't need to enforce + * that all swap pages go through the swap cache! + */ +void rw_swap_page(int rw, unsigned long entry, char *buf, int wait) +{ + struct page *page = mem_map + MAP_NR(buf); + + if (page->inode && page->inode != &swapper_inode) + panic ("Tried to swap a non-swapper page"); + + /* + * Make sure that we have a swap cache association for this + * page. We need this to find which swap page to unlock once + * the swap IO has completed to the physical page. If the page + * is not already in the cache, just overload the offset entry + * as if it were: we are not allowed to manipulate the inode + * hashing for locked pages. + */ + if (!PageSwapCache(page)) { + printk("VM: swap page is not in swap cache\n"); + return; + } + if (page->offset != entry) { + printk ("swap entry mismatch"); + return; + } + rw_swap_page_base(rw, entry, page, wait); +} + /* * Setting up a new swap file needs a simple wrapper just to read the * swap signature. SysV shared memory also needs a simple wrapper. @@ -242,33 +287,23 @@ clear_bit(PG_swap_cache, &page->flags); } - - /* - * Swap partitions are now read via brw_page. ll_rw_page is an - * asynchronous function now --- we must call wait_on_page afterwards - * if synchronous IO is required. + * shmfs needs a version that doesn't put the page in the page cache! + * The swap lock map insists that pages be in the page cache! + * Therefore we can't use it. Later when we can remove the need for the + * lock map and we can reduce the number of functions exported. */ -void ll_rw_page(int rw, kdev_t dev, unsigned long offset, char * buffer) +void rw_swap_page_nolock(int rw, unsigned long entry, char *buffer, int wait) { - int block = offset; - struct page *page; - - switch (rw) { - case READ: - break; - case WRITE: - if (is_read_only(dev)) { - printk("Can't page to read-only device %s\n", - kdevname(dev)); - return; - } - break; - default: - panic("ll_rw_page: bad block dev cmd, must be R/W"); - } - page = mem_map + MAP_NR(buffer); - if (!PageLocked(page)) - panic ("ll_rw_page: page not already locked"); - brw_page(rw, page, dev, &block, PAGE_SIZE, 0); + struct page *page = mem_map + MAP_NR((unsigned long) buffer); + + if (!PageLocked(page)) { + printk("VM: rw_swap_page_nolock: page not locked!\n"); + return; + } + if (PageSwapCache(page)) { + printk ("VM: rw_swap_page_nolock: page in swap cache!\n"); + return; + } + rw_swap_page_base(rw, entry, page, wait); } diff -u --recursive --new-file v2.1.132/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c --- v2.1.132/linux/net/appletalk/aarp.c Thu Nov 19 09:56:29 1998 +++ linux/net/appletalk/aarp.c Wed Dec 23 09:44:42 1998 @@ -294,7 +294,7 @@ while((*n)!=NULL) { /* Expired ? */ - if((*n)->expires_at < jiffies) + if(time_after(jiffies, (*n)->expires_at)) { t= *n; *n=(*n)->next; diff -u --recursive --new-file v2.1.132/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c --- v2.1.132/linux/net/appletalk/ddp.c Tue Dec 22 14:16:59 1998 +++ linux/net/appletalk/ddp.c Wed Dec 23 14:10:36 1998 @@ -31,12 +31,19 @@ * AppleTalk drivers, cleaned it. * Rob Newberry : Added proxy AARP and AARP proc fs, * moved probing to AARP module. + * Adrian Sun/ + * Michael Zuelsdorff : fix for net.0 packets. don't + * allow illegal ether/tokentalk + * port assignment. we lose a + * valid localtalk port as a + * result. + * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. - * + * */ #include @@ -141,7 +148,7 @@ continue; } - if(to->sat_addr.s_net == 0 + if(to->sat_addr.s_net == ATADDR_ANYNET && to->sat_addr.s_node == ATADDR_BCAST && s->protinfo.af_at.src_net == atif->address.s_net) { @@ -156,7 +163,14 @@ break; } - /* XXXX.0 */ + /* XXXX.0 -- we got a request for this router. make sure + * that the node is appropriately set. */ + if (to->sat_addr.s_node == ATADDR_ANYNODE && + to->sat_addr.s_net != ATADDR_ANYNET && + atif->address.s_node == s->protinfo.af_at.src_node) { + to->sat_addr.s_node = atif->address.s_node; + break; + } } return (s); @@ -502,6 +516,12 @@ && iface->address.s_net==net && !(iface->status & ATIF_PROBE)) return (iface); + + /* XXXX.0 -- net.0 returns the iface associated with net */ + if ((node==ATADDR_ANYNODE) && (net != ATADDR_ANYNET) && + (ntohs(iface->nets.nr_firstnet) <= ntohs(net)) && + (ntohs(net) <= ntohs(iface->nets.nr_lastnet))) + return (iface); } return (NULL); diff -u --recursive --new-file v2.1.132/linux/net/bridge/br.c linux/net/bridge/br.c --- v2.1.132/linux/net/bridge/br.c Tue Dec 22 14:16:59 1998 +++ linux/net/bridge/br.c Wed Dec 23 09:44:42 1998 @@ -1539,7 +1539,7 @@ f->mcast_timer = jiffies; else { if(f->mcast_count > max_mcast_per_period) { - if(jiffies > (f->mcast_timer + mcast_hold_time)) + if(time_after(jiffies, f->mcast_timer + mcast_hold_time)) f->mcast_count = 0; else return 1; } diff -u --recursive --new-file v2.1.132/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c --- v2.1.132/linux/net/ipv6/af_inet6.c Mon Oct 5 13:13:49 1998 +++ linux/net/ipv6/af_inet6.c Sun Dec 27 10:44:45 1998 @@ -477,7 +477,7 @@ { if (!unloadable) return 1; /* We keep internally 3 raw sockets */ - return __this_module.usecount - 3; + return atomic_read(&(__this_module.uc.usecount)) - 3; } #endif diff -u --recursive --new-file v2.1.132/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c --- v2.1.132/linux/net/ipx/af_ipx.c Thu Nov 19 09:56:29 1998 +++ linux/net/ipx/af_ipx.c Mon Dec 28 11:06:44 1998 @@ -50,6 +50,9 @@ * Revision 0.39: SPX interfaces * Revision 0.40: Tiny SIOCGSTAMP fix (chris@cybernet.co.nz) * Revision 0.41: 802.2TR removed (p.norton@computer.org) + * Fixed connecting to primary net, + * Automatic binding on send & receive, + * Martijn van Oosterhout * * Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT * pair. Also, now usage count is managed this way @@ -450,7 +453,57 @@ struct sock *sock1 = NULL, *sock2 = NULL; struct sk_buff *skb1 = NULL, *skb2 = NULL; - sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); + if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451) + { + /* + * The packet's target is a NCP connection handler. We want to + * hand it to the correct socket directly within the kernel, + * so that the mars_nwe packet distribution process + * does not have to do it. Here we only care about NCP and + * BURST packets. + * You might call this a hack, but believe me, you do not + * want a complete NCP layer in the kernel, and this is + * VERY fast as well. + */ + int connection = 0; + + if (*((char*)(ipx+1)) == 0x22 && *((char*)(ipx+1)+1) == 0x22) + { + /* + * The packet is a NCP request + */ + connection = ( ((int) *((char*)(ipx+1)+5)) << 8 ) + | (int) *((char*)(ipx+1)+3); + } + else if (*((char*)(ipx+1))== 0x77 && *((char*)(ipx+1)+1) == 0x77) + { + /* + * The packet is a BURST packet + */ + connection = ( ((int) *((char*)(ipx+1)+9)) << 8 ) + | (int) *((char*)(ipx+1)+8); + } + + if (connection) + { + /* + * Now we have to look for a special NCP connection handling + * socket. Only these sockets have ipx_ncp_conn != 0, set + * by SIOCIPXNCPCONN. + */ + for (sock1=intrfc->if_sklist; + (sock1 != NULL) && + (sock1->protinfo.af_ipx.ipx_ncp_conn != connection); + sock1=sock1->next); + } + } + if (sock1 == NULL) + { + /* No special socket found, forward the packet the + * normal way. + */ + sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); + } /* * We need to check if there is a primary net and if @@ -1822,7 +1875,7 @@ } /* protect IPX system stuff like routing/sap */ - if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !suser()) + if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !capable(CAP_NET_ADMIN)) return (-EACCES); sk->protinfo.af_ipx.port = addr->sipx_port; @@ -1930,7 +1983,8 @@ return (ret); } - if(ipxrtr_lookup(addr->sipx_network) == NULL) + /* We can either connect to primary network or somewhere we can route to */ + if( !(addr->sipx_network == 0 && ipx_primary_net != NULL) && ipxrtr_lookup(addr->sipx_network) == NULL) return (-ENETUNREACH); sk->protinfo.af_ipx.dest_addr.net = addr->sipx_network; @@ -2061,8 +2115,9 @@ int retval; int flags = msg->msg_flags; - if(sk->zapped) - return (-EIO); /* Socket not bound */ + /* Socket gets bound below anyway */ +/* if(sk->zapped) + return (-EIO); */ /* Socket not bound */ if(flags & ~MSG_DONTWAIT) return (-EINVAL); @@ -2120,6 +2175,26 @@ struct sk_buff *skb; int copied, err; + /* put the autobinding in */ + if(sk->protinfo.af_ipx.port == 0) + { + struct sockaddr_ipx uaddr; + int ret; + + uaddr.sipx_port = 0; + uaddr.sipx_network = 0; + +#ifdef CONFIG_IPX_INTERN + memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node, + IPX_NODE_LEN); +#endif /* CONFIG_IPX_INTERN */ + + ret = ipx_bind(sock, (struct sockaddr *)&uaddr, + sizeof(struct sockaddr_ipx)); + if(ret != 0) + return (ret); + } + if(sk->zapped) return (-ENOTCONN); @@ -2191,14 +2266,14 @@ case SIOCADDRT: case SIOCDELRT: - if(!suser()) + if(!capable(CAP_NET_ADMIN)) return (-EPERM); return (ipxrtr_ioctl(cmd,(void *)arg)); case SIOCSIFADDR: case SIOCAIPXITFCRT: case SIOCAIPXPRISLT: - if(!suser()) + if(!capable(CAP_NET_ADMIN)) return (-EPERM); case SIOCGIFADDR: @@ -2206,6 +2281,17 @@ case SIOCIPXCFGDATA: return (ipxcfg_get_config_data((void *)arg)); + + case SIOCIPXNCPCONN: + { + /* + * This socket wants to take care of the NCP connection + * handed to us in arg. + */ + if (!capable(CAP_NET_ADMIN)) + return(-EPERM); + return get_user(sk->protinfo.af_ipx.ipx_ncp_conn, (const unsigned short *)(arg)); + } case SIOCGSTAMP: { diff -u --recursive --new-file v2.1.132/linux/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c --- v2.1.132/linux/net/netrom/nr_dev.c Thu Feb 12 20:56:15 1998 +++ linux/net/netrom/nr_dev.c Mon Dec 28 11:06:44 1998 @@ -52,6 +52,8 @@ #include #include +#ifdef CONFIG_INET + /* * Only allow IP over NET/ROM frames through if the netrom device is up. */ @@ -81,37 +83,6 @@ return 1; } -static int nr_header(struct sk_buff *skb, struct device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) -{ - unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN); - - memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len); - buff[6] &= ~AX25_CBIT; - buff[6] &= ~AX25_EBIT; - buff[6] |= AX25_SSSID_SPARE; - buff += AX25_ADDR_LEN; - - if (daddr != NULL) - memcpy(buff, daddr, dev->addr_len); - buff[6] &= ~AX25_CBIT; - buff[6] |= AX25_EBIT; - buff[6] |= AX25_SSSID_SPARE; - buff += AX25_ADDR_LEN; - - *buff++ = sysctl_netrom_network_ttl_initialiser; - - *buff++ = NR_PROTO_IP; - *buff++ = NR_PROTO_IP; - *buff++ = 0; - *buff++ = 0; - *buff++ = NR_PROTOEXT; - - if (daddr != NULL) - return 37; - - return -37; -} static int nr_rebuild_header(struct sk_buff *skb) { @@ -121,10 +92,6 @@ unsigned char *bp = skb->data; if (arp_find(bp + 7, skb)) { -#if 0 - /* BUGGGG! If arp_find returned 1, skb does not exist. --ANK*/ - kfree_skb(skb); -#endif return 1; } @@ -156,6 +123,47 @@ stats->tx_bytes += skbn->len; return 1; +} + +#else + +static int nr_rebuild_header(struct sk_buff *skb) +{ + return 1; +} + +#endif + +static int nr_header(struct sk_buff *skb, struct device *dev, unsigned short type, + void *daddr, void *saddr, unsigned len) +{ + unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN); + + memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len); + buff[6] &= ~AX25_CBIT; + buff[6] &= ~AX25_EBIT; + buff[6] |= AX25_SSSID_SPARE; + buff += AX25_ADDR_LEN; + + if (daddr != NULL) + memcpy(buff, daddr, dev->addr_len); + buff[6] &= ~AX25_CBIT; + buff[6] |= AX25_EBIT; + buff[6] |= AX25_SSSID_SPARE; + buff += AX25_ADDR_LEN; + + *buff++ = sysctl_netrom_network_ttl_initialiser; + + *buff++ = NR_PROTO_IP; + *buff++ = NR_PROTO_IP; + *buff++ = 0; + *buff++ = 0; + *buff++ = NR_PROTOEXT; + + if (daddr != NULL) + return 37; + + return -37; } static int nr_set_mac_address(struct device *dev, void *addr) diff -u --recursive --new-file v2.1.132/linux/net/sched/sch_api.c linux/net/sched/sch_api.c --- v2.1.132/linux/net/sched/sch_api.c Sat Sep 5 16:46:42 1998 +++ linux/net/sched/sch_api.c Wed Dec 23 09:44:42 1998 @@ -898,7 +898,7 @@ stop = jiffies + HZ/10; PSCHED_GET_TIME(stamp); do_gettimeofday(&tv); - while (jiffies < stop) + while (time_before(jiffies, stop)) barrier(); PSCHED_GET_TIME(stamp1); do_gettimeofday(&tv1); diff -u --recursive --new-file v2.1.132/linux/net/sunrpc/auth.c linux/net/sunrpc/auth.c --- v2.1.132/linux/net/sunrpc/auth.c Mon Apr 7 11:35:33 1997 +++ linux/net/sunrpc/auth.c Wed Dec 23 09:44:42 1998 @@ -117,7 +117,7 @@ printk("RPC: rpcauth_gc_credcache looping!\n"); break; } - if (!cred->cr_count && cred->cr_expire < jiffies) { + if (!cred->cr_count && time_after(jiffies, cred->cr_expire)) { *q = cred->cr_next; cred->cr_next = free; free = cred; @@ -160,7 +160,7 @@ nr = RPC_DO_ROOTOVERRIDE(task)? 0 : (current->uid % RPC_CREDCACHE_NR); - if (auth->au_nextgc < jiffies) + if (time_after(jiffies, auth->au_nextgc)) rpcauth_gc_credcache(auth); q = &auth->au_credcache[nr]; diff -u --recursive --new-file v2.1.132/linux/net/sunrpc/xprt.c linux/net/sunrpc/xprt.c --- v2.1.132/linux/net/sunrpc/xprt.c Mon Oct 5 13:13:49 1998 +++ linux/net/sunrpc/xprt.c Wed Dec 23 09:44:42 1998 @@ -293,7 +293,7 @@ if (xprt->nocong) return; if (result >= 0) { - if (xprt->cong < cwnd || jiffies < xprt->congtime) + if (xprt->cong < cwnd || time_before(jiffies, xprt->congtime)) return; /* The (cwnd >> 1) term makes sure * the result gets rounded properly. */ @@ -543,7 +543,7 @@ pkt_cnt++; pkt_len += req->rq_slen + copied; pkt_rtt += jiffies - req->rq_xtime; - if (nextstat < jiffies) { + if (time_after(jiffies, nextstat)) { printk("RPC: %lu %ld cwnd\n", jiffies, xprt->cwnd); printk("RPC: %ld %ld %ld %ld stat\n", jiffies, pkt_cnt, pkt_len, pkt_rtt); diff -u --recursive --new-file v2.1.132/linux/net/wanrouter/wanmain.c linux/net/wanrouter/wanmain.c --- v2.1.132/linux/net/wanrouter/wanmain.c Tue Dec 22 14:16:59 1998 +++ linux/net/wanrouter/wanmain.c Mon Dec 28 11:07:13 1998 @@ -27,6 +27,9 @@ * May 17, 1998 K. Baranowski Fixed SNAP encapsulation in wan_encapsulate * Dec 15, 1998 Arnaldo Melo support for firmwares of up to 128000 bytes * check wandev->setup return value +* Dec 22, 1998 Arnaldo Melo vmalloc/vfree used in device_setup to allocate +* kernel memory and copy configuration data to +* kernel space (for big firmwares) *****************************************************************************/ #include /* offsetof(), etc. */ @@ -36,6 +39,7 @@ #include /* kmalloc(), kfree() */ #include /* verify_area(), etc. */ #include /* inline mem*, str* functions */ +#include /* vmalloc, vfree */ #include /* kernel <-> user copy */ #include /* htons(), etc. */ #include /* copy_to/from_user */ @@ -100,7 +104,30 @@ static unsigned char oui_802_2[] = { 0x00, 0x80, 0xC2 }; #endif -#ifdef MODULE +#ifndef MODULE + +int wanrouter_init(void) +{ + int err; + extern void wanpipe_init(void); + + printk(KERN_INFO "%s v%u.%u %s\n", + fullname, ROUTER_VERSION, ROUTER_RELEASE, copyright); + err = wanrouter_proc_init(); + if (err) + printk(KERN_ERR "%s: can't create entry in proc filesystem!\n", modname); + + /* + * Initialise compiled in boards + */ + +#ifdef CONFIG_VENDOR_SANGOMA + wanpipe_init(); +#endif + return err; +} + +#else /* * Kernel Loadable Module Entry Points @@ -139,14 +166,6 @@ wanrouter_proc_cleanup(); } -#else - -__initfunc(void wanrouter_init(void)) -{ - int err = wanrouter_proc_init(); - if (err) printk(KERN_ERR - "%s: can't create entry in proc filesystem!\n", modname); -} #endif /* @@ -440,7 +459,7 @@ static int device_setup (wan_device_t* wandev, wandev_conf_t* u_conf) { void* data; - wandev_conf_t* conf; + wandev_conf_t *conf; int err= -EINVAL; if (wandev->setup == NULL) /* Nothing to do ? */ @@ -464,7 +483,7 @@ if(conf->data_size > 128000 || conf->data_size < 0){ goto bail; } - data = kmalloc(conf->data_size, GFP_KERNEL); + data = vmalloc(conf->data_size); if (data) { if(!copy_from_user(data, conf->data, conf->data_size)) @@ -473,10 +492,13 @@ err = wandev->setup(wandev,conf); } else - err = -ENOBUFS; + err = -EFAULT; } + else + err = -ENOBUFS; + if (data) - kfree(data); + vfree(data); } bail: kfree(conf); diff -u --recursive --new-file v2.1.132/linux/scripts/Menuconfig linux/scripts/Menuconfig --- v2.1.132/linux/scripts/Menuconfig Thu May 7 22:51:56 1998 +++ linux/scripts/Menuconfig Wed Dec 23 07:26:32 1998 @@ -47,6 +47,16 @@ # # 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help # texts. +# +# 12 Dec 1998, Michael Elizabeth Chastain (mec@shout.net) +# Remove a /tmp security hole in get_def (also makes it faster). +# Give uninitialized variables canonical values rather than null value. +# Change a lot of places to call set_x_info uniformly. +# Take out message about preparing version (old sound driver cruft). +# +# 13 Dec 1998, Riley H Williams (rhw@bigfoot.com) +# When an error occurs, actually display the error message as well as +# our comments thereon. # @@ -65,20 +75,24 @@ # set -h +o posix -# -# Converts "# xxx is not..." to xxx=n -# -parse_config () { - sed -e 's/# \(.*\) is not.*/\1=n/' -} -# -# Parses the defconfig file to set the default for a new parameter. -# -function get_def () { - parse_config < arch/$ARCH/defconfig | grep "^$1=" > /tmp/conf.$$ - . /tmp/conf.$$ - rm /tmp/conf.$$ + +# Given a configuration variable, set the global variable $x to its value, +# and the global variable $info to the string " (NEW)" if this is a new +# variable. +# +# This function looks for: (1) the current value, or (2) the default value +# from the arch-dependent defconfig file, or (3) a default passed by the caller. + +function set_x_info () { + eval x=\$$1 + if [ -z "$x" ]; then + eval `sed -n -e 's/# \(.*\) is not set.*/\1=n/' -e "/^$1=/p" arch/$ARCH/defconfig` + eval x=\${$1:-"$2"} + eval $1=$x + eval INFO_$1="' (NEW)'" + fi + eval info="\$INFO_$1" } # @@ -93,19 +107,6 @@ load_functions () { # -# Macro for setting the x and info varibles. get's default from defconfig -# file if it's a new parameter. -# -function set_x () { - eval x=\$$1 - if [ -z "$x" ]; then - get_def "$1" - eval x=\${$1:-'n'} INFO_$1="' (NEW)'" - fi - eval info="\$INFO_$1" -} - -# # Additional comments # function comment () { @@ -125,7 +126,7 @@ # which calls our local bool function. # function bool () { - set_x "$2" + set_x_info "$2" "n" case $x in y|m) flag="*" ;; @@ -148,7 +149,7 @@ then bool "$1" "$2" else - set_x "$2" + set_x_info "$2" "n" case $x in y) flag="*" ;; @@ -193,9 +194,9 @@ # Add a menu item which will call our local int function. # function int () { - eval $2=\${$2:-"$3"} x=\$$2 + set_x_info "$2" "$3" - echo -ne "'$2' '($x) $1' " >>MCmenu + echo -ne "'$2' '($x) $1$info' " >>MCmenu echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' ;}" >>MCradiolists } @@ -204,9 +205,10 @@ # Add a menu item which will call our local hex function. # function hex () { - eval $2=\${$2:-"$3"} x=\${$2##*[x,X]} + set_x_info "$2" "$3" + x=${x##*[x,X]} - echo -ne "'$2' '($x) $1' " >>MCmenu + echo -ne "'$2' '($x) $1$info' " >>MCmenu echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' ;}" >>MCradiolists } @@ -215,9 +217,9 @@ # Add a menu item which will call our local string function. # function string () { - eval $2=\${$2:-"$3"} x=\$$2 + set_x_info "$2" "$3" - echo -ne "'$2' ' $1: \"$x\"' " >>MCmenu + echo -ne "'$2' ' $1: \"$x\"$info' " >>MCmenu echo -e "function $2 () { l_string '$1' '$2' '$3' '$x' ;}" >>MCradiolists } @@ -370,7 +372,7 @@ # Same as bool() except options are (Module/No) # function mod_bool () { - set_x "$2" + set_x_info "$2" "n" case $x in y|m) flag='M' ;; @@ -722,14 +724,20 @@ do comment_ctr=0 #So comment lines get unique tags - $1 "$default" #Create the lxdialog menu & functions + $1 "$default" 2> MCerror #Create the lxdialog menu & functions if [ "$?" != "0" ] then clear cat < /' MCerror + cat <. You may also send a problem report to . @@ -741,6 +749,7 @@ cleanup exit 1 fi + rm -f MCerror . ./MCradiolists #Source the menu's functions @@ -778,6 +787,7 @@ stty sane clear cat <>$CONFIG echo "#define $2 ($x)" >>$CONFIG_H } function hex () { - eval x=\${$2:-"$3"} + set_x_info "$2" "$3" echo "$2=$x" >>$CONFIG echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H } function string () { - eval x=\${$2:-"$3"} + set_x_info "$2" "$3" echo "$2=\"$x\"" >>$CONFIG echo "#define $2 \"$x\"" >>$CONFIG_H } @@ -1250,10 +1240,8 @@ # Fresh new log. >.menuconfig.log -echo -n "Preparing configuration scripts: version" - # Load the functions used by the config.in files. -echo -n ", functions" +echo -n "Preparing scripts: functions" load_functions if [ ! -e $CONFIG_IN ]