diff -u --recursive --new-file v9/linux/CREDITS linux/CREDITS --- v9/linux/CREDITS Sun Aug 17 12:48:45 1997 +++ linux/CREDITS Wed Sep 17 12:00:48 1997 @@ -42,7 +42,7 @@ D: Moving all VFS access checks into the file systems S: MIT Room E15-341 S: 20 Ames Street -S: Cambridge, Massachusetts 02139 +S: Cambridge, Massachusetts 02139 S: USA N: John Aycock @@ -107,7 +107,9 @@ N: Randolph Bentson E: bentson@grieg.seaslug.org -D: author of driver for Cyclades Cyclom-Y async mux +W: http://www.aa.net/~bentson/ +P: 1024/39ED5729 5C A8 7A F4 B2 7A D1 3E B5 3B 81 CF 47 30 11 71 +D: Author of driver for Cyclades Cyclom-Y async mux S: 2322 37th Ave SW S: Seattle, Washington 98126-2010 S: USA @@ -122,7 +124,9 @@ S: The Netherlands N: Hennus Bergman -E: hennus@sky.ow.nl [My uucp-fed Linux box at home] +E: hennus@cybercomm.nl +W: http://www.cybercomm.nl/~hennus/ +P: 1024/77D50909 76 99 FD 31 91 E1 96 1C 90 BB 22 80 62 F6 BD 63 D: Author and maintainer of the QIC-02 tape driver S: The Netherlands @@ -131,16 +135,14 @@ D: Original author of the Linux networking code N: Philip Blundell -E: pjb27@cam.ac.uk -E: pb@nexus.co.uk -E: phil@tazenda.demon.co.uk +E: Philip.Blundell@pobox.com D: Device driver hacking (especially EtherExpress16/3C505 net cards) D: Some Linux/ARM stuff -S: Trinity College -S: Cambridge, UK. CB2 1TQ +S: 201 Gilbert Road +S: Cambridge, UK. CB4 3PA N: Thomas Bogendoerfer -E: tsbogend@bigbug.franken.de +E: tsbogend@alpha.franken.de D: Lance32 driver D: strace for Linux/Alpha S: Baumgartenweg 5 @@ -148,12 +150,8 @@ S: Germany N: Bill Bogstad -E: bogstad@cs.jhu.edu -D: Wrote /proc/self patch -S: Johns Hopkins University -S: Computer Science Department -S: Baltimore, Maryland 21218 -S: USA +E: bogstad@pobox.com +D: wrote /proc/self hack, minor samba & dosemu patches N: Axel Boldt E: boldt@math.ucsb.edu @@ -214,7 +212,7 @@ S: Fremont, California 94536 S: USA -N: Chih-Jen Chang +N: Chih-Jen Chang E: chihjenc@scf.usc.edu E: chihjen@iis.sinica.edu.tw D: IGMP(Internet Group Management Protocol) version 2 @@ -240,9 +238,10 @@ N: Juan Jose Ciarlante E: jjciarla@raiz.uncu.edu.ar -E: irriga@impsat1.com.ar +E: juanjo@irriga.uncu.edu.ar D: Network driver alias support D: IP masq hashing and app modules +D: IP ip_dynaddr bits S: Las Cuevas 2385 - Bo Guemes S: Las Heras, Mendoza CP 5539 S: Argentina @@ -256,16 +255,9 @@ N: Alan Cox E: alan@lxorguk.ukuu.org.uk (linux related - except big patches) -E: iialan@www.linux.org.uk (linux.org.uk/big patches) +E: iialan@www.uk.linux.org (linux.org.uk/big patches) E: alan@cymru.net (commercial CymruNET stuff) -E: gw4pts@gw4pts.ampr.org (amateur radio stuff) -E: GW4PTS@GB7SWN (packet radio) -E: Please don't use iialan@iifeak.swan.ac.uk for Linux stuff -S: c/o 3Com/I^2IT Limited -S: The Innovation Centre -S: University Of Wales -S: Swansea, SA2 8PP -S: Wales, UK +E: Alan.Cox@linux.org (if others fail) D: NET2Debugged/NET3 author D: Network layer debugging D: Initial AX.25 & IPX releases @@ -273,6 +265,11 @@ D: Current 3c501 hacker. >>More 3c501 info/tricks wanted<<. D: Watchdog timer drivers D: Linux/SMP +S: CymruNet Limited +S: The Innovation Centre +S: Singleton Park +S: Swansea, SA2 8PP +S: Wales, United Kingdom N: Laurence Culhane E: loz@holmes.demon.co.uk @@ -285,6 +282,7 @@ N: Ray Dassen E: jdassen@wi.LeidenUniv.nl W: http://www.wi.leidenuniv.nl/~jdassen/ +P: 1024/672D05C1 DD 60 32 60 F7 90 64 80 E7 6F D4 E4 F8 C9 4A 58 D: Debian GNU/Linux: www.debian.org maintainer, FAQ co-maintainer, D: packages testing, nit-picking & fixing. Enjoying BugFree (TM) kernels. S: Zuidsingel 10A @@ -293,12 +291,12 @@ N: David Davies E: davies@wanton.lkg.dec.com -S: Digital Equipment Corporation -S: 550 King Street -S: Littleton, MA 01460 -S: U.S.A. D: Network driver author - depca, ewrk3 and de4x5 D: Wrote shared interrupt support +S: Digital Equipment Corporation +S: 550 King Street +S: Littleton, Massachusetts 01460 +S: USA N: Wayne Davison E: davison@borland.com @@ -311,12 +309,10 @@ N: Todd J. Derr E: tjd@fore.com -D: x86 VESA console blanking enhancements -D: maintainer of dual-monitor patches for 1.0+ -D: MouseMan driver for selection -S: Fore Systems, Inc. -S: 5800 Corporate Drive -S: Pittsburgh, Pennsylvania 15237-5829 +W: http://www.wordsmith.org/~tjd +D: Random console hacks and other miscellaneous stuff +S: 3000 FORE Drive +S: Warrendale, Pennsylvania 15086 S: USA N: Eddie C. Dost @@ -348,7 +344,7 @@ D: SCSI code D: Assorted snippets elsewhere D: Boot sector "..." printing -S: 2255 Spruce +S: 2037 Walnut #6 S: Boulder, Colorado 80302 S: USA @@ -413,7 +409,7 @@ S: Australia N: Ralf Flaxa -E: rf@lst.de +E: rfflaxa@immd4.informatik.uni-erlangen.de D: The Linux Support Team Erlangen D: Creator of LST distribution D: Author of installation tool LISA @@ -469,15 +465,6 @@ E: philip@raptor.com D: Kernel / timekeeping stuff -N: Michael A. Griffith -E: grif@cs.ucr.edu -W: http://www.cs.ucr.edu/~grif -D: Loopback speedup, qlogic scsi hacking, VT_LOCKSWITCH -S: Department of Computer Science -S: University of California, Riverside -S: Riverside, California 92521-0304 -S: USA - N: Dmitry S. Gorodchanin E: begemot@bgm.rosprint.net D: RISCom/8 driver, misc kernel fixes. @@ -499,7 +486,16 @@ E: jgotts@engin.umich.edu D: kernel hacker S: 8124 Constitution Apt. 7 -S: Sterling Heights, Michigan 48313 +S: Sterling Heights, Michigan 48313 +S: USA + +N: Michael A. Griffith +E: grif@cs.ucr.edu +W: http://www.cs.ucr.edu/~grif +D: Loopback speedup, qlogic scsi hacking, VT_LOCKSWITCH +S: Department of Computer Science +S: University of California, Riverside +S: Riverside, California 92521-0304 S: USA N: Grant Guenther @@ -561,11 +557,9 @@ S: Germany N: Richard Henderson -E: rth@tamu.edu +E: richard@gnu.ai.mit.edu +E: rth@cygnus.com D: Alpha/ELF, gcc, binutils, and glibc -S: 304 E. North Ave. -S: Bryan, Texas 77801-3431 -S: USA N: Sebastian Hetze E: she@lunetix.de @@ -674,6 +668,7 @@ S: USA N: Bernhard Kaindl +E: bkaindl@netway.at E: edv@bartelt.via.at D: Author of a menu based configuration tool, kmenu, which D: is the predecessor of 'make menuconfig' and 'make xconfig'. @@ -713,7 +708,7 @@ S: USA N: Alain L. Knaff -E: Alain.Knaff@imag.fr +E: Alain.Knaff@poboxes.com D: floppy driver S: 19, rue Jean l'Aveugle S: L-1148 Luxembourg-City @@ -793,7 +788,7 @@ D: Promised to send money if I would put his name in the source tree. S: PO Box 371 S: North Little Rock, Arkansas 72115 -S: US +S: USA N: Martin von Loewis E: loewis@informatik.hu-berlin.de @@ -812,7 +807,7 @@ E: imp@village.org D: Linux/MIPS Deskstation support, Provided OI/OB for Linux S: 8786 Niwot Rd -S: Niwot, CO 80503 +S: Niwot, Colorado 80503 S: USA N: H.J. Lu @@ -842,6 +837,14 @@ D: SLS distribution D: Initial implementation of VC's, pty's and select() +N: Pat Mackinlay +E: pat@it.com.au +D: 8 bit XT hard disk driver +D: Miscellaneous ST0x, TMC-8xx and other SCSI hacking +S: 25 McMillan Street +S: Victoria Park 6100 +S: Australia + N: James B. MacLean E: macleajb@ednet.ns.ca W: http://www.ednet.ns.ca/~macleajb/dosemu.html @@ -851,14 +854,6 @@ S: Halifax, Nova Scotia S: Canada B3J 3C8 -N: Pat Mackinlay -E: pat@it.com.au -D: 8 bit XT hard disk driver -D: Miscellaneous ST0x, TMC-8xx and other SCSI hacking -S: 25 McMillan Street -S: Victoria Park 6100 -S: Australia - N: Martin Mares E: mj@k332.feld.cvut.cz W: http://atrey.karlin.mff.cuni.cz/~mj/ @@ -872,6 +867,9 @@ N: John A. Martin E: jam@acm.org +W: http://linux.wauug.org/~jam/ +P: 1024/04456D53 9D A3 6C 6B 88 80 8A 61 D7 06 22 4F 95 40 CE D2 +P: 1024/3B986635 5A61 7EE6 9E20 51FB 59FB 2DA5 3E18 DD55 3B98 6635 D: FSSTND contributor D: Credit file compilator @@ -890,7 +888,7 @@ D: DLCI/FRAD drivers for Sangoma SDLAs S: Innovative Logic Corp S: P.O. Box 1068 -S: Laurel, MD 20732 +S: Laurel, Maryland 20732 S: USA N: Bradley McLean @@ -909,12 +907,13 @@ S: Germany N: Michael Meskes -E: meskes@informatik.rwth-aachen.de +E: meskes@topsystem.de +P: 1024/04B6E8F5 6C 77 33 CA CC D6 22 03 AB AB 15 A3 AE AD 39 7D D: Kernel hacker. Software watchdog daemon. D: Maintainer of several Debian packages -S: Lehrstuhl fuer angewandte Mathematik insb. Informatik -S: RWTH-Aachen -S: D-52056 Aachen +S: topsystem Systemhaus GmbH +S: Europark A2, Adenauerstr. 20 +S: D-52146 Wuerselen S: Germany N: Nigel Metheringham @@ -923,14 +922,11 @@ D: IP Masquerading work and minor fixes S: Planet Online S: The White House, Melbourne Street, LEEDS -S: LS2 7PS, UK +S: LS2 7PS, United Kingdom N: Craig Metz -E: cmetz@tjhsst.edu +E: cmetz@inner.net D: Some of PAS 16 mixer & PCM support -S: 12305 Country Ridge Lane -S: Fairfax, Virginia 22033 -S: USA N: William (Bill) Metzenthen E: billm@suburbia.net @@ -959,8 +955,9 @@ S: USA N: Rick Miller -E: rick@digalogsys.com -D: Original Linux Device Registrar (Major/minor numbers), au-play, bwBASIC +E: rdmiller@execpc.com +D: Original Linux Device Registrar (Major/minor numbers) +D: au-play, bwBASIC S: S78 W16203 Woods Road S: Muskego, Wisconsin 53150 S: USA @@ -993,7 +990,7 @@ E: davidm@azstarnet.com D: Linux/Alpha S: 2552 E. Copper Street -S: Tucson, AZ 85716-2406 +S: Tucson, Arizona 85716-2406 S: USA N: Ian A. Murdock @@ -1011,9 +1008,9 @@ S: Finland N: Jonathan Naylor -E: jsn@cs.nott.ac.uk +E: g4klx@g4klx.demon.co.uk E: g4klx@amsat.org -E: G4KLX@GB7DAD (Packet Radio) +W: http://zone.pspt.fi/~jsn/ D: AX.25 and NET/ROM protocol suites S: 24 Castle View Drive S: Cromford @@ -1055,7 +1052,7 @@ D: IPX development and support N: Avery Pennarun -E: apenwarr@foxnet.net +E: apenwarr@bond.net D: ARCnet driver D: "make xconfig" improvements D: Various minor hacking @@ -1125,17 +1122,16 @@ S: Germany N: Joerg Reuter -E: jreuter@poboxes.com +E: jreuter@lykos.oche.de E: dl1bke@db0pra.ampr.org (amateur radio) -W: http://www.rat.de/jr D: Z8530 SCC driver and DAMA Slave for AX.25 N: William E. Roadcap -E: roadcapw@titus.org +E: roadcapw@cfw.com W: http://www.cfw.com/~roadcapw D: Author of ncurses based configuration tool, Menuconfig. S: 1407 Broad Street -S: Waynesboro, Virginia 22980 +S: Waynesboro, Virginia 22980 S: USA N: Florian La Roche @@ -1167,6 +1163,7 @@ N: Thomas Sailer E: sailer@ife.ee.ethz.ch +E: HB9JNX@HB9W.CHE.EU (packet radio) D: Baycom radio modem driver S: Weinbergstrasse 76 S: 8408 Winterthur @@ -1222,7 +1219,7 @@ D: SCSI debugging D: Maintainer of the Debian Kernel packages S: 14355 SW Allen Blvd., Suite #140 -S: Beaverton, OR 97008 +S: Beaverton, Oregon 97008 S: USA N: Mike Shaver @@ -1287,7 +1284,7 @@ E: leo@netlabs.net W: http://www.netlabs.net/hp/leo/ D: Optics Storage 8000AT cdrom driver -S: Cliffwood, NJ 07721 +S: Cliffwood, New Jersey 07721 S: USA N: Henrik Storner @@ -1329,13 +1326,13 @@ S: Spain N: Linus Torvalds -E: Linus.Torvalds@Helsinki.FI +E: torvalds@transmeta.com W: http://www.cs.helsinki.fi/~torvalds/ P: 1024/A86B35C5 96 54 50 29 EC 11 44 7A BE 67 3C 24 03 13 62 C8 -D: General kernel hacker -S: Kalevankatu 55 B 37 -S: 00180 Helsinki -S: Finland +D: Original kernel hacker +S: 3665 Benton Street #36 +S: Santa Clara, California 95051 +S: USA N: Jeff Tranter E: Jeff_Tranter@Mitel.COM @@ -1355,10 +1352,11 @@ S: 2615 Australia N: Winfried Trümper -E: truemper@MI.Uni-Koeln.DE +E: winni@xpilot.org +W: http://www.shop.de/~winni/ D: German HOWTO, Enhanced German HOWTO, Crash-Kurs Linux (German) -D: 1- or 5-days tutorials on Linux twice a year (free of charge) -D: Linux-Workshop Köln (aka LUUG cologne, germany) +D: Day and week tutorials on Linux twice a year (free of charge) +D: Linux-Workshop Köln (aka LUUG Cologne, Germany) S: Tacitusstr. 6 S: D-50968 Köln @@ -1489,7 +1487,7 @@ S: Oncology Research Division Computing Facility S: Roger Maris Cancer Center S: 820 4th St. N. -S: Fargo, North Dakota 58122 +S: Fargo, North Dakota 58122 S: USA N: Hans-Joachim Widmaier @@ -1530,7 +1528,7 @@ S: Finland N: Roger E. Wolff -E: R.E.Wolff@BitWizard.nl +E: wolff@dutecai.et.tudelft.nl D: Written kmalloc/kfree D: Written Specialix IO8+ driver S: Oosterstraat 23 diff -u --recursive --new-file v9/linux/Documentation/networking/alias.txt linux/Documentation/networking/alias.txt --- v9/linux/Documentation/networking/alias.txt Tue Aug 12 11:17:41 1997 +++ linux/Documentation/networking/alias.txt Wed Sep 17 12:00:48 1997 @@ -6,6 +6,7 @@ (specific IP) support. From version 0.50, dynamic configuration of max alias per device and tx/rx stats for aliases added. + Also fixed inter-alias routing and arping problems. Features -------- @@ -35,9 +36,38 @@ # modprobe ip_alias.o Also, dynamic loading is supported (kerneld). - You should have the following line in /etc/conf.modules: + You should have the following line in /etc/conf.modules (not needed + for newer modutils): alias net_alias-2 ip_alias + Module options + -------------- + From 0.5x ip_alias module supports a new option ("no_sel" symbol). + If no_sel is set (default is 0), alias association (device selection) with + foreign addresses will be disabled. + + You will get: + - Faster operation by avoiding completely routing lookups. + Due to the "logical nature" of aliasing, netdevice SELection can only be + done based on info from network layer. When packet dst address isn't + one of my addresses, I query the routing table to see which netdevice + would be selected for packet _source_ address. This option avoids + doing so, and you must consider using it if you *only* have same-net + aliases (common usage). + + You will loose: + - Inter-alias routing + - Proxyarp over aliases + + To activate: + # insmod ip_alias.o no_sel=1 + or + # modprobe ip_alias.o no_sel=1 + or + add the following line to /etc/conf.modules: + options ip_alias no_sel=1 + + o Alias creation. Alias creation is done by 'magic' iface naming: eg. to create a 200.1.1.1 alias for eth0 ... @@ -81,9 +111,9 @@ device family address eth0:0 2 200.1.1.1 -o PROCfs dynamic configuration +o PROCfs dynamic configuration (from v0.50) You can now change the max aliases per device limit via - /proc/sys/net/core/net_alias_max entry + /proc/sys/net/core/net_alias_max entry (default=256) # cat /proc/sys/net/core/net_alias_max 256 # echo 1000 > /proc/sys/net/core/net_alias_max @@ -111,9 +141,9 @@ Fake rx/tx stats are accounted: - TX When the packet is ``switched'' from logical alias device to - physical device, tx counter gets incr. + physical device, tx counter gets incremented. - RX - When an incoming packet's address equals alias device's addr it + When an incoming packet's address equals alias network device's addr it gets ``switched'' from physical to logical device, rx counter gets incr. @@ -122,7 +152,23 @@ will NOT pass down via alias device (so, no tx++ will occur). Also NOTE that currently ifconfig does not handle the ``:'' of alias devices - names, a little patch (attached) solves the problem. + names, a little patch solves the problem: +--- ifconfig.c.dist Tue Apr 4 17:58:32 1995 ++++ ifconfig.c Fri Oct 25 13:11:23 1996 +@@ -243,7 +243,12 @@ + bp++; + if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':') + { +- bp=strchr(bp,':'); ++ /* ++ * start bp at ifname end to prevent ':' ambiguity ++ * with alias devices (eg. eth0:0) ++ * ++ */ ++ bp+=strlen(ifname); + bp++; + sscanf(bp,"%d %d %d %d %d %d %d %d %d %d %d", + &ife->stats.rx_packets, Relationship with main device ----------------------------- @@ -138,7 +184,12 @@ Please e-mail me: Juan Jose Ciarlante or - +Acknowledments +-------------- +Special thanks to Claudia for all her love an patience. +Also thanks to Antonio Trevi~o great human being +and un*x guru. + ; local variables: ; mode: indented-text ; mode: auto-fill diff -u --recursive --new-file v9/linux/Documentation/networking/ip_dynaddr.txt linux/Documentation/networking/ip_dynaddr.txt --- v9/linux/Documentation/networking/ip_dynaddr.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/networking/ip_dynaddr.txt Wed Sep 17 12:00:48 1997 @@ -0,0 +1,29 @@ +IP dynamic address hack-port v0.03 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This stuff allows diald ONESHOT connections to get established by +dynamically changing packet source address (and socket's if local procs). +It is implemented for TCP diald-box connections(1) and IP_MASQuerading(2). + +If enabled[*] and forwarding interface has changed: + 1) Socket (and packet) source address is rewritten ON RETRANSMISSIONS + while in SYN_SENT state (diald-box processes). + 2) Out-bounded MASQueraded source address changes ON OUTPUT (when + internal host does retransmission) until a packet from outside is + received by the tunnel. + +This is specially helpful for auto dialup links (diald), where the +``actual'' outgoing address is unknown at the moment the link is +going up. So, the *same* (local AND masqueraded) connections requests that +bring the link up will be able to get established. + +[*] At boot, by default no address rewriting is attempted. + To enable: + # echo 1 > /proc/sys/net/ipv4/ip_dynaddr + To enable verbose mode: + # echo 2 > /proc/sys/net/ipv4/ip_dynaddr + To disable (default) + # echo 0 > /proc/sys/net/ipv4/ip_dynaddr + +Enjoy! + +-- Juanjo diff -u --recursive --new-file v9/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v9/linux/arch/i386/defconfig Fri Sep 5 20:43:58 1997 +++ linux/arch/i386/defconfig Mon Sep 22 13:44:01 1997 @@ -150,7 +150,6 @@ # CONFIG_HPFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_AUTOFS_FS is not set # # Character devices diff -u --recursive --new-file v9/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- v9/linux/arch/i386/kernel/entry.S Mon Aug 11 13:42:11 1997 +++ linux/arch/i386/kernel/entry.S Tue Sep 16 14:42:45 1997 @@ -259,7 +259,6 @@ iret #endif - ENTRY(lcall7) pushfl # We get a different stack layout with call gates, pushl %eax # which has to be cleaned up later.. diff -u --recursive --new-file v9/linux/arch/i386/kernel/ksyms.c linux/arch/i386/kernel/ksyms.c --- v9/linux/arch/i386/kernel/ksyms.c Tue Apr 8 08:47:45 1997 +++ linux/arch/i386/kernel/ksyms.c Tue Sep 16 14:40:50 1997 @@ -2,6 +2,7 @@ #include #include #include +#include #include @@ -13,6 +14,7 @@ /* platform dependent support */ X(dump_thread), X(dump_fpu), + XNOVERS(__do_delay), XNOVERS(down_failed), XNOVERS(down_failed_interruptible), XNOVERS(up_wakeup), diff -u --recursive --new-file v9/linux/arch/i386/lib/Makefile linux/arch/i386/lib/Makefile --- v9/linux/arch/i386/lib/Makefile Wed Sep 11 07:57:13 1996 +++ linux/arch/i386/lib/Makefile Tue Sep 16 14:41:18 1997 @@ -11,6 +11,6 @@ endif L_TARGET = lib.a -L_OBJS = checksum.o semaphore.o +L_OBJS = checksum.o semaphore.o delay.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v9/linux/arch/i386/lib/delay.S linux/arch/i386/lib/delay.S --- v9/linux/arch/i386/lib/delay.S Wed Dec 31 16:00:00 1969 +++ linux/arch/i386/lib/delay.S Tue Sep 16 14:55:07 1997 @@ -0,0 +1,14 @@ +#include + +/* + * BogoMips loop. Non-inlined because various x86's have so wildly + * varying results depending on the exact alignment. + */ + +ENTRY(__do_delay) +1: decl %eax + jns 1b + ret + + + diff -u --recursive --new-file v9/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v9/linux/drivers/char/mem.c Fri Sep 20 07:00:34 1996 +++ linux/drivers/char/mem.c Tue Sep 9 16:06:48 1997 @@ -194,12 +194,6 @@ return 0; } -static int read_full(struct inode * node, struct file * file, char * buf,int count) -{ - file->f_pos += count; - return count; -} - static int write_full(struct inode * inode, struct file * file, const char * buf, int count) { return -ENOSPC; @@ -242,7 +236,9 @@ #define write_kmem write_mem #define mmap_kmem mmap_mem #define zero_lseek null_lseek +#define full_lseek null_lseek #define write_zero write_null +#define read_full read_null static struct file_operations ram_fops = { memory_lseek, @@ -322,7 +318,7 @@ }; static struct file_operations full_fops = { - memory_lseek, + full_lseek, read_full, write_full, NULL, /* full_readdir */ diff -u --recursive --new-file v9/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v9/linux/drivers/char/tty_io.c Wed Aug 13 09:56:45 1997 +++ linux/drivers/char/tty_io.c Tue Sep 16 09:36:49 1997 @@ -1474,11 +1474,10 @@ if (on) { if (!waitqueue_active(&tty->read_wait)) tty->minimum_to_wake = 1; - if (filp->f_owner == 0) { - if (tty->pgrp) - filp->f_owner = -tty->pgrp; - else - filp->f_owner = current->pid; + if (filp->f_owner.pid == 0) { + filp->f_owner.pid = (-tty->pgrp) ? : current->pid; + filp->f_owner.uid = current->uid; + filp->f_owner.euid = current->euid; } } else { if (!tty->fasync && !waitqueue_active(&tty->read_wait)) diff -u --recursive --new-file v9/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c --- v9/linux/drivers/net/3c59x.c Fri Sep 5 11:20:20 1997 +++ linux/drivers/net/3c59x.c Mon Sep 15 09:45:39 1997 @@ -1,4 +1,4 @@ -/* EtherLink.c: A 3Com EtherLink PCI III/XL ethernet driver for linux. */ +/* EtherLinkXL.c: A 3Com EtherLink PCI III/XL ethernet driver for linux. */ /* Written 1996-1997 by Donald Becker. @@ -15,14 +15,16 @@ */ static char *version = -"3c59x.c:v0.43 9/2/97 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n"; +"3c59x.c:v0.44 9/9/97 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n"; -/* "Knobs" that turn on special features. */ +/* "Knobs" that adjust features and parameters. */ /* Set the copy breakpoint for the copy-only-tiny-frames scheme. Setting to > 1512 effectively disables this feature. */ static const rx_copybreak = 200; /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */ static const mtu = 1500; +/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ +static const max_interrupt_work = 12; /* Enable the automatic media selection code -- usually set. */ #define AUTOMEDIA 1 @@ -135,14 +137,17 @@ #endif #ifdef VORTEX_DEBUG -int vortex_debug = VORTEX_DEBUG; +static int vortex_debug = VORTEX_DEBUG; #else -int vortex_debug = 1; +static int vortex_debug = 1; #endif +/* Set iff a MII transceiver on any interface requires mdio preamble. */ +static char mii_preamble_required = 0; + /* Caution! These entries must be consistent, with the EISA ones last. */ -static int product_ids[] = {0x5900, 0x5950, 0x5951, 0x5952, 0x9000, 0x9001, - 0x9050, 0x9051, 0, 0}; +static const int product_ids[] = { + 0x5900, 0x5950, 0x5951, 0x5952, 0x9000, 0x9001, 0x9050, 0x9051, 0, 0}; static const char *product_names[] = { "3c590 Vortex 10Mbps", "3c595 Vortex 100baseTX", @@ -316,7 +321,7 @@ }; enum Window4 { /* Window 4: Xcvr/media bits. */ - Wn4_NetDiag = 6, Wn4_PhysicalMgmt=8, Wn4_Media = 10, + Wn4_FIFODiag = 4, Wn4_NetDiag = 6, Wn4_PhysicalMgmt=8, Wn4_Media = 10, }; enum Win4_Media_bits { Media_SQE = 0x0008, /* Enable SQE error counting for AUI. */ @@ -423,7 +428,11 @@ int options, int card_idx); static int vortex_probe1(struct device *dev); static int vortex_open(struct device *dev); +static void mdio_sync(int ioaddr, int bits); static int mdio_read(int ioaddr, int phy_id, int location); +#ifdef HAVE_PRIVATE_IOCTL +static void mdio_write(int ioaddr, int phy_id, int location, int value); +#endif static void vortex_timer(unsigned long arg); static int vortex_start_xmit(struct sk_buff *skb, struct device *dev); static int boomerang_start_xmit(struct sk_buff *skb, struct device *dev); @@ -434,6 +443,9 @@ static void update_stats(int addr, struct device *dev); static struct enet_statistics *vortex_get_stats(struct device *dev); static void set_rx_mode(struct device *dev); +#ifdef HAVE_PRIVATE_IOCTL +static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd); +#endif #ifndef NEW_MULTICAST static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); #endif @@ -758,11 +770,16 @@ int phy, phy_idx = 0; EL3WINDOW(4); for (phy = 0; phy < 32 && phy_idx < sizeof(vp->phys); phy++) { - int mii_status = mdio_read(ioaddr, phy, 0); - if (mii_status != 0xffff && mii_status != 0x0000) { + int mii_status; + mdio_sync(ioaddr, 32); + mii_status = mdio_read(ioaddr, phy, 0); + if (mii_status != 0xffff) { vp->phys[phy_idx++] = phy; printk("%s: MII transceiver found at address %d.\n", dev->name, phy); + mdio_sync(ioaddr, 32); + if ((mdio_read(ioaddr, phy, 1) & 0x0040) == 0) + mii_preamble_required = 1; } } if (phy_idx == 0) { @@ -790,6 +807,9 @@ dev->hard_start_xmit = &vortex_start_xmit; dev->stop = &vortex_close; dev->get_stats = &vortex_get_stats; +#ifdef HAVE_PRIVATE_IOCTL + dev->do_ioctl = &vortex_ioctl; +#endif #ifdef NEW_MULTICAST dev->set_multicast_list = &set_rx_mode; #else @@ -801,7 +821,7 @@ /* Read and write the MII registers using software-generated serial MDIO protocol. The maxium data clock rate is 2.5 Mhz. */ -#define mdio_delay(microsecs) udelay(microsecs) +#define mdio_delay() udelay(1) #define MDIO_SHIFT_CLK 0x01 #define MDIO_DIR_WRITE 0x04 @@ -810,41 +830,73 @@ #define MDIO_DATA_READ 0x02 #define MDIO_ENB_IN 0x00 +static void mdio_sync(int ioaddr, int bits) +{ + int mdio_addr = ioaddr + Wn4_PhysicalMgmt; + + /* Establish sync by sending at least 32 logic ones. */ + while (-- bits >= 0) { + outw(MDIO_DATA_WRITE1, mdio_addr); + mdio_delay(); + outw(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } +} static int mdio_read(int ioaddr, int phy_id, int location) { int i; int read_cmd = (0xf6 << 10) | (phy_id << 5) | location; - unsigned short retval = 0; + unsigned int retval = 0; int mdio_addr = ioaddr + Wn4_PhysicalMgmt; + if (mii_preamble_required) + mdio_sync(ioaddr, 32); + /* Shift the read command bits out. */ - for (i = 17; i >= 0; i--) { + for (i = 14; i >= 0; i--) { int dataval = (read_cmd&(1< 0; i--) { - outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(1); - retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0); + /* Read the two transition, 16 data, and wire-idle bits. */ + for (i = 19; i > 0; i--) { outw(MDIO_ENB_IN, mdio_addr); - mdio_delay(1); - } - /* Clear out extra bits. Needed? */ - for (i = 16; i > 0; i--) { + mdio_delay(); + retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0); outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(1); + mdio_delay(); + } + return retval>>1 & 0xffff; +} + +static void mdio_write(int ioaddr, int phy_id, int location, int value) +{ + int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value; + int mdio_addr = ioaddr + Wn4_PhysicalMgmt; + int i; + + if (mii_preamble_required) + mdio_sync(ioaddr, 32); + + /* Shift the command bits out. */ + for (i = 31; i >= 0; i--) { + int dataval = (write_cmd&(1<= 0; i--) { outw(MDIO_ENB_IN, mdio_addr); - mdio_delay(1); + mdio_delay(); + outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); } - return retval; + + return; } @@ -888,19 +940,22 @@ outl(config.i, ioaddr + Wn3_Config); if (dev->if_port == XCVR_MII) { - int mii_reg1, mii_reg25; + int mii_reg1, mii_reg5; /* We cheat here: we know that we are using the 83840 transceiver which summarizes the FD status in an extended register. */ EL3WINDOW(4); /* Read BMSR (reg1) only to clear old status. */ mii_reg1 = mdio_read(ioaddr, vp->phys[0], 1); - mii_reg25 = mdio_read(ioaddr, vp->phys[0], 0x19); + mii_reg5 = mdio_read(ioaddr, vp->phys[0], 5); + if (mii_reg5 == 0xffff || mii_reg5 == 0x0000) + ; /* No MII device or no link partner report */ + else if ((mii_reg5 & 0x0100) != 0 /* 100baseTx-FD */ + || (mii_reg5 & 0x00C0) == 0x0040) /* 10T-FD, but not 100-HD */ + vp->full_duplex = 1; if (vortex_debug > 1) - printk("%s: MII #%d status %4.4x, duplex report %4.4x," + printk("%s: MII #%d status %4.4x, link partner capability %4.4x," " setting %s-duplex.\n", dev->name, vp->phys[0], - mii_reg1, mii_reg25, mii_reg25 & 0x0080 ? "full" : "half"); - if (mii_reg25 & 0x0080) - vp->full_duplex = 1; + mii_reg1, mii_reg5, vp->full_duplex ? "full" : "half"); EL3WINDOW(3); } @@ -1030,6 +1085,7 @@ outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, ioaddr + EL3_CMD); outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull + | AdapterFailure | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete, ioaddr + EL3_CMD); @@ -1071,9 +1127,11 @@ case XCVR_MII: { int mii_reg1 = mdio_read(ioaddr, vp->phys[0], 1); + int mii_reg5 = mdio_read(ioaddr, vp->phys[0], 5); if (vortex_debug > 1) - printk("%s: MII #%d status register is %4.4x.\n", - dev->name, vp->phys[0], mii_reg1); + printk("%s: MII #%d status register is %4.4x, " + "link partner capability %4.4x.\n", + dev->name, vp->phys[0], mii_reg1, mii_reg5); if (mii_reg1 & 0x0004) ok = 1; break; @@ -1134,19 +1192,28 @@ inw(ioaddr + EL3_STATUS)); /* Slight code bloat to be user friendly. */ if ((inb(ioaddr + TxStatus) & 0x88) == 0x88) - printk("%s: Transmitter encountered 16 collisions -- network" - " network cable problem?\n", dev->name); + printk("%s: Transmitter encountered 16 collisions --" + " network cable problem?\n", dev->name); + if (inw(ioaddr + EL3_STATUS) & IntLatch) { + printk("%s: Interrupt posted but not handled --" + " IRQ blocked by another device?\n", dev->name); + /* Bad idea here.. but we might as well handle a few events. */ + vortex_interrupt IRQ(dev->irq, dev, 0); + } #ifndef final_version - printk(" Flags; bus-master %d, full %d; dirty %d current %d.\n", - vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx, vp->cur_tx); - printk(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr), - &vp->tx_ring[0]); - for (i = 0; i < TX_RING_SIZE; i++) { - printk(" %d: %p length %8.8x status %8.8x\n", i, - &vp->tx_ring[i], - vp->tx_ring[i].length, - vp->tx_ring[i].status); + if (vp->full_bus_master_tx) { + printk(" Flags; bus-master %d, full %d; dirty %d current %d.\n", + vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx, vp->cur_tx); + printk(" Transmit list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr), + &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]); + for (i = 0; i < TX_RING_SIZE; i++) { + printk(" %d: @%p length %8.8x status %8.8x\n", i, + &vp->tx_ring[i], + vp->tx_ring[i].length, + vp->tx_ring[i].status); + } } +#ifdef notdef if (vp->full_bus_master_rx) { printk(" Switching to non-bus-master receives.\n"); outw(SetStatusEnb | AdapterFailure|IntReq|StatsFull | @@ -1154,12 +1221,13 @@ RxComplete | (vp->bus_master ? DMADone : 0), ioaddr + EL3_CMD); } -#endif /* Issue TX_RESET and TX_START commands. */ outw(TxReset, ioaddr + EL3_CMD); for (i = 20; i >= 0 ; i--) if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) break; +#endif +#endif if (vp->full_bus_master_tx) { /* Change 6/25/97 Michael Sievers sieversm@mail.desy.de The card has been resetted, but the Tx Ring is still full. @@ -1170,19 +1238,23 @@ unsigned int dirty_tx = vp->dirty_tx; + if (vortex_debug > 0) + printk("%s: Freeing Tx ring entries:", dev->name); while (vp->cur_tx - dirty_tx > 0) { int entry = dirty_tx % TX_RING_SIZE; if (inl(ioaddr + DownListPtr) == virt_to_bus(&vp->tx_ring[entry])) break; /* It still hasn't been processed. */ if (vp->tx_skbuff[entry]) { - if (vortex_debug > 0) - printk("%s: Freeing Tx ring entry %d\n",dev->name,entry); - dev_kfree_skb(vp->tx_skbuff[entry], FREE_WRITE); - vp->tx_skbuff[entry] = 0; + if (vortex_debug > 0) + printk(" %d\n", entry); + dev_kfree_skb(vp->tx_skbuff[entry], FREE_WRITE); + vp->tx_skbuff[entry] = 0; + vp->stats.tx_dropped++; } + if (vortex_debug > 0) + printk(".\n"); vp->stats.tx_errors++; - vp->stats.tx_dropped++; dirty_tx++; } vp->dirty_tx = dirty_tx; @@ -1323,10 +1395,10 @@ printk("%s: Trying to send a packet, Tx index %d.\n", dev->name, vp->cur_tx); if (vp->tx_full) { - if (vortex_debug >0) - printk("%s: Tx Ring full, refusing to send buffer.\n", - dev->name); - return 1; + if (vortex_debug >0) + printk("%s: Tx Ring full, refusing to send buffer.\n", + dev->name); + return 1; } /* end change 06/25/97 M. Sievers */ vp->tx_skbuff[entry] = skb; @@ -1339,7 +1411,7 @@ cli(); outw(DownStall, ioaddr + EL3_CMD); /* Wait for the stall to complete. */ - for (i = 20; i >= 0 ; i--) + for (i = 60; i >= 0 ; i--) if ( (inw(ioaddr + EL3_STATUS) & CmdInProgress) == 0) break; prev_entry->next = virt_to_bus(&vp->tx_ring[entry]); @@ -1374,7 +1446,7 @@ struct vortex_private *lp; int ioaddr, status; int latency; - int i = 0; + int i = max_interrupt_work; if (dev->interrupt) printk("%s: Re-entering the interrupt handler.\n", dev->name); @@ -1389,17 +1461,20 @@ if (vortex_debug > 4) printk("%s: interrupt, status %4.4x, timer %d.\n", dev->name, status, latency); - if ((status & 0xE000) != 0xE000) { +#ifdef notdef + /* This code guard against bogus hangs, but fails with shared IRQs. */ + if ((status & ~0xE000) == 0x0000) { static int donedidthis=0; /* Some interrupt controllers store a bogus interrupt from boot-time. Ignore a single early interrupt, but don't hang the machine for other interrupt problems. */ - if (donedidthis++ > 1) { + if (donedidthis++ > 100) { printk("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n", dev->name, status, dev->start); FREE_IRQ(dev->irq, dev); } } +#endif do { if (vortex_debug > 5) @@ -1416,6 +1491,13 @@ dev->tbusy = 0; mark_bh(NET_BH); } + if (status & TxComplete) { /* Really "TxError" for us. */ + /* Presumably a tx-timeout. We must merely re-enable. */ + if (vortex_debug > 0) + printk("%s: Host error, Tx status register %2.2x.\n", + dev->name, inb(TxStatus)); + outw(TxEnable, ioaddr + EL3_CMD); + } if (status & DownComplete) { unsigned int dirty_tx = lp->dirty_tx; @@ -1431,13 +1513,13 @@ /* lp->stats.tx_packets++; Counted below. */ dirty_tx++; } + lp->dirty_tx = dirty_tx; outw(AckIntr | DownComplete, ioaddr + EL3_CMD); - if (lp->tx_full) { + if (lp->tx_full && (lp->cur_tx - dirty_tx <= TX_RING_SIZE - 1)) { lp->tx_full= 0; dev->tbusy = 0; mark_bh(NET_BH); } - lp->dirty_tx = dirty_tx; } #ifdef VORTEX_BUS_MASTER if (status & DMADone) { @@ -1476,22 +1558,38 @@ printk(" %2.2x", inb(ioaddr+reg)); } EL3WINDOW(7); - outw(SetIntrEnb | TxAvailable | RxComplete + outw(SetIntrEnb | TxAvailable | RxComplete | AdapterFailure | UpComplete | DownComplete, ioaddr + EL3_CMD); DoneDidThat++; } } if (status & AdapterFailure) { - /* Adapter failure requires Rx reset and reinit. */ - outw(RxReset, ioaddr + EL3_CMD); - /* Set the Rx filter to the current state. */ - set_rx_mode(dev); - outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */ - outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); + u16 fifo_diag; + EL3WINDOW(4); + fifo_diag = inw(ioaddr + Wn4_FIFODiag); + if (vortex_debug > 0) + printk("%s: Host error, FIFO diagnostic register %4.4x.\n", + dev->name, fifo_diag); + /* Adapter failure requires Tx/Rx reset and reinit. */ + if (fifo_diag & 0x0400) { + int j; + outw(TxReset, ioaddr + EL3_CMD); + for (j = 20; j >= 0 ; j--) + if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) + break; + outw(TxEnable, ioaddr + EL3_CMD); + } + if (fifo_diag & 0x2000) { + outw(RxReset, ioaddr + EL3_CMD); + /* Set the Rx filter to the current state. */ + set_rx_mode(dev); + outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */ + outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); + } } } - if (++i > 10) { + if (--i < 0) { printk("%s: Infinite loop in interrupt, status %4.4x. " "Disabling functions (%4.4x).\n", dev->name, status, SetStatusEnb | ((~status) & 0x7FE)); @@ -1595,7 +1693,7 @@ while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) { if (rx_status & RxDError) { /* Error, update stats. */ unsigned char rx_error = rx_status >> 16; - if (vortex_debug > 4) + if (vortex_debug > 2) printk(" Rx error: status %2.2x.\n", rx_error); vp->stats.rx_errors++; if (rx_error & 0x01) vp->stats.rx_over_errors++; @@ -1788,6 +1886,37 @@ EL3WINDOW(7); return; } + +#ifdef HAVE_PRIVATE_IOCTL +static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + int ioaddr = dev->base_addr; + u16 *data = (u16 *)&rq->ifr_data; + int phy = vp->phys[0] & 0x1f; + + if (vortex_debug > 2) + printk("%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n", + dev->name, rq->ifr_ifrn.ifrn_name, cmd, + data[0], data[1], data[2], data[3]); + + switch(cmd) { + case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + data[0] = phy; + case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + EL3WINDOW(4); + data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f); + return 0; + case SIOCDEVPRIVATE+2: /* Write the specified MII register */ + if (!suser()) + return -EPERM; + mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]); + return 0; + default: + return -EOPNOTSUPP; + } +} +#endif /* HAVE_PRIVATE_IOCTL */ /* This new version of set_rx_mode() supports v1.4 kernels. The Vortex chip has no documented multicast filter, so the only diff -u --recursive --new-file v9/linux/drivers/net/tulip.c linux/drivers/net/tulip.c --- v9/linux/drivers/net/tulip.c Fri Sep 5 11:20:20 1997 +++ linux/drivers/net/tulip.c Sun Sep 7 12:28:36 1997 @@ -1444,7 +1444,7 @@ } if (tulip_debug > 0) /* Gurppp, should be >1 */ printk(KERN_INFO "%s: Setting %s-duplex based on MII" - " Xcvr #%d parter capability of %4.4x.\n", + " Xcvr #%d partner capability of %4.4x.\n", dev->name, full_duplex ? "full" : "half", tp->phys[0], mii_reg5); } diff -u --recursive --new-file v9/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in --- v9/linux/drivers/scsi/Config.in Sat Aug 16 11:21:04 1997 +++ linux/drivers/scsi/Config.in Mon Sep 15 09:41:28 1997 @@ -42,7 +42,7 @@ dep_tristate 'EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support' CONFIG_SCSI_EATA $CONFIG_SCSI if [ "$CONFIG_SCSI_EATA" != "n" ]; then bool ' enable tagged command queueing' CONFIG_SCSI_EATA_TAGGED_QUEUE - bool ' enable linked commands' CONFIG_SCSI_EATA_LINKED_COMMANDS + bool ' enable elevator sorting' CONFIG_SCSI_EATA_LINKED_COMMANDS int ' maximum number of queued commands' CONFIG_SCSI_EATA_MAX_TAGS 16 fi dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN $CONFIG_SCSI @@ -91,7 +91,7 @@ dep_tristate 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 $CONFIG_SCSI dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F $CONFIG_SCSI if [ "$CONFIG_SCSI_U14_34F" != "n" ]; then - bool ' enable linked commands' CONFIG_SCSI_U14_34F_LINKED_COMMANDS + bool ' enable elevator sorting' CONFIG_SCSI_U14_34F_LINKED_COMMANDS int ' maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8 fi dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR $CONFIG_SCSI diff -u --recursive --new-file v9/linux/drivers/scsi/aic7xxx/aic7xxx.reg linux/drivers/scsi/aic7xxx/aic7xxx.reg --- v9/linux/drivers/scsi/aic7xxx/aic7xxx.reg Wed Aug 13 09:53:45 1997 +++ linux/drivers/scsi/aic7xxx/aic7xxx.reg Mon Sep 22 14:53:10 1997 @@ -1079,10 +1079,25 @@ CUR_SCBID { size 1 } + ARG_1 { + size 1 + mask SEND_MSG 0x80 + mask SEND_SENSE 0x40 + mask SEND_REJ 0x20 + alias RETURN_1 + } /* * Running count of commands placed in * the QOUTFIFO. This is cleared by the * kernel driver every FIFODEPTH commands. + * + * NOTE: these scratch RAM registers are *only* used on cards + * that enable SCB paging. The 2742 is unable to page. We + * won't use these on a 2742, and we can't init these registers + * in the kernel driver for 2742 cards because these locations are + * are used by the 2742 cards to control things like bus + * termination. Touching these memory locations is a no-no on all + * non-paging cards as far as we are concerned. */ CMDOUTCNT { size 1 @@ -1094,13 +1109,6 @@ FIFODEPTH { size 1 } - ARG_1 { - size 1 - mask SEND_MSG 0x80 - mask SEND_SENSE 0x40 - mask SEND_REJ 0x20 - alias RETURN_1 - } /* * These are reserved registers in the card's scratch ram. Some of * the values are specified in the AHA2742 technical reference manual @@ -1108,6 +1116,11 @@ */ SCSICONF { address 0x05a + size 1 + bit RESET_SCSI 0x40 + } + SCSICONF2 { + address 0x05b size 1 bit RESET_SCSI 0x40 } diff -u --recursive --new-file v9/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c --- v9/linux/drivers/scsi/aic7xxx.c Wed Aug 13 09:53:45 1997 +++ linux/drivers/scsi/aic7xxx.c Mon Sep 22 14:53:09 1997 @@ -871,7 +871,7 @@ long r_total; /* total reads */ long r_total512; /* 512 byte blocks read */ long r_bins[10]; /* binned reads */ - } stats[2][16][8]; /* channel, target, lun */ + } stats[16][8]; /* channel, target, lun */ #endif /* AIC7XXX_PROC_STATS */ }; @@ -968,7 +968,13 @@ * These functions are not used yet, but when we do memory mapped * IO, we'll use them then. * + * For now we leave these commented out as the x86 inline assembly causes + * compiles to barf on DEC Alphas. Besides, they aren't even used yet, so + * they constitute wasted .text space right now. ***************************************************************************/ + +/*************************************************************************** + static inline unsigned char aic_inb(struct aic7xxx_host *p, long port) { @@ -1007,6 +1013,7 @@ outsb(p->base + port, valp, size); } } + ***************************************************************************/ /*+F************************************************************************* * Function: @@ -1985,6 +1992,8 @@ aic7xxx_queue_cmd_complete(p, cmd); #ifdef AIC7XXX_PROC_STATS + if ( (cmd->cmnd[0] != TEST_UNIT_READY) && + (cmd->cmnd[0] != INQUIRY) ) { int actual; @@ -2000,7 +2009,7 @@ long *ptr; int x; - sp = &p->stats[cmd->channel & 0x01][cmd->target & 0x0F][cmd->lun & 0x07]; + sp = &p->stats[((cmd->channel << 3) | cmd->target) & 0xf][cmd->lun & 0x7]; sp->xfers++; if (cmd->request.cmd == WRITE) @@ -4062,7 +4071,7 @@ #ifndef AIC7XXX_TAGGED_QUEUEING_BY_DEVICE device->queue_depth = default_depth; #else - if (p->instance > NUMBER(aic7xxx_tag_info)) + if (p->instance >= NUMBER(aic7xxx_tag_info)) { device->queue_depth = default_depth; } @@ -5022,7 +5031,7 @@ scbq_init(&p->scb_data->free_scbs); scbq_init(&p->waiting_scbs); - for (i = 0; i <= NUMBER(p->device_status); i++) + for (i = 0; i < NUMBER(p->device_status); i++) { p->device_status[i].commands_sent = 0; p->device_status[i].flags = 0; @@ -5305,8 +5314,11 @@ */ outb(p->qcntmask, p->base + QCNTMASK); - outb(p->qfullcount, p->base + FIFODEPTH); - outb(0, p->base + CMDOUTCNT); + if (p->flags & PAGE_ENABLED) + { + outb(p->qfullcount, p->base + FIFODEPTH); + outb(0, p->base + CMDOUTCNT); + } /* * We don't have any waiting selections or disconnected SCBs. @@ -5721,7 +5733,7 @@ * a NULL entry to indicate that no prior hosts have * been found/registered for that IRQ. */ - for (i = 0; i <= NUMBER(aic7xxx_boards); i++) + for (i = 0; i < NUMBER(aic7xxx_boards); i++) { aic7xxx_boards[i] = NULL; } @@ -6887,7 +6899,7 @@ scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]); base = p->base; channel = cmd->channel ? 'B': 'A'; - tindex = (cmd->channel << 4) | cmd->target; + tindex = (cmd->channel << 3) | cmd->target; #ifdef 0 /* AIC7XXX_DEBUG_ABORT */ if (scb != NULL) @@ -7128,4 +7140,3 @@ * tab-width: 8 * End: */ - diff -u --recursive --new-file v9/linux/drivers/scsi/aic7xxx_proc.c linux/drivers/scsi/aic7xxx_proc.c --- v9/linux/drivers/scsi/aic7xxx_proc.c Wed Aug 6 21:51:02 1997 +++ linux/drivers/scsi/aic7xxx_proc.c Mon Sep 22 14:53:09 1997 @@ -21,13 +21,15 @@ * o Modified from the EATA-DMA /proc support. * o Additional support for device block statistics provided by * Matthew Jacob. + * o Correction of overflow by Heinz Mauelshagen + * o Adittional corrections by Doug Ledford * * Dean W. Gehnert, deang@teleport.com, 05/01/96 * * $Id: aic7xxx_proc.c,v 4.1 1997/06/97 08:23:42 deang Exp $ *-M*************************************************************************/ -#define BLS buffer + len + size +#define BLS (&aic7xxx_buffer[size]) #define HDRB \ " < 512 512-1K 1-2K 2-4K 4-8K 8-16K 16-32K 32-64K 64-128K >128K" @@ -62,7 +64,7 @@ proc_debug("aic7xxx_set_info(): %s\n", buffer); return (-ENOSYS); /* Currently this is a no-op */ } - + /*+F************************************************************************* * Function: * aic7xxx_proc_info @@ -71,20 +73,23 @@ * Return information to handle /proc support for the driver. *-F*************************************************************************/ int -aic7xxx_proc_info(char *buffer, char **start, off_t offset, int length, - int hostno, int inout) +aic7xxx_proc_info ( char *buffer, char **start, off_t offset, int length, + int hostno, int inout) { struct Scsi_Host *HBAptr; struct aic7xxx_host *p; - int i; - int found = FALSE; - int size = 0; - int len = 0; - off_t begin = 0; - off_t pos = 0; + static int aic7xxx_buffer_size = 0; + int found = FALSE; + static int size = 0; + unsigned char i; + static char *aic7xxx_buffer = NULL; static char *bus_names[] = { "Single", "Twin", "Wide" }; static char *chip_names[] = { "AIC-777x", "AIC-785x", "AIC-786x", "AIC-787x", "AIC-788x" }; +#ifdef AIC7XXX_PROC_STATS + struct aic7xxx_xferstats *sp; + unsigned char target, lun; +#endif HBAptr = NULL; for (i=0; i < NUMBER(aic7xxx_boards); i++) @@ -95,7 +100,7 @@ { break; } - + while ((HBAptr->hostdata != NULL) && !found && ((HBAptr = ((struct aic7xxx_host *) HBAptr->hostdata)->next) != NULL)) { @@ -104,7 +109,7 @@ found = TRUE; } } - + if (!found) { HBAptr = NULL; @@ -115,43 +120,69 @@ } } } - + if (HBAptr == NULL) { - size += sprintf(BLS, "Can't find adapter for host number %d\n", hostno); - len += size; pos = begin + len; size = 0; - goto stop_output; + size += sprintf( buffer, "Can't find adapter for host number %d\n", hostno); + if ( size > length) return size; + return length; } - + if (inout == TRUE) /* Has data been written to the file? */ { return (aic7xxx_set_info(buffer, length, HBAptr)); } - + p = (struct aic7xxx_host *) HBAptr->hostdata; + /* It takes roughly 1K of space to hold all relevant card info, not */ + /* counting any proc stats, so we start out with a 1.5k buffer size and */ + /* if proc_stats is defined, then we sweep the stats structure to see */ + /* how many drives we will be printing out for and add 384 bytes per */ + /* device with active stats. */ + + size = 1536; +#ifdef AIC7XXX_PROC_STATS + for (target=0; target<16; target++) + { + for (lun=0; lun<8; lun++) + { + if (p->stats[target][lun].xfers != 0) + size += 384; + } + } +#endif + if ( aic7xxx_buffer_size != size) { + if ( aic7xxx_buffer != NULL) + { + kfree ( aic7xxx_buffer); + aic7xxx_buffer_size = 0; + } + aic7xxx_buffer = kmalloc ( size, GFP_KERNEL); + } + if ( aic7xxx_buffer == NULL) { + size = sprintf ( buffer, "AIC7xxx - kmalloc error at line %d\n", + __LINE__); + return size; + } + aic7xxx_buffer_size = size; + + size = 0; size += sprintf(BLS, "Adaptec AIC7xxx driver version: "); size += sprintf(BLS, "%s/", rcs_version(AIC7XXX_C_VERSION)); size += sprintf(BLS, "%s", rcs_version(AIC7XXX_H_VERSION)); #if 0 size += sprintf(BLS, "%s\n", rcs_version(AIC7XXX_SEQ_VER)); #endif - if (size > 512) - printk(KERN_CRIT "aic7xxx: possible overflow at first position\n"); - len += size; pos = begin + len; size = 0; - if (pos < offset) - { - begin = pos; - len = 0; - } - size += sprintf(BLS, "\n"); size += sprintf(BLS, "Compile Options:\n"); #ifdef AIC7XXX_RESET_DELAY - size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", AIC7XXX_RESET_DELAY); + size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", + AIC7XXX_RESET_DELAY); #endif #ifdef AIC7XXX_CMDS_PER_LUN - size += sprintf(BLS, " AIC7XXX_CMDS_PER_LUN : %d\n", AIC7XXX_CMDS_PER_LUN); + size += sprintf(BLS, " AIC7XXX_CMDS_PER_LUN : %d\n", + AIC7XXX_CMDS_PER_LUN); #endif #ifdef AIC7XXX_TAGGED_QUEUEING size += sprintf(BLS, " AIC7XXX_TAGGED_QUEUEING: Enabled\n"); @@ -168,29 +199,19 @@ #else size += sprintf(BLS, " AIC7XXX_PROC_STATS : Disabled\n"); #endif - if (size > 512) - printk(KERN_CRIT "aic7xxx: possible overflow at second position\n"); - len += size; pos = begin + len; size = 0; - if (pos < offset) - { - begin = pos; - len = 0; - } - else if (pos >= offset + length) - goto stop_output; - size += sprintf(BLS, "\n"); size += sprintf(BLS, "Adapter Configuration:\n"); size += sprintf(BLS, " SCSI Adapter: %s\n", - board_names[p->chip_type]); + board_names[p->chip_type]); size += sprintf(BLS, " (%s chipset)\n", - chip_names[p->chip_class]); - size += sprintf(BLS, " Host Bus: %s\n", bus_names[p->bus_type]); + chip_names[p->chip_class]); + size += sprintf(BLS, " Host Bus: %s\n", + bus_names[p->bus_type]); size += sprintf(BLS, " Base IO: %#.4x\n", p->base); size += sprintf(BLS, " Base IO Memory: 0x%x\n", p->mbase); size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); size += sprintf(BLS, " SCBs: Used %d, HW %d, Page %d\n", - p->scb_data->numscbs, p->scb_data->maxhscbs, p->scb_data->maxscbs); + p->scb_data->numscbs, p->scb_data->maxhscbs, p->scb_data->maxscbs); size += sprintf(BLS, " Interrupts: %d", p->isr_count); if (p->chip_class == AIC_777x) { @@ -211,92 +232,56 @@ (p->flags & ULTRA_ENABLED) ? "En" : "Dis"); size += sprintf(BLS, " Target Disconnect: %sabled\n", p->discenable ? "En" : "Dis"); - if (size > 512) - printk(KERN_CRIT "aic7xxx: possible overflow at third position\n"); - len += size; pos = begin + len; size = 0; - if (pos < offset) - { - begin = pos; - len = 0; - } - else if (pos >= offset + length) - goto stop_output; - + #ifdef AIC7XXX_PROC_STATS + size += sprintf(BLS, "\n"); + size += sprintf(BLS, "Statistics:\n"); + for (target = 0; target < 16; target++) { - struct aic7xxx_xferstats *sp; - int channel, target, lun; - - /* - * XXX: Need to fix this to avoid overflow... - * Fixed - gordo. - */ - size += sprintf(BLS, "\n"); - size += sprintf(BLS, "Statistics:\n"); - for (channel = 0; channel < 2; channel++) + for (lun = 0; lun < 8; lun++) { - for (target = 0; target < 16; target++) + sp = &p->stats[target][lun]; + if (sp->xfers == 0) { - for (lun = 0; lun < 8; lun++) - { - sp = &p->stats[channel][target][lun]; - if (sp->xfers == 0) - { - continue; - } - size += sprintf(BLS, "CHAN#%c (TGT %d LUN %d):\n", - 'A' + channel, target, lun); - size += sprintf(BLS, "nxfers %ld (%ld read;%ld written)\n", - sp->xfers, sp->r_total, sp->w_total); - size += sprintf(BLS, "blks(512) rd=%ld; blks(512) wr=%ld\n", - sp->r_total512, sp->w_total512); - size += sprintf(BLS, "%s\n", HDRB); - size += sprintf(BLS, " Reads:"); - size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->r_bins[0], - sp->r_bins[1], sp->r_bins[2], sp->r_bins[3]); - size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->r_bins[4], - sp->r_bins[5], sp->r_bins[6], sp->r_bins[7]); - size += sprintf(BLS, "%6ld %6ld\n", sp->r_bins[8], - sp->r_bins[9]); - size += sprintf(BLS, "Writes:"); - size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->w_bins[0], - sp->w_bins[1], sp->w_bins[2], sp->w_bins[3]); - size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->w_bins[4], - sp->w_bins[5], sp->w_bins[6], sp->w_bins[7]); - size += sprintf(BLS, "%6ld %6ld\n", sp->w_bins[8], - sp->w_bins[9]); - size += sprintf(BLS, "\n"); - } - if (size > 512) - printk(KERN_CRIT "aic7xxx: possible overflow at loop %d:%d\n", target, lun); - len += size; pos = begin + len; size = 0; - if (pos < offset) - { - begin = pos; - len = 0; - } - else if (pos >= offset + length) - goto stop_output; + continue; } + if (p->bus_type == AIC_TWIN) + size += sprintf(BLS, "CHAN#%c (TGT %d LUN %d):\n", + 'A' + (target >> 3), (target & 0x7), lun); + else + size += sprintf(BLS, "CHAN#%c (TGT %d LUN %d):\n", + 'A', target, lun); + size += sprintf(BLS, "nxfers %ld (%ld read;%ld written)\n", + sp->xfers, sp->r_total, sp->w_total); + size += sprintf(BLS, "blks(512) rd=%ld; blks(512) wr=%ld\n", + sp->r_total512, sp->w_total512); + size += sprintf(BLS, "%s\n", HDRB); + size += sprintf(BLS, " Reads:"); + for (i=0; i<10; i++) + size += sprintf(BLS, "%6ld ", sp->r_bins[i]); + size += sprintf(BLS, "\n"); + size += sprintf(BLS, "Writes:"); + for (i=0; i<10; i++) + size += sprintf(BLS, "%6ld ", sp->w_bins[i]); + size += sprintf(BLS, "\n\n"); } } #endif /* AIC7XXX_PROC_STATS */ -stop_output: - proc_debug("2pos: %ld offset: %ld len: %d\n", pos, offset, len); - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); /* Start slop */ - if (len < 0) - { - len = 0; /* off end of file */ - } - else if (len > length) - { - len = length; /* Ending slop */ + if ( size >= aic7xxx_buffer_size ) + printk(KERN_WARNING "aic7xxx: Overflow in aic7xxx_proc.c\n"); + + if ( offset > size - 1) { + kfree ( aic7xxx_buffer); + aic7xxx_buffer = NULL; + aic7xxx_buffer_size = length = 0; + *start = NULL; + } else { + *start = &aic7xxx_buffer[offset]; /* Start of wanted data */ + if ( size - offset < length) length = size - offset; } - proc_debug("3pos: %ld offset: %ld len: %d\n", pos, offset, len); - return (len); + return length; } /* diff -u --recursive --new-file v9/linux/drivers/scsi/aic7xxx_reg.h linux/drivers/scsi/aic7xxx_reg.h --- v9/linux/drivers/scsi/aic7xxx_reg.h Wed Aug 13 09:53:45 1997 +++ linux/drivers/scsi/aic7xxx_reg.h Mon Sep 22 14:53:09 1997 @@ -252,18 +252,20 @@ #define CUR_SCBID 0x58 -#define CMDOUTCNT 0x59 +#define ARG_1 0x59 +#define RETURN_1 0x59 +#define SEND_MSG 0x80 +#define SEND_SENSE 0x40 +#define SEND_REJ 0x20 #define SCSICONF 0x5a -#define RESET_SCSI 0x40 -#define FIFODEPTH 0x5a +#define CMDOUTCNT 0x5a -#define ARG_1 0x5b -#define RETURN_1 0x5b -#define SEND_MSG 0x80 -#define SEND_SENSE 0x40 -#define SEND_REJ 0x20 +#define FIFODEPTH 0x5b + +#define SCSICONF2 0x5b +#define RESET_SCSI 0x40 #define HOSTCONF 0x5d diff -u --recursive --new-file v9/linux/drivers/scsi/aic7xxx_seq.h linux/drivers/scsi/aic7xxx_seq.h --- v9/linux/drivers/scsi/aic7xxx_seq.h Wed Aug 13 09:53:45 1997 +++ linux/drivers/scsi/aic7xxx_seq.h Mon Sep 22 14:53:09 1997 @@ -26,8 +26,8 @@ 0x50, 0x6a, 0x60, 0x00, 0xff, 0x90, 0x4a, 0x02, 0x00, 0xa1, 0xa1, 0x17, - 0xff, 0x6c, 0x5b, 0x02, - 0xff, 0x5b, 0x27, 0x1c, + 0xff, 0x6c, 0x59, 0x02, + 0xff, 0x59, 0x27, 0x1c, 0xff, 0x4a, 0x90, 0x02, 0x00, 0x65, 0xaa, 0x17, 0x00, 0x6a, 0x52, 0x17, @@ -37,7 +37,7 @@ 0x00, 0x65, 0xbb, 0x17, 0x10, 0x6a, 0x60, 0x00, 0x00, 0x65, 0x03, 0x10, - 0xff, 0x5b, 0x90, 0x02, + 0xff, 0x59, 0x90, 0x02, 0xff, 0x58, 0xb3, 0x02, 0x10, 0x6a, 0x60, 0x00, 0x00, 0x65, 0x03, 0x10, @@ -217,7 +217,7 @@ 0x00, 0xb9, 0x77, 0x17, 0xff, 0xa2, 0xda, 0x1e, 0x71, 0x6a, 0x91, 0x00, - 0x40, 0x5b, 0xda, 0x18, + 0x40, 0x59, 0xda, 0x18, 0xff, 0xb9, 0xb3, 0x02, 0x00, 0x65, 0xe7, 0x10, 0x20, 0xa0, 0xe0, 0x1a, @@ -226,9 +226,9 @@ 0x00, 0xa1, 0xa1, 0x17, 0xff, 0x49, 0x6d, 0x02, 0xff, 0x4a, 0x90, 0x02, - 0xff, 0x5a, 0x64, 0x02, - 0x00, 0x59, 0xe1, 0x1c, - 0x01, 0x59, 0x59, 0x06, + 0xff, 0x5b, 0x64, 0x02, + 0x00, 0x5a, 0xe1, 0x1c, + 0x01, 0x5a, 0x5a, 0x06, 0xff, 0xb9, 0x9d, 0x02, 0x02, 0x6a, 0x91, 0x00, 0x08, 0xa0, 0xe7, 0x1e, @@ -255,8 +255,8 @@ 0xff, 0x66, 0x66, 0x06, 0xff, 0x64, 0xf7, 0x1a, 0x41, 0x6a, 0x91, 0x00, - 0x20, 0x5b, 0xcd, 0x1c, - 0x80, 0x5b, 0xcf, 0x18, + 0x20, 0x59, 0xcd, 0x1c, + 0x80, 0x59, 0xcf, 0x18, 0x10, 0x4c, 0x03, 0x00, 0x00, 0x65, 0xcf, 0x10, 0x04, 0xa0, 0xa0, 0x00, @@ -276,10 +276,10 @@ 0x07, 0x64, 0x64, 0x02, 0x00, 0x42, 0x42, 0x00, 0x00, 0x42, 0xa1, 0x17, - 0xff, 0x6c, 0x5b, 0x02, - 0xff, 0x5b, 0x28, 0x19, - 0xff, 0x5b, 0x18, 0x1d, - 0xff, 0x5b, 0x90, 0x02, + 0xff, 0x6c, 0x59, 0x02, + 0xff, 0x59, 0x28, 0x19, + 0xff, 0x59, 0x18, 0x1d, + 0xff, 0x59, 0x90, 0x02, 0x04, 0xa0, 0x2d, 0x1f, 0x00, 0x65, 0x2a, 0x11, 0xff, 0x06, 0x6a, 0x02, @@ -289,11 +289,11 @@ 0xe0, 0x4c, 0x2d, 0x19, 0x20, 0x12, 0x2d, 0x19, 0x20, 0x41, 0x41, 0x00, - 0x5b, 0x6a, 0x3a, 0x17, + 0x59, 0x6a, 0x3a, 0x17, 0xff, 0x3f, 0x64, 0x02, - 0x00, 0x5b, 0x65, 0x06, + 0x00, 0x59, 0x65, 0x06, 0x00, 0x65, 0x2d, 0x13, - 0xff, 0x5b, 0x90, 0x02, + 0xff, 0x59, 0x90, 0x02, 0xff, 0x42, 0x64, 0x02, 0x00, 0xa1, 0x2d, 0x19, 0x20, 0xa0, 0x2d, 0x1f, @@ -341,7 +341,7 @@ 0x40, 0x41, 0x4e, 0x1b, 0x21, 0x6a, 0x91, 0x01, 0xff, 0x65, 0x90, 0x02, - 0xff, 0x5b, 0x64, 0x02, + 0xff, 0x59, 0x64, 0x02, 0x00, 0xb9, 0x56, 0x19, 0x04, 0xa0, 0x60, 0x1b, 0x01, 0x65, 0x65, 0x06, @@ -349,7 +349,7 @@ 0x00, 0x65, 0x52, 0x19, 0x00, 0x6a, 0xad, 0x17, 0x0d, 0x6a, 0x3d, 0x00, - 0x00, 0x5b, 0x77, 0x17, + 0x00, 0x59, 0x77, 0x17, 0xff, 0xa8, 0x5e, 0x1f, 0x10, 0xa0, 0xa0, 0x00, 0x08, 0xa0, 0x4e, 0x1f, diff -u --recursive --new-file v9/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c --- v9/linux/drivers/scsi/eata.c Wed Aug 6 11:41:23 1997 +++ linux/drivers/scsi/eata.c Mon Sep 15 09:41:28 1997 @@ -1,5 +1,14 @@ /* * eata.c - Low-level driver for EATA/DMA SCSI host adapters. + * + * 12 Sep 1997 rev. 3.11 for linux 2.0.30 and 2.1.55 + * Use of udelay inside the wait loops to avoid timeout + * problems with fast cpus. + * Removed check about useless calls to the interrupt service + * routine (reported on SMP systems only). + * At initialization time "sorted/unsorted" is displayed instead + * of "linked/unlinked" to reinforce the fact that "linking" is + * nothing but "elevator sorting" in the actual implementation. * * 17 May 1997 rev. 3.10 for linux 2.0.30 and 2.1.38 * Use of serial_number_at_timeout in abort and reset processing. @@ -283,6 +292,7 @@ #include #include #include +#include #include #include #include @@ -323,6 +333,7 @@ #undef DEBUG_INTERRUPT #undef DEBUG_STATISTICS #undef DEBUG_RESET +#undef DEBUG_SMP #define MAX_ISA 4 #define MAX_VESA 0 @@ -351,7 +362,7 @@ #define READY 5 #define ABORTING 6 #define NO_DMA 0xff -#define MAXLOOP 200000 +#define MAXLOOP 10000 #define TAG_MIXED 0 #define TAG_SIMPLE 1 #define TAG_HEAD 2 @@ -630,9 +641,9 @@ if (TLDEV(dev->type)) { if (linked_comm && dev->queue_depth > 2) - link_suffix = ", linked"; + link_suffix = ", sorted"; else - link_suffix = ", unlinked"; + link_suffix = ", unsorted"; } if (tagged_comm && dev->tagged_supported && TLDEV(dev->type)) { @@ -656,8 +667,10 @@ static inline int wait_on_busy(unsigned int iobase, unsigned int loop) { - while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) + while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) { + udelay(1L); if (--loop == 0) return TRUE; + } return FALSE; } @@ -683,8 +696,10 @@ for (p = start; p <= end; p++) { - while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) + while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) { + udelay(1L); if (--loop == 0) return TRUE; + } loop = MAXLOOP; *p = inw(iobase); @@ -1416,7 +1431,7 @@ HD(j)->in_reset = TRUE; sti(); time = jiffies; - while ((jiffies - time) < HZ && limit++ < 100000000); + while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); cli(); printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); @@ -1831,9 +1846,11 @@ calls[irq]++; +#if defined (DEBUG_SMP) if (total_loops == 0) printk("%s: ihdlr, irq %d, no command completed, calls %d.\n", driver_name, irq, calls[irq]); +#endif if (do_trace) printk("%s: ihdlr, exit, irq %d, calls %d.\n", driver_name, irq, calls[irq]); diff -u --recursive --new-file v9/linux/drivers/scsi/eata.h linux/drivers/scsi/eata.h --- v9/linux/drivers/scsi/eata.h Wed Aug 6 11:41:23 1997 +++ linux/drivers/scsi/eata.h Mon Sep 15 09:41:28 1997 @@ -12,7 +12,7 @@ int eata2x_abort(Scsi_Cmnd *); int eata2x_reset(Scsi_Cmnd *, unsigned int); -#define EATA_VERSION "3.10.00" +#define EATA_VERSION "3.11.00" #define EATA { \ diff -u --recursive --new-file v9/linux/drivers/scsi/scsi_module.c linux/drivers/scsi/scsi_module.c --- v9/linux/drivers/scsi/scsi_module.c Wed Nov 8 22:24:08 1995 +++ linux/drivers/scsi/scsi_module.c Tue Sep 23 21:04:20 1997 @@ -34,7 +34,11 @@ int init_module(void) { driver_template.usage_count = &mod_use_count_; scsi_register_module(MODULE_SCSI_HA, &driver_template); - return (driver_template.present == 0); + if (driver_template.present) + return 0; + + scsi_unregister_module(MODULE_SCSI_HA, &driver_template); + return -1; } void cleanup_module( void) { diff -u --recursive --new-file v9/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c --- v9/linux/drivers/scsi/u14-34f.c Wed Aug 6 11:41:23 1997 +++ linux/drivers/scsi/u14-34f.c Mon Sep 15 09:41:28 1997 @@ -1,6 +1,15 @@ /* * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. * + * 12 Sep 1997 rev. 3.11 for linux 2.0.30 and 2.1.55 + * Use of udelay inside the wait loops to avoid timeout + * problems with fast cpus. + * Removed check about useless calls to the interrupt service + * routine (reported on SMP systems only). + * At initialization time "sorted/unsorted" is displayed instead + * of "linked/unlinked" to reinforce the fact that "linking" is + * nothing but "elevator sorting" in the actual implementation. + * * 17 May 1997 rev. 3.10 for linux 2.0.30 and 2.1.38 * Use of serial_number_at_timeout in abort and reset processing. * Use of the __initfunc and __initdata macro in setup code. @@ -269,6 +278,7 @@ #include #include #include +#include #include #include #include @@ -321,6 +331,7 @@ #undef DEBUG_INTERRUPT #undef DEBUG_STATISTICS #undef DEBUG_RESET +#undef DEBUG_SMP #define MAX_ISA 3 #define MAX_VESA 1 @@ -349,7 +360,7 @@ #define READY 5 #define ABORTING 6 #define NO_DMA 0xff -#define MAXLOOP 200000 +#define MAXLOOP 10000 #define REG_LCL_MASK 0 #define REG_LCL_INTR 1 @@ -530,9 +541,9 @@ if (TLDEV(dev->type)) { if (linked_comm && dev->queue_depth > 2) - link_suffix = ", linked"; + link_suffix = ", sorted"; else - link_suffix = ", unlinked"; + link_suffix = ", unsorted"; } if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue) @@ -551,8 +562,10 @@ static inline int wait_on_busy(unsigned int iobase, unsigned int loop) { - while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED) + while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED) { + udelay(1L); if (--loop == 0) return TRUE; + } return FALSE; } @@ -588,7 +601,7 @@ sti(); time = jiffies; - while ((jiffies - time) < HZ && limit++ < 100000000); + while ((jiffies - time) < HZ && limit++ < 20000) udelay(100L); cli(); if (cpp->adapter_status || HD(j)->cp_stat[0] != FREE) { @@ -1195,7 +1208,7 @@ HD(j)->in_reset = TRUE; sti(); time = jiffies; - while ((jiffies - time) < HZ && limit++ < 100000000); + while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); cli(); printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); @@ -1616,9 +1629,11 @@ calls[irq]++; +#if defined (DEBUG_SMP) if (total_loops == 0) printk("%s: ihdlr, irq %d, no command completed, calls %d.\n", driver_name, irq, calls[irq]); +#endif if (do_trace) printk("%s: ihdlr, exit, irq %d, calls %d.\n", driver_name, irq, calls[irq]); diff -u --recursive --new-file v9/linux/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h --- v9/linux/drivers/scsi/u14-34f.h Wed Aug 6 11:41:23 1997 +++ linux/drivers/scsi/u14-34f.h Mon Sep 15 09:41:28 1997 @@ -11,7 +11,7 @@ int u14_34f_reset(Scsi_Cmnd *, unsigned int); int u14_34f_biosparam(Disk *, kdev_t, int *); -#define U14_34F_VERSION "3.10.00" +#define U14_34F_VERSION "3.11.00" #define ULTRASTOR_14_34F { \ NULL, /* Ptr for modules */ \ diff -u --recursive --new-file v9/linux/fs/buffer.c linux/fs/buffer.c --- v9/linux/fs/buffer.c Tue Aug 19 15:18:16 1997 +++ linux/fs/buffer.c Tue Sep 23 13:23:33 1997 @@ -559,7 +559,7 @@ static struct buffer_head *find_candidate(struct buffer_head *bh, int *list_len, int size) { - int behind = 0; + int lookahead = 7; if (!bh) goto no_candidate; @@ -572,11 +572,12 @@ try_to_free_buffer(bh,&bh,1); if (!bh) break; + lookahead = 7; continue; } else if (buffer_locked(bh) && (bh->b_list == BUF_LOCKED || bh->b_list == BUF_LOCKED1)) { - if (behind++ > 10) { + if (!--lookahead) { (*list_len) = 0; goto no_candidate; } @@ -595,9 +596,10 @@ { struct buffer_head * bh; struct buffer_head * candidate[BUF_DIRTY]; + extern struct task_struct *bdflush_tsk; unsigned int best_time, winner; int buffers[BUF_DIRTY]; - int i; + int i, limit = ((min_free_pages + free_pages_low) >> 1); int needed; refilled = 1; @@ -606,7 +608,7 @@ for user processes to use (and dirty) */ /* We are going to try to locate this much memory */ - needed =bdf_prm.b_un.nrefill * size; + needed = bdf_prm.b_un.nrefill * size; while (nr_free_pages > min_free_pages*2 && needed > 0 && grow_buffers(GFP_BUFFER, size)) { @@ -661,21 +663,38 @@ /* Dirty buffers should not overtake, wakeup_bdflush(1) calls bdflush and sleeps, therefore kswapd does his important work. */ - if ((nr_buffers_type[BUF_DIRTY] > nr_buffers * bdf_prm.b_un.nfract/100) || - (nr_free_pages < min_free_pages)) + if (nr_buffers_type[BUF_DIRTY] > nr_buffers * bdf_prm.b_un.nfract/100) wakeup_bdflush(1); /* Too bad, that was not enough. Try a little harder to grow some. */ - if (nr_free_pages > min_free_pages + 5) { + if (nr_free_pages > limit) { if (grow_buffers(GFP_BUFFER, size)) { needed -= PAGE_SIZE; goto repeat; }; } + /* If we are not bdflush we should wake up bdflush and try it again. */ + + if (current != bdflush_tsk) { + wakeup_bdflush(1); + needed -= PAGE_SIZE; + goto repeat; + } + + /* We are bdflush: let's try our best */ + + /* + * In order to protect our reserved pages, + * return now if we got any buffers. + */ + allow_interrupts(); + if (free_list[BUFSIZE_INDEX(size)]) + return; + /* and repeat until we find something good */ - wakeup_bdflush(1); + grow_buffers(GFP_BUFFER, size); /* decrease needed even if there is no success */ needed -= PAGE_SIZE; @@ -966,11 +985,15 @@ * This is critical. We can't swap out pages to get * more buffer heads, because the swap-out may need * more buffer-heads itself. Thus GFP_ATOMIC. + * + * This is no longer true, it is GFP_BUFFER again, the + * swapping code now knows not to perform I/O when that + * GFP level is specified... -DaveM */ /* we now use kmalloc() here instead of gfp as we want to be able to easily release buffer heads - they took up quite a bit of memory (tridge) */ - bh = (struct buffer_head *) kmalloc(sizeof(*bh),GFP_ATOMIC); + bh = (struct buffer_head *) kmalloc(sizeof(*bh),GFP_BUFFER); if (bh) { put_unused_buffer_head(bh); nr_buffer_heads++; diff -u --recursive --new-file v9/linux/fs/fcntl.c linux/fs/fcntl.c --- v9/linux/fs/fcntl.c Thu Jul 4 11:23:45 1996 +++ linux/fs/fcntl.c Tue Sep 16 15:47:57 1997 @@ -55,8 +55,6 @@ asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct file * filp; - struct task_struct *p; - int task_found = 0; if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) return -EBADF; @@ -108,49 +106,11 @@ * current syscall conventions, the only way * to fix this will be in libc. */ - return filp->f_owner; + return filp->f_owner.pid; case F_SETOWN: - /* - * Add the security checks - AC. Without - * this there is a massive Linux security - * hole here - consider what happens if - * you do something like - * - * fcntl(0,F_SETOWN,some_root_process); - * getchar(); - * - * and input a line! - * - * BTW: Don't try this for fun. Several Unix - * systems I tried this on fall for the - * trick! - * - * I had to fix this botch job as Linux - * kill_fasync asserts priv making it a - * free all user process killer! - * - * Changed to make the security checks more - * liberal. -- TYT - */ - if (current->pgrp == -arg || current->pid == arg) - goto fasync_ok; - - for_each_task(p) { - if ((p->pid == arg) || (p->pid == -arg) || - (p->pgrp == -arg)) { - task_found++; - if ((p->session != current->session) && - (p->uid != current->uid) && - (p->euid != current->euid) && - !suser()) - return -EPERM; - break; - } - } - if ((task_found == 0) && !suser()) - return -EINVAL; - fasync_ok: - filp->f_owner = arg; + filp->f_owner.pid = arg; + filp->f_owner.uid = current->uid; + filp->f_owner.euid = current->euid; if (S_ISSOCK (filp->f_inode->i_mode)) sock_fcntl (filp, F_SETOWN, arg); return 0; @@ -164,18 +124,38 @@ } } +static void send_sigio(int sig, int pid, uid_t uid, uid_t euid) +{ + struct task_struct * p; + + for_each_task(p) { + int match = p->pid; + if (pid < 0) + match = -p->pgrp; + if (pid != match) + continue; + if (!euid && + (euid ^ p->suid) && (euid ^ p->uid) && + (uid ^ p->suid) && (uid ^ p->uid)) + continue; + p->signal |= 1 << (sig-1); + if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked)) + wake_up_process(p); + } +} + void kill_fasync(struct fasync_struct *fa, int sig) { while (fa) { + struct fown_struct * fown; if (fa->magic != FASYNC_MAGIC) { printk("kill_fasync: bad magic number in " "fasync_struct!\n"); return; } - if (fa->fa_file->f_owner > 0) - kill_proc(fa->fa_file->f_owner, sig, 1); - else - kill_pg(-fa->fa_file->f_owner, sig, 1); + fown = &fa->fa_file->f_owner; + if (fown->pid) + send_sigio(sig, fown->pid, fown->uid, fown->euid); fa = fa->fa_next; } } diff -u --recursive --new-file v9/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- v9/linux/fs/smbfs/inode.c Sat Aug 16 11:21:49 1997 +++ linux/fs/smbfs/inode.c Mon Sep 15 10:02:41 1997 @@ -232,10 +232,13 @@ kdev_t dev = sb->s_dev; int error; + MOD_INC_USE_COUNT; + if (smb_get_mount_data(&data, raw_data) != 0) { printk("smb_read_super: wrong data argument\n"); sb->s_dev = 0; + MOD_DEC_USE_COUNT; return NULL; } fd = data.fd; @@ -243,12 +246,14 @@ { printk("smb_read_super: invalid file descriptor\n"); sb->s_dev = 0; + MOD_DEC_USE_COUNT; return NULL; } if (!S_ISSOCK(filp->f_inode->i_mode)) { printk("smb_read_super: not a socket!\n"); sb->s_dev = 0; + MOD_DEC_USE_COUNT; return NULL; } /* We must malloc our own super-block info */ @@ -258,6 +263,8 @@ if (smb_sb == NULL) { printk("smb_read_super: could not alloc smb_sb_info\n"); + sb->s_dev = 0; + MOD_DEC_USE_COUNT; return NULL; } filp->f_count += 1; @@ -328,7 +335,6 @@ printk("smb_read_super: get root inode failed\n"); goto fail; } - MOD_INC_USE_COUNT; return sb; fail: @@ -340,6 +346,7 @@ filp->f_count -= 1; smb_dont_catch_keepalive(server); smb_kfree_s(SMB_SBP(sb), sizeof(struct smb_sb_info)); + MOD_DEC_USE_COUNT; return NULL; } @@ -385,9 +392,32 @@ (attr->ia_gid != SMB_SERVER(inode)->m.gid))) return -EPERM; - if (((attr->ia_valid & ATTR_MODE) && - (attr->ia_mode & ~(S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)))) - return -EPERM; + if (attr->ia_valid & ATTR_MODE) { + struct smb_dirent *fold = SMB_FINFO(inode); + struct smb_dirent finfo; + + if (attr->ia_mode & ~(S_IFREG | S_IFDIR | + S_IRWXU | S_IRWXG | S_IRWXO)) + return -EPERM; + + memset((char *)&finfo, 0, sizeof(finfo)); + finfo.attr = fold->attr; + + if((attr->ia_mode & 0200) == 0) + finfo.attr |= aRONLY; + else + finfo.attr &= ~aRONLY; + + if ((error = smb_proc_setattr(SMB_SERVER(inode), + inode, &finfo)) >= 0) + { + fold->attr = finfo.attr; + if ((attr->ia_mode & 0200) == 0) + inode->i_mode &= ~0222; + else + inode->i_mode |= 0222; + } + } if ((attr->ia_valid & ATTR_SIZE) != 0) { @@ -401,41 +431,18 @@ goto fail; } - if ((attr->ia_valid & (ATTR_CTIME | ATTR_MTIME | ATTR_ATIME)) != 0) - { - - struct smb_dirent finfo; - finfo.attr = 0; - finfo.f_size = inode->i_size; - finfo.f_blksize = inode->i_blksize; - - if ((attr->ia_valid & ATTR_CTIME) != 0) - finfo.f_ctime = attr->ia_ctime; - else - finfo.f_ctime = inode->i_ctime; - - if ((attr->ia_valid & ATTR_MTIME) != 0) - finfo.f_mtime = attr->ia_mtime; - else - finfo.f_mtime = inode->i_mtime; + /* ATTR_CTIME and ATTR_ATIME can not be set via SMB, so ignore it. */ - if ((attr->ia_valid & ATTR_ATIME) != 0) - finfo.f_atime = attr->ia_atime; + if (attr->ia_valid & ATTR_MTIME) + { + if (smb_make_open(inode, O_WRONLY) != 0) + error = -EACCES; else - finfo.f_atime = inode->i_atime; - - if ((error = smb_proc_setattr(SMB_SERVER(inode), - inode, &finfo)) >= 0) - { - inode->i_ctime = finfo.f_ctime; - inode->i_mtime = finfo.f_mtime; - inode->i_atime = finfo.f_atime; - } + inode->i_mtime = attr->ia_mtime; } fail: smb_invalid_dir_cache(smb_info_ino(SMB_INOP(inode)->dir)); - return error; } diff -u --recursive --new-file v9/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c --- v9/linux/fs/smbfs/proc.c Wed Aug 13 09:57:46 1997 +++ linux/fs/smbfs/proc.c Mon Sep 15 10:02:41 1997 @@ -230,40 +230,6 @@ return local2utc(secs); } - -/* Convert linear UNIX date to a MS-DOS time/date pair. */ - -static void -date_unix2dos(int unix_date, byte * date, byte * time) -{ - int day, year, nl_day, month; - - unix_date = utc2local(unix_date); - WSET(time, 0, - (unix_date % 60) / 2 + (((unix_date / 60) % 60) << 5) + - (((unix_date / 3600) % 24) << 11)); - day = unix_date / 86400 - 3652; - year = day / 365; - if ((year + 3) / 4 + 365 * year > day) - year--; - day -= (year + 3) / 4 + 365 * year; - if (day == 59 && !(year & 3)) - { - nl_day = day; - month = 2; - } else - { - nl_day = (year & 3) || day <= 59 ? day : day - 1; - for (month = 0; month < 12; month++) - if (day_n[month] > nl_day) - break; - } - WSET(date, 0, - nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9)); -} - - - /*****************************************************************************/ /* */ /* Support section. */ @@ -922,6 +888,9 @@ entry->f_mode = server->m.file_mode; } + if (entry->attr & aRONLY) + entry->f_mode &= ~0222; + if ((entry->f_blksize != 0) && (entry->f_size != 0)) { entry->f_blocks = @@ -1414,80 +1383,15 @@ return 0; } -static int -smb_proc_getattr_trans2(struct inode *dir, const char *name, int len, - struct smb_dirent *entry) -{ - struct smb_server *server = SMB_SERVER(dir); - char param[SMB_MAXPATHLEN + 20]; - char *p; - int result; - - unsigned char *resp_data = NULL; - unsigned char *resp_param = NULL; - int resp_data_len = 0; - int resp_param_len = 0; - - WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */ - DSET(param, 2, 0); - p = smb_encode_path(server, param + 6, SMB_INOP(dir), name, len); - - smb_lock_server(server); - retry: - result = smb_trans2_request(server, TRANSACT2_QPATHINFO, - 0, NULL, p - param, param, - &resp_data_len, &resp_data, - &resp_param_len, &resp_param); - - if (server->rcls != 0) - { - smb_unlock_server(server); - return -smb_errno(server->rcls, server->err); - } - if (result < 0) - { - if (smb_retry(server)) - { - goto retry; - } - smb_unlock_server(server); - return result; - } - if (resp_data_len < 22) - { - smb_unlock_server(server); - return -ENOENT; - } - entry->f_ctime = date_dos2unix(WVAL(resp_data, 2), - WVAL(resp_data, 0)); - entry->f_atime = date_dos2unix(WVAL(resp_data, 6), - WVAL(resp_data, 4)); - entry->f_mtime = date_dos2unix(WVAL(resp_data, 10), - WVAL(resp_data, 8)); - entry->f_size = DVAL(resp_data, 12); - entry->attr = WVAL(resp_data, 20); - smb_unlock_server(server); - - return 0; -} - int smb_proc_getattr(struct inode *dir, const char *name, int len, struct smb_dirent *entry) { struct smb_server *server = SMB_SERVER(dir); - int result = 0; + int result; smb_init_dirent(server, entry); - - if (server->protocol >= PROTOCOL_LANMAN2) - { - result = smb_proc_getattr_trans2(dir, name, len, entry); - } - if ((server->protocol < PROTOCOL_LANMAN2) || (result < 0)) - { - result = smb_proc_getattr_core(dir, name, len, entry); - } + result = smb_proc_getattr_core(dir, name, len, entry); smb_finish_dirent(server, entry); entry->len = len; @@ -1497,12 +1401,9 @@ return result; } - -/* In core protocol, there is only 1 time to be set, we use - entry->f_mtime, to make touch work. */ -static int -smb_proc_setattr_core(struct smb_server *server, - struct inode *i, struct smb_dirent *new_finfo) +int +smb_proc_setattr(struct smb_server *server, + struct inode *i, struct smb_dirent *new_finfo) { char *p; char *buf; @@ -1514,12 +1415,14 @@ buf = server->packet; p = smb_setup_header(server, SMBsetatr, 8, 0); WSET(buf, smb_vwv0, new_finfo->attr); - DSET(buf, smb_vwv1, utc2local(new_finfo->f_mtime)); + DSET(buf, smb_vwv1, 0); + DSET(buf, smb_vwv3, 0); + DSET(buf, smb_vwv5, 0); + WSET(buf, smb_vwv7, 0); *p++ = 4; p = smb_encode_path(server, p, SMB_INOP(i)->dir, SMB_INOP(i)->finfo.name, SMB_INOP(i)->finfo.len); - p = smb_encode_ascii(p, "", 0); smb_setup_bcc(server, p); if ((result = smb_request_ok(server, SMBsetatr, 0, 0)) < 0) @@ -1530,74 +1433,6 @@ } } smb_unlock_server(server); - return result; -} - -static int -smb_proc_setattr_trans2(struct smb_server *server, - struct inode *i, struct smb_dirent *new_finfo) -{ - char param[SMB_MAXPATHLEN + 20]; - char data[26]; - char *p; - int result; - - unsigned char *resp_data = NULL; - unsigned char *resp_param = NULL; - int resp_data_len = 0; - int resp_param_len = 0; - - WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */ - DSET(param, 2, 0); - p = smb_encode_path(server, param + 6, - SMB_INOP(i)->dir, SMB_INOP(i)->finfo.name, - SMB_INOP(i)->finfo.len); - - date_unix2dos(new_finfo->f_ctime, &(data[0]), &(data[2])); - date_unix2dos(new_finfo->f_atime, &(data[4]), &(data[6])); - date_unix2dos(new_finfo->f_mtime, &(data[8]), &(data[10])); - DSET(data, 12, new_finfo->f_size); - DSET(data, 16, new_finfo->f_blksize); - WSET(data, 20, new_finfo->attr); - WSET(data, 22, 0); - - smb_lock_server(server); - retry: - result = smb_trans2_request(server, TRANSACT2_SETPATHINFO, - 26, data, p - param, param, - &resp_data_len, &resp_data, - &resp_param_len, &resp_param); - - if (server->rcls != 0) - { - smb_unlock_server(server); - return -smb_errno(server->rcls, server->err); - } - if (result < 0) - { - if (smb_retry(server)) - { - goto retry; - } - } - smb_unlock_server(server); - return 0; -} - -int -smb_proc_setattr(struct smb_server *server, struct inode *inode, - struct smb_dirent *new_finfo) -{ - int result; - - if (server->protocol >= PROTOCOL_LANMAN2) - { - result = smb_proc_setattr_trans2(server, inode, new_finfo); - } - if ((server->protocol < PROTOCOL_LANMAN2) || (result < 0)) - { - result = smb_proc_setattr_core(server, inode, new_finfo); - } return result; } diff -u --recursive --new-file v9/linux/fs/smbfs/sock.c linux/fs/smbfs/sock.c --- v9/linux/fs/smbfs/sock.c Wed Aug 13 09:57:46 1997 +++ linux/fs/smbfs/sock.c Mon Sep 15 10:02:41 1997 @@ -437,8 +437,10 @@ result = -EIO; goto fail; } - DDPRINTK("target: %X\n", *data + WVAL(inbuf, smb_drdisp)); + DDPRINTK("target: %X\n", + (unsigned int) *data + WVAL(inbuf, smb_drdisp)); DDPRINTK("source: %X\n", + (unsigned int) smb_base(inbuf) + WVAL(inbuf, smb_droff)); DDPRINTK("disp: %d, off: %d, cnt: %d\n", WVAL(inbuf, smb_drdisp), WVAL(inbuf, smb_droff), @@ -553,7 +555,7 @@ } len = smb_len(buffer) + 4; - DDPRINTK("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]); + DPRINTK("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]); old_mask = current->blocked; current->blocked |= ~(_S(SIGKILL) | _S(SIGSTOP)); @@ -672,8 +674,8 @@ unsigned short fs; int result; - DDPRINTK("smb_trans2_request: com=%d, ld=%d, lp=%d\n", - trans2_command, ldata, lparam); + DPRINTK("smb_trans2_request: com=%d, ld=%d, lp=%d\n", + trans2_command, ldata, lparam); if (server->state != CONN_VALID) { diff -u --recursive --new-file v9/linux/include/asm-i386/delay.h linux/include/asm-i386/delay.h --- v9/linux/include/asm-i386/delay.h Tue Oct 8 09:43:30 1996 +++ linux/include/asm-i386/delay.h Tue Sep 16 14:44:38 1997 @@ -6,15 +6,19 @@ * * Delay routines, using a pre-computed "loops_per_second" value. */ - + +#include + #ifdef __SMP__ #include #endif +extern void __do_delay(void); /* Special register call calling convention */ + extern __inline__ void __delay(int loops) { __asm__ __volatile__( - ".align 2,0x90\n1:\tdecl %0\n\tjns 1b" + "call " SYMBOL_NAME_STR(__do_delay) :/* no outputs */ :"a" (loops) :"ax"); diff -u --recursive --new-file v9/linux/include/linux/fs.h linux/include/linux/fs.h --- v9/linux/include/linux/fs.h Sat Aug 23 10:54:51 1997 +++ linux/include/linux/fs.h Mon Sep 22 23:03:31 1997 @@ -79,7 +79,7 @@ /* * Flags that can be altered by MS_REMOUNT */ -#define MS_RMT_MASK (MS_RDONLY|MS_MANDLOCK|MS_NOATIME) +#define MS_RMT_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME) /* * Magic mount flag number. Has to be or-ed to the flag values. @@ -332,6 +332,11 @@ } u; }; +struct fown_struct { + int pid; /* pid or -pgrp where SIGIO should be sent */ + uid_t uid, euid; /* uid/euid of process setting the owner */ +}; + struct file { mode_t f_mode; loff_t f_pos; @@ -339,7 +344,7 @@ unsigned short f_count; unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin; struct file *f_next, *f_prev; - int f_owner; /* pid or -pgrp where SIGIO should be sent */ + struct fown_struct f_owner; struct inode * f_inode; struct file_operations * f_op; unsigned long f_version; diff -u --recursive --new-file v9/linux/include/linux/mroute.h linux/include/linux/mroute.h --- v9/linux/include/linux/mroute.h Sat Aug 23 10:56:33 1997 +++ linux/include/linux/mroute.h Mon Sep 22 23:04:59 1997 @@ -147,6 +147,8 @@ struct sk_buff_head mfc_unresolved; /* Unresolved buffers */ int mfc_queuelen; /* Unresolved buffer counter */ unsigned char mfc_ttls[MAXVIFS]; /* TTL thresholds */ + unsigned long mfc_packets; /* Packets on this entry */ + unsigned long mfc_bytes; /* Bytes on this entry */ }; #define MFC_QUEUED 1 diff -u --recursive --new-file v9/linux/include/linux/tty_flip.h linux/include/linux/tty_flip.h --- v9/linux/include/linux/tty_flip.h Sun May 22 21:55:15 1994 +++ linux/include/linux/tty_flip.h Tue Sep 9 19:26:41 1997 @@ -10,10 +10,11 @@ _INLINE_ void tty_insert_flip_char(struct tty_struct *tty, unsigned char ch, char flag) { - if (tty->flip.count++ >= TTY_FLIPBUF_SIZE) - return; - *tty->flip.flag_buf_ptr++ = flag; - *tty->flip.char_buf_ptr++ = ch; + if (tty->flip.count < TTY_FLIPBUF_SIZE) { + tty->flip.count++; + *tty->flip.flag_buf_ptr++ = flag; + *tty->flip.char_buf_ptr++ = ch; + } } _INLINE_ void tty_schedule_flip(struct tty_struct *tty) diff -u --recursive --new-file v9/linux/include/net/ip_alias.h linux/include/net/ip_alias.h --- v9/linux/include/net/ip_alias.h Mon Dec 25 20:03:01 1995 +++ linux/include/net/ip_alias.h Wed Sep 17 12:00:48 1997 @@ -2,7 +2,7 @@ * IP_ALIAS (AF_INET) aliasing definitions. * * - * Version: @(#)ip_alias.h 0.43 12/20/95 + * Version: @(#)ip_alias.h 0.50 4/20/97 * * Author: Juan Jose Ciarlante, * diff -u --recursive --new-file v9/linux/include/net/route.h linux/include/net/route.h --- v9/linux/include/net/route.h Sat Aug 23 10:56:23 1997 +++ linux/include/net/route.h Mon Sep 22 23:04:50 1997 @@ -85,6 +85,7 @@ extern void ip_rt_update(int event, struct device *dev); extern void ip_rt_redirect(__u32 src, __u32 dst, __u32 gw, struct device *dev); extern struct rtable *ip_rt_slow_route(__u32 daddr, int local, struct device *dev); +extern struct device *ip_rt_dev(__u32 addr); extern int rt_get_info(char * buffer, char **start, off_t offset, int length, int dummy); extern int rt_cache_get_info(char *buffer, char **start, off_t offset, int length, int dummy); extern int ip_rt_ioctl(unsigned int cmd, void *arg); diff -u --recursive --new-file v9/linux/kernel/sched.c linux/kernel/sched.c --- v9/linux/kernel/sched.c Mon Aug 11 13:42:11 1997 +++ linux/kernel/sched.c Tue Sep 9 18:22:31 1997 @@ -340,15 +340,19 @@ if (smp_processor_id() == boot_cpu_id) return; if (smp_blocked_interrupt_pending) { - long timeout_counter = loops_per_sec; unsigned long saved_kernel_counter; + long timeout_counter; saved_active_kernel_processor = active_kernel_processor; saved_kernel_counter = kernel_counter; kernel_counter = 0; active_kernel_processor = boot_cpu_id; + timeout_counter = 6000000; while (active_kernel_processor != saved_active_kernel_processor && --timeout_counter >= 0) - barrier(); + { + udelay(10); + barrier(); + } if (timeout_counter < 0) panic("FORWARDED INTERRUPT TIMEOUT (AKP = %d, Saved AKP = %d)\n", active_kernel_processor, saved_active_kernel_processor); diff -u --recursive --new-file v9/linux/mm/kmalloc.c linux/mm/kmalloc.c --- v9/linux/mm/kmalloc.c Sat Jun 8 08:12:33 1996 +++ linux/mm/kmalloc.c Tue Sep 23 13:23:33 1997 @@ -447,6 +447,6 @@ return; not_on_freelist: - printk("Ooops. page %p doesn't show on freelist.\n", page); restore_flags(flags); + printk("Ooops. page %p doesn't show on freelist.\n", page); } diff -u --recursive --new-file v9/linux/mm/vmscan.c linux/mm/vmscan.c --- v9/linux/mm/vmscan.c Tue Aug 26 09:46:04 1997 +++ linux/mm/vmscan.c Tue Sep 23 13:23:33 1997 @@ -406,11 +406,8 @@ can_do_io = 1; if (wait) stop = 0; - if (priority == GFP_BUFFER) { - /* bdflush() should do the rest if we fail */ - stop = 3; + if (priority == GFP_BUFFER) can_do_io = 0; - } switch (state) { do { case 0: @@ -492,10 +489,14 @@ interruptible_sleep_on(&kswapd_wait); kswapd_awake = 1; swapstats.wakeups++; + /* Protect our reserved pages: */ + i = 0; + if (nr_free_pages <= min_free_pages) + i = (1+min_free_pages) - nr_free_pages; /* Do the background pageout: */ - for (i=0; i < kswapd_ctl.maxpages; i++) + for (i += kswapd_ctl.maxpages; i > 0; i--) try_to_free_page(GFP_KERNEL, 0, - (nr_free_pages < min_free_pages)); + (nr_free_pages <= min_free_pages)); } } diff -u --recursive --new-file v9/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v9/linux/net/ipv4/arp.c Tue Aug 12 17:12:26 1997 +++ linux/net/ipv4/arp.c Wed Sep 17 12:00:47 1997 @@ -1921,6 +1921,7 @@ { /* * net_alias_dev_rx32 returns main dev if it fails to found other. + * if successful, also incr. alias rx count. */ dev = net_alias_dev_rx32(dev, AF_INET, sip, tip); diff -u --recursive --new-file v9/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c --- v9/linux/net/ipv4/icmp.c Wed Aug 13 17:15:54 1997 +++ linux/net/ipv4/icmp.c Mon Sep 15 09:54:52 1997 @@ -40,6 +40,8 @@ * valid (RFC 1812). * Alan Cox : Spoofing and junk icmp protections. * Elliot Poger : Added support for SO_BINDTODEVICE. + * Willy Konynenberg : Transparent proxy adapted to new + * socket hash code. * * * RFC1122 (Host Requirements -- Comm. Layer) Status: @@ -993,15 +995,8 @@ * in udp.c or tcp.c... */ -/* This should work with the new hashes now. -DaveM */ -extern struct sock *tcp_v4_proxy_lookup(unsigned short num, unsigned long raddr, - unsigned short rnum, unsigned long laddr, - unsigned long paddr, unsigned short pnum, - struct device *dev); -extern struct sock *udp_v4_proxy_lookup(unsigned short num, unsigned long raddr, - unsigned short rnum, unsigned long laddr, - unsigned long paddr, unsigned short pnum, - struct device *dev); +extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, struct device *dev); +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, struct device *dev); int icmp_chkaddr(struct sk_buff *skb) { @@ -1017,8 +1012,7 @@ { struct tcphdr *th = (struct tcphdr *)(((unsigned char *)iph)+(iph->ihl<<2)); - sk = tcp_v4_proxy_lookup(th->source, iph->daddr, th->dest, - iph->saddr, 0, 0, skb->dev); + sk = tcp_v4_lookup(iph->saddr, th->source, iph->daddr, th->dest, skb->dev); if (!sk) return 0; if (sk->saddr != iph->saddr) return 0; if (sk->daddr != iph->daddr) return 0; @@ -1032,8 +1026,7 @@ { struct udphdr *uh = (struct udphdr *)(((unsigned char *)iph)+(iph->ihl<<2)); - sk = udp_v4_proxy_lookup(uh->source, iph->daddr, uh->dest, - iph->saddr, 0, 0, skb->dev); + sk = udp_v4_lookup(iph->saddr, uh->source, iph->daddr, uh->dest, skb->dev); if (!sk) return 0; if (sk->saddr != iph->saddr && ip_chk_addr(iph->saddr) != IS_MYADDR) return 0; diff -u --recursive --new-file v9/linux/net/ipv4/ip_alias.c linux/net/ipv4/ip_alias.c --- v9/linux/net/ipv4/ip_alias.c Tue Aug 12 11:30:25 1997 +++ linux/net/ipv4/ip_alias.c Wed Sep 17 12:00:48 1997 @@ -2,12 +2,14 @@ * IP_ALIAS (AF_INET) aliasing module. * * - * Version: @(#)ip_alias.c 0.43 12/20/95 + * Version: @(#)ip_alias.c 0.50 6/14/97 * * Author: Juan Jose Ciarlante, * * Fixes: * JJC : ip_alias_dev_select method. + * JJC : use ip_rt_dev instead of ip_rt_route + * JJC : new no_sel semantics * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -76,11 +78,13 @@ (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); } +/* + * Called by net_alias module when no local alias address has been hit, + * to find out if an alias is a better candidate for handling given addr + */ struct device *ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa) { __u32 addr; - struct rtable *rt; - struct device *dev=NULL; /* * Defensive... @@ -102,13 +106,12 @@ * net_alias module will check if returned device is main_dev's alias */ - rt = ip_rt_route(addr, 0, NULL); - if(rt) - { - dev=rt->rt_dev; - ip_rt_put(rt); - } - return dev; + /* + * Fixed arping caused by incorrectly using ip_rt_route(), + * ip_rt_dev() just returns routing device without hh generation. + */ + + return ip_rt_dev(addr); } /* @@ -149,8 +152,23 @@ #ifdef MODULE +/* + * If no_sel is set, alias association (device selection) with + * foreign addresses will be disabled. + * You will get: + * - faster operation by avoiding completely routing lookups + * You will loose: + * - inter-alias routing + * - proxyarp over aliases + */ + +int no_sel = 0; + int init_module(void) { + if (no_sel) + ip_alias_type.dev_select = NULL; + if (ip_alias_init() != 0) return -EIO; return 0; diff -u --recursive --new-file v9/linux/net/ipv4/ip_input.c linux/net/ipv4/ip_input.c --- v9/linux/net/ipv4/ip_input.c Tue Aug 12 17:12:40 1997 +++ linux/net/ipv4/ip_input.c Wed Sep 17 12:00:47 1997 @@ -299,10 +299,13 @@ * Try to select closest alias device, if any. * net_alias_dev_rx32 returns main device if it * fails to found other. + * If successful, also incr. alias rx count. + * + * Only makes sense for unicasts - Thanks ANK. */ #ifdef CONFIG_NET_ALIAS - if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) { + if (skb->pkt_type == PACKET_HOST && iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) { skb->dev = dev = net_alias_dev_rx32(skb->dev, AF_INET, iph->saddr, iph->daddr); } #endif diff -u --recursive --new-file v9/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c --- v9/linux/net/ipv4/ip_output.c Tue Aug 12 11:30:35 1997 +++ linux/net/ipv4/ip_output.c Mon Sep 15 09:53:36 1997 @@ -983,8 +983,7 @@ } #endif #ifdef CONFIG_IP_ACCT - if(!offset) - ip_fw_chk(iph, dev, NULL, ip_acct_chain, 0, IP_FW_MODE_ACCT_OUT); + ip_fw_chk(iph, dev, NULL, ip_acct_chain, 0, IP_FW_MODE_ACCT_OUT); #endif offset -= (maxfraglen-fragheaderlen); fraglen = maxfraglen; diff -u --recursive --new-file v9/linux/net/ipv4/ipmr.c linux/net/ipv4/ipmr.c --- v9/linux/net/ipv4/ipmr.c Thu Nov 14 05:20:10 1996 +++ linux/net/ipv4/ipmr.c Mon Sep 15 10:08:30 1997 @@ -193,6 +193,8 @@ init_timer(&c->mfc_timer); c->mfc_timer.data=(long)c; c->mfc_timer.function=ipmr_cache_timer; + c->mfc_packets=0; + c->mfc_bytes=0; return c; } @@ -591,6 +593,7 @@ struct sioc_sg_req sr; struct sioc_vif_req vr; struct vif_device *vif; + struct mfc_cache *cl; switch(cmd) { @@ -617,6 +620,19 @@ if(err) return err; memcpy_fromfs(&sr,(void *)arg,sizeof(sr)); + cl=ipmr_cache_find(sr.src.s_addr,sr.grp.s_addr); + if(cl==NULL) + { + sr.pktcnt=0; + sr.bytecnt=0; + sr.wrong_if=0; + } + else + { + sr.pktcnt=cl->mfc_packets; + sr.bytecnt=cl->mfc_bytes; + sr.wrong_if=0; + } memcpy_tofs((void *)arg,&sr,sizeof(sr)); return 0; default: @@ -753,6 +769,8 @@ vif_table[vif].pkt_in++; vif_table[vif].bytes_in+=skb->len; + cache->mfc_packets++; + cache->mfc_bytes+=skb->len; /* * Forward the frame @@ -785,9 +803,7 @@ if(psend==-1) kfree_skb(skb, FREE_WRITE); else - { ipmr_queue_xmit(skb, &vif_table[psend], skb->dev, is_frag); - } } /* @@ -907,7 +923,7 @@ void ip_mr_init(void) { - printk(KERN_INFO "Linux IP multicast router 0.06.\n"); + printk(KERN_INFO "Linux IP multicast router 0.07.\n"); register_netdevice_notifier(&ip_mr_notifier); #ifdef CONFIG_PROC_FS proc_net_register(&(struct proc_dir_entry) { diff -u --recursive --new-file v9/linux/net/ipv4/route.c linux/net/ipv4/route.c --- v9/linux/net/ipv4/route.c Thu Sep 4 11:18:06 1997 +++ linux/net/ipv4/route.c Wed Sep 17 12:00:48 1997 @@ -46,6 +46,7 @@ * Andi Kleen : Don't send multicast addresses to * kerneld. * + * Juan Jose Ciarlante : Added ip_rt_dev * 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 @@ -1533,6 +1534,20 @@ * refcnt goes to zero, because nobody else will... */ if ( rt && (rt->rt_flags & RTF_NOTCACHED) && (!rt->rt_refcnt) ) rt_free(rt); +} + +/* + * Return routing dev for given address. + * Called by ip_alias module to avoid using ip_rt_route and + * generating hhs. + */ +struct device * ip_rt_dev(__u32 addr) +{ + struct fib_node *f; + f = fib_lookup(addr, NULL); + if (f) + return f->fib_info->fib_dev; + return NULL; } struct rtable * ip_rt_route(__u32 daddr, int local, struct device *dev) diff -u --recursive --new-file v9/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c --- v9/linux/net/ipv4/tcp_input.c Sun Aug 17 13:27:49 1997 +++ linux/net/ipv4/tcp_input.c Mon Sep 15 09:54:52 1997 @@ -34,6 +34,8 @@ * David S. Miller : New socket lookup architecture for ISS. * This code is dedicated to John Dyson. * Elliot Poger : Added support for SO_BINDTODEVICE. + * Willy Konynenberg : Transparent proxy adapted to new + * socket hash code. */ #include @@ -301,76 +303,41 @@ } #ifdef CONFIG_IP_TRANSPARENT_PROXY -#define secondlist(hpnum, sk, fpass) \ -({ struct sock *s1; if((hpnum) && !(sk) && (fpass)--) \ - s1 = tcp_bound_hash[tcp_bhashfn(hpnum)]; \ - else \ - s1 = (sk); \ - s1; \ -}) - -#define tcp_v4_proxy_loop_init(hnum, hpnum, sk, fpass) \ - secondlist((hpnum), tcp_bound_hash[tcp_bhashfn(hnum)],(fpass)) - -#define tcp_v4_proxy_loop_next(hnum, hpnum, sk, fpass) \ - secondlist((hpnum),(sk)->bind_next,(fpass)) - -struct sock *tcp_v4_proxy_lookup(unsigned short num, unsigned long raddr, - unsigned short rnum, unsigned long laddr, - unsigned long paddr, unsigned short pnum, +/* I am not entirely sure this is fully equivalent to the old lookup code, but it does + * look reasonable. WFK + */ +struct sock *tcp_v4_proxy_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, u32 paddr, u16 rport, struct device *dev) { - struct sock *s, *result = NULL; - int badness = -1; - unsigned short hnum = ntohs(num); - unsigned short hpnum = ntohs(pnum); - int firstpass = 1; - - /* This code must run only from NET_BH. */ - for(s = tcp_v4_proxy_loop_init(hnum, hpnum, s, firstpass); - s != NULL; - s = tcp_v4_proxy_loop_next(hnum, hpnum, s, firstpass)) { - if(s->num == hnum || s->num == hpnum) { - int score = 0; - if(s->dead && (s->state == TCP_CLOSE)) - continue; - if(s->rcv_saddr) { - if((s->num != hpnum || s->rcv_saddr != paddr) && - (s->num != hnum || s->rcv_saddr != laddr)) - continue; - score++; - } - if(s->daddr) { - if(s->daddr != raddr) - continue; - score++; - } - if(s->dummy_th.dest) { - if(s->dummy_th.dest != rnum) - continue; - score++; - } - if(s->bound_device) { - if (s->bound_device != dev) - continue; - score++; - } - if(score == 4 && s->num == hnum) { - result = s; - break; - } else if(score > badness && (s->num == hpnum || s->rcv_saddr)) { - result = s; - badness = score; - } - } + unsigned short hnum = ntohs(dport); + unsigned short hrnum = ntohs(rport); + struct sock *sk; + + /* Optimize here for direct hit, only listening connections can + * have wildcards anyways. It is assumed that this code only + * gets called from within NET_BH. + */ + sk = tcp_established_hash[tcp_hashfn(daddr, hnum, saddr, sport)]; + for(; sk; sk = sk->next) + if(sk->daddr == saddr && /* remote address */ + sk->dummy_th.dest == sport && /* remote port */ + sk->num == hnum && /* local port */ + sk->rcv_saddr == daddr && /* local address */ + ((sk->bound_device==NULL) || (sk->bound_device==dev)) ) + goto hit; /* You sunk my battleship! */ + /* If we don't match on a bound socket, try to find one explicitly listening + * on the remote address (a proxy bind). + */ + sk = tcp_v4_lookup_longway(daddr, hnum, dev); + /* If that didn't yield an exact match, look for a socket listening on the + * redirect port. + */ + if (!sk || sk->rcv_saddr != daddr) { + sk = tcp_v4_lookup_longway(paddr, hrnum, dev); } - return result; +hit: + return sk; } - -#undef secondlist -#undef tcp_v4_proxy_loop_init -#undef tcp_v4_proxy_loop_next - #endif /* @@ -2258,8 +2225,8 @@ struct tcphdr *th = (struct tcphdr *)(skb->h.raw + iph->ihl*4); struct sock *sk; - sk = tcp_v4_proxy_lookup(th->dest, iph->saddr, th->source, iph->daddr, - 0, 0, skb->dev); + sk = tcp_v4_lookup(iph->saddr, th->source, iph->daddr, th->dest, + skb->dev); if (!sk) return 0; /* 0 means accept all LOCAL addresses here, not all the world... */ @@ -2327,8 +2294,7 @@ #endif #ifdef CONFIG_IP_TRANSPARENT_PROXY if (skb->redirport) - sk = tcp_v4_proxy_lookup(th->dest, saddr, th->source, daddr, - dev->pa_addr, skb->redirport, dev); + sk = tcp_v4_proxy_lookup(saddr, th->source, daddr, th->dest, dev->pa_addr, skb->redirport, dev); else #endif sk = __tcp_v4_lookup(th, saddr, th->source, daddr, th->dest, dev); @@ -2643,11 +2609,17 @@ tcp_set_state(sk, TCP_CLOSE); sk->shutdown = SHUTDOWN_MASK; #ifdef CONFIG_IP_TRANSPARENT_PROXY - sk = tcp_v4_proxy_lookup(th->dest, saddr, th->source, daddr, - dev->pa_addr, skb->redirport, dev); -#else - sk = NULL; + /* What to do here? + * For the non-proxy case, this code is effectively almost a no-op, + * due to the sk = NULL. Is that intentional? If so, why shouldn't we + * do the same for the proxy case and get rid of some useless code? + */ + if (skb->redirport) + sk = tcp_v4_proxy_lookup(saddr, th->source, daddr, th->dest, + dev->pa_addr, skb->redirport, dev); + else #endif + sk = NULL; /* this is not really correct: we should check sk->users */ if (sk && sk->state==TCP_LISTEN) { diff -u --recursive --new-file v9/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c --- v9/linux/net/ipv4/tcp_output.c Fri Aug 15 12:23:23 1997 +++ linux/net/ipv4/tcp_output.c Wed Sep 17 12:03:45 1997 @@ -537,6 +537,7 @@ skb2->raddr=rt->rt_gateway; if (sk->state == TCP_SYN_SENT && sysctl_ip_dynaddr) ip_rewrite_addrs (sk, skb2, dev); + skb_pull(skb2,((unsigned char *)skb2->ip_hdr)-skb2->data); skb2->dev = dev; skb2->arp=1; if (rt->rt_hh) diff -u --recursive --new-file v9/linux/net/ipv4/udp.c linux/net/ipv4/udp.c --- v9/linux/net/ipv4/udp.c Tue Aug 12 11:30:35 1997 +++ linux/net/ipv4/udp.c Mon Sep 15 09:54:52 1997 @@ -53,6 +53,8 @@ * Last socket cache retained as it * does have a high hit rate. * Elliot Poger : Added support for SO_BINDTODEVICE. + * Willy Konynenberg : Transparent proxy adapted to new + * socket hash code. * * * This program is free software; you can redistribute it and/or @@ -313,79 +315,60 @@ } #ifdef CONFIG_IP_TRANSPARENT_PROXY -#define secondlist(hpnum, sk, fpass) \ -({ struct sock *s1; if(!(sk) && (fpass)--) \ - s1 = udp_hash[(hpnum) & (TCP_HTABLE_SIZE - 1)]; \ - else \ - s1 = (sk); \ - s1; \ -}) - -#define udp_v4_proxy_loop_init(hnum, hpnum, sk, fpass) \ - secondlist((hpnum), udp_hash[(hnum)&(TCP_HTABLE_SIZE-1)],(fpass)) - -#define udp_v4_proxy_loop_next(hnum, hpnum, sk, fpass) \ - secondlist((hpnum),(sk)->next,(fpass)) - -struct sock *udp_v4_proxy_lookup(unsigned short num, unsigned long raddr, - unsigned short rnum, unsigned long laddr, - unsigned long paddr, unsigned short pnum, +struct sock *udp_v4_proxy_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, u32 paddr, u16 rport, struct device *dev) { - struct sock *s, *result = NULL; + struct sock *hh[3], *sk, *result = NULL; + int i; int badness = -1; - unsigned short hnum = ntohs(num); - unsigned short hpnum = ntohs(pnum); - int firstpass = 1; + unsigned short hnum = ntohs(dport); + unsigned short hpnum = ntohs(rport); SOCKHASH_LOCK(); - for(s = udp_v4_proxy_loop_init(hnum, hpnum, s, firstpass); - s != NULL; - s = udp_v4_proxy_loop_next(hnum, hpnum, s, firstpass)) { - if(s->num == hnum || s->num == hpnum) { - int score = 0; - if(s->dead && (s->state == TCP_CLOSE)) - continue; - if(s->rcv_saddr) { - if((s->num != hpnum || s->rcv_saddr != paddr) && - (s->num != hnum || s->rcv_saddr != laddr)) - continue; - score++; - } - if(s->daddr) { - if(s->daddr != raddr) - continue; - score++; - } - if(s->dummy_th.dest) { - if(s->dummy_th.dest != rnum) - continue; - score++; - } - /* If this socket is bound to a particular interface, - * did the packet come in on it? */ - if(s->bound_device) { - if (s->bound_device != dev) + hh[0] = udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]; + hh[1] = udp_hash[hpnum & (UDP_HTABLE_SIZE - 1)]; + for (i = 0; i < 2; i++) { + for(sk = hh[i]; sk != NULL; sk = sk->next) { + if(sk->num == hnum || sk->num == hpnum) { + int score = 0; + if(sk->dead && (sk->state == TCP_CLOSE)) continue; - score++; - } - if(score == 4 && s->num == hnum) { - result = s; - break; - } else if(score > badness && (s->num == hpnum || s->rcv_saddr)) { - result = s; + if(sk->rcv_saddr) { + if((sk->num != hpnum || sk->rcv_saddr != paddr) && + (sk->num != hnum || sk->rcv_saddr != daddr)) + continue; + score++; + } + if(sk->daddr) { + if(sk->daddr != saddr) + continue; + score++; + } + if(sk->dummy_th.dest) { + if(sk->dummy_th.dest != sport) + continue; + score++; + } + /* If this socket is bound to a particular interface, + * did the packet come in on it? */ + if(sk->bound_device) { + if (sk->bound_device != dev) + continue; + score++; + } + if(score == 4 && sk->num == hnum) { + result = sk; + break; + } else if(score > badness && (sk->num == hpnum || sk->rcv_saddr)) { + result = sk; badness = score; + } } } } SOCKHASH_UNLOCK(); return result; } - -#undef secondlist -#undef udp_v4_proxy_loop_init -#undef udp_v4_proxy_loop_next - #endif static inline struct sock *udp_v4_mcast_next(struct sock *sk, @@ -950,8 +933,8 @@ struct udphdr *uh = (struct udphdr *)(skb->h.raw + iph->ihl*4); struct sock *sk; - sk = udp_v4_proxy_lookup(uh->dest, iph->saddr, uh->source, iph->daddr, - 0, 0, skb->dev); + sk = udp_v4_lookup(iph->saddr, uh->source, iph->daddr, uh->dest, + skb->dev); if (!sk) return 0; /* 0 means accept all LOCAL addresses here, not all the world... */ @@ -1098,8 +1081,8 @@ #endif #ifdef CONFIG_IP_TRANSPARENT_PROXY if(skb->redirport) - sk = udp_v4_proxy_lookup(uh->dest, saddr, uh->source, - daddr, dev->pa_addr, skb->redirport, dev); + sk = udp_v4_proxy_lookup(saddr, uh->source, daddr, uh->dest, + dev->pa_addr, skb->redirport, dev); else #endif sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, dev); diff -u --recursive --new-file v9/linux/net/netsyms.c linux/net/netsyms.c --- v9/linux/net/netsyms.c Tue Aug 12 11:30:39 1997 +++ linux/net/netsyms.c Wed Sep 17 12:00:48 1997 @@ -100,6 +100,7 @@ X(init_etherdev), X(ip_rt_route), + X(ip_rt_dev), X(icmp_send), X(ip_options_compile), X(ip_rt_put),