diff -u --recursive --new-file v1.3.90/linux/CREDITS linux/CREDITS --- v1.3.90/linux/CREDITS Wed Apr 17 09:06:31 1996 +++ linux/CREDITS Wed Apr 17 09:01:18 1996 @@ -665,6 +665,13 @@ S: D53424 Remagen S: Germany +N: Phil Lewis +E: beans@bucket.ualr.edu +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 + N: Martin von Loewis E: loewis@informatik.hu-berlin.de D: script binary format @@ -774,6 +781,15 @@ D: 8 bit XT hard disk driver for OMTI5520 S: Branderweg 4 S: D-91058 Erlangen +S: Germany + +N: Michael Meskes +E: meskes@informatik.rwth-aachen.de +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: Germany N: Craig Metz diff -u --recursive --new-file v1.3.90/linux/Documentation/Changes linux/Documentation/Changes --- v1.3.90/linux/Documentation/Changes Wed Apr 17 09:06:31 1996 +++ linux/Documentation/Changes Thu Apr 18 15:00:12 1996 @@ -2,7 +2,7 @@ important packages for Linux as well as instructions for newcomers to the 1.3.x series of kernels. -Last updated: Apr 15, 1996. +Last updated: Apr 17, 1996. Authors: Alessandro Sigala (ssigala@globalnet.it) and Chris Ricker (gt1355b@prism.gatech.edu). @@ -18,9 +18,9 @@ - Dynamic linker (ld.so) 1.7.14 - GNU CC 2.7.2 - Binutils 2.6.0.12 -- Linux C Library Stable: 5.2.18, Exp: 5.3.9 +- Linux C Library Stable: 5.2.18, Exp: 5.3.9, Alpha: 5.3.11 - Linux C++ Library 2.7.1.4 -- Termcap 2.0.7 +- Termcap 2.0.8 - Procps 0.99a - Gpm 1.06 - SysVinit 2.60 @@ -86,7 +86,7 @@ The Termcap Library =================== - The current Termcap release is 2.0.7. If you upgrade to this release + The current Termcap release is 2.0.8. If you upgrade to this release read the `README' file contained into the package to get some important information about the `tgetent' function changes! @@ -162,7 +162,7 @@ Linux's handling of named pipes changed (it now does it The Right Way instead of the SunOS way ;-). This broke some programs that depended on the SunOS behavior, most notably SysVinit. If you're running 2.59 -or earlier, you will probably get a weird error on shutdown in which +or earlier, you will probably get a wierd error on shutdown in which your computer shuts down fine but "INIT: error reading initrequest" or words to that effect scroll across your screen hundreds of times. To fix, upgrade to @@ -188,7 +188,7 @@ ln -s /usr/lib/terminfo/l/linux /usr/lib/terminfo/c/console Better yet, just get the latest official Linux termcap from -ftp://sunsite.unc.edu/pub/Linux/GCC/termcap-2.0.7.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/termcap-2.0.8.tar.gz Hdparm ====== @@ -353,7 +353,7 @@ Termcap Library =============== -ftp://sunsite.unc.edu/pub/Linux/GCC/termcap-2.0.7.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/termcap-2.0.8.tar.gz Modules utilities ================= diff -u --recursive --new-file v1.3.90/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v1.3.90/linux/Documentation/Configure.help Wed Apr 17 09:06:31 1996 +++ linux/Documentation/Configure.help Wed Apr 17 09:01:18 1996 @@ -2196,6 +2196,23 @@ Multiple-Ethernet-mini-HOWTO, available from sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. +DECchip Tulip (dc21x4x) PCI support +CONFIG_DEC_ELCP + This driver is developed for the SMC EtherPower series ethernet + cards and also works with the DECchip 21040/21041/21140 + (Tulip series) based other cards. If you have a network card of + this type, say Y and read the Ethernet-HOWTO, available via ftp + (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. More + specific information is contained in + Documentation/networking/tulip.txt. This driver is also available + as a module ( = code which can be inserted in and removed from + the running kernel whenever you want). If you want to compile + it as a module, say M here and read Documentation/modules.txt as + well as Documentation/networking/net-modules.txt. + ****************************************************************** + If your card is NOT SMC EtherPower 10/100 PCI (smc9332dst), + you can try the de4x5.c driver. + ICL EtherTeam 16i/32 support CONFIG_ETH16I If you have a network (ethernet) card of this type, say Y and read @@ -2751,12 +2768,16 @@ This selects whether you want to include the driver for the standard serial ports. People who might say N here are those that are setting up dedicated ethernet WWW/ftp servers, or users that have - one of the various bus mice instead of a serial mouse. Note that - the Cyclades and Stallion drivers do not need this driver to be - built in for them to work. They are completely independent of each - other. Most people will say Y here however, so that they can use - serial mice, modems and similar devices connecting to the standard - serial ports. + one of the various bus mice instead of a serial mouse. (Note that + the Cyclades and Stallion drivers do not need this driver built in + for them to work. They are completely independent of each other.) + If you want to compile this driver as a module, say M here and read + Documentation/modules.txt. [WARNING: Do not compile this driver as + a module if you are using non-standard serial ports, since the + configuration information will be lost when kerneld automatically + unloads the driver. This limitation may be lifted in the future.] + Most people will say Y or M here, so that they can use serial mice, + modems and similar devices connecting to the standard serial ports. Digiboard PC/X Support CONFIG_DIGI diff -u --recursive --new-file v1.3.90/linux/Documentation/digiboard.txt linux/Documentation/digiboard.txt --- v1.3.90/linux/Documentation/digiboard.txt Fri Apr 12 15:51:43 1996 +++ linux/Documentation/digiboard.txt Wed Apr 17 08:12:58 1996 @@ -21,25 +21,25 @@ Supporting Tools: ----------------- -Some tools and more detailed up to date information can be found at +Some tools and more detailed information can be found at ftp://ftp.fuller.edu/Linux/digi +WARNING: Most of the stuff available right now uses the WRONG Major Device +numbers and the wrong call out devices. Be careful and check them first. +Better not use any of the software in that directory if you run a recent +1.3.X Kernel or later! + The "ditty" tool described in the Digiboard Manuals for other Unixes is also available. Currently the Linux MAKEDEV command does not support generating the Digiboard Devices. Use the following script to generate the devices: -WARNING: Most of the stuff available right now uses the WRONG Major Device -numbers and is severely outdated. Be careful and check them first. -Better not use any of the software in that directory if you run a recent -1.3.X Kernel! - ------------------ mkdigidev begin #!/bin/sh # # Script to create Digiboard Devices -# Christoph Lameter, April 6, 1996 +# Christoph Lameter, April 16, 1996 # # Usage: # mkdigidev [] @@ -60,14 +60,53 @@ for c in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do name=`expr $boardnum \* 16 + $c` - mknod /dev/ttyd$name c $DIGIMAJOR $name + mknod /dev/cud$name c $DIGIMAJOR $name mknod /dev/ttyD$name c $DIGICUMAJOR $name done boardnum=`expr $boardnum + 1` done ------------------ mkdigidev end +or apply the following patch to /dev/MAKEDEV and do a +make digi +----- MAKDEV Patch +--- /dev/MAKEDEV Sun Aug 13 15:48:23 1995 ++++ MAKEDEV Tue Apr 16 17:53:27 1996 +@@ -120,7 +120,7 @@ + while [ $# -ne 0 ] + do + case "$1" in +- mem|tty|ttyp|cua|cub) ;; ++ mem|tty|ttyp|cua|cub|cud) ;; + hd) echo hda hdb hdc hdd ;; + xd) echo xda xdb ;; + fd) echo fd0 fd1 ;; +@@ -140,6 +140,7 @@ + dcf) echo dcf ;; + pcmcia) ;; # taken care of by its own driver + ttyC) echo cyclades ;; ++ ttyD) echo digi ;; + *) echo "$0: don't know what \"$1\" is" >&2 ;; + esac + shift +@@ -208,6 +209,15 @@ + do + makedev ttyC$i c $major1 `expr 32 + $i` $tty + makedev cub$i c $major2 `expr 32 + $i` $dialout ++ done ++ ;; ++ digi) ++ major1=`Major ttyD` || continue ++ major2=`Major cud` || continue ++ for i in 0 1 2 3 4 5 6 7 # 8 9 10 11 12 13 14 15 ++ do ++ makedev ttyD$i c $major1 `expr 32 + $i` $tty ++ makedev cud$i c $major2 `expr 32 + $i` $dialout + done + ;; + par[0-2]) +----- End Makedev patch -The ttyd devices behave like the /dev/cua?? devices +The /dev/cud?? devices behave like the /dev/cua?? devices and the ttyD devices are like the /dev/ttyS?? devices. Sources of Information @@ -80,7 +119,7 @@ (Write e-mail to that address to subscribe. Common ListServ commands work. Archive of messages available) -Christoph Lameter (clameter@fuller.edu) 6. April 1996. +Christoph Lameter (clameter@fuller.edu) 16. April 1996. ----------------------------------------------------------------------------- diff -u --recursive --new-file v1.3.90/linux/Documentation/networking/tulip.txt linux/Documentation/networking/tulip.txt --- v1.3.90/linux/Documentation/networking/tulip.txt Thu Jan 1 02:00:00 1970 +++ linux/Documentation/networking/tulip.txt Wed Apr 17 08:32:47 1996 @@ -0,0 +1,110 @@ + Tulip ethernet card driver + +The Tulip driver is developed by Donald Becker and changed by +Takashi Manabe. This driver is designed to work with PCI ethernet +cards which use the DECchip DC21x4x family. This driver hopefully +works with all of 1.2.x and 1.3.x kernels, but I tested only +with 1.2.13, 1.3.39, 1.3.49, 1.3.52, 1.3.57 and later. + +Hopefully, the de4x5.c driver will support all cards supported +by the tulip.c driver. However, the SMC's 9332dst card and some +cards do not work with the de4x5.c driver. So, if your card is +not a 9332dst, please try the de4x5.c driver first. + +Success List +============ + ++-------------------------------------+-----------+-------------+ +|vendor/card |chip |system | ++-------------------------------------+-----------+-------------+ +|SMC | | | +| EtherPower 10 PCI(8432T/8432BT) |21040/21041|Pentium | ++-------------------------------------+-----------+-------------+ +|SMC | | | +| EtherPower 10/100 PCI(9332DST) |21140 |Pentium/UDB | ++-------------------------------------+-----------+-------------+ +|DEC | | | +| EtherWorks 100/10 PCI(DE500-XA) |21140 |Pentium | ++-------------------------------------+-----------+-------------+ +|DEC | | | +| EtherWorks 10 PCI(DE450) |21041 |Pentium | ++-------------------------------------+-----------+-------------+ +|DEC | | | +| QSILVER's |21040 |UDB | ++-------------------------------------+-----------+-------------+ +|ZNYX | | | +| 312 etherarray |21040 |Pentium | ++-------------------------------------+-----------+-------------+ +|Allied Telesis | | | +| LA100PCI-T |21140 |Pentium/UDB | ++-------------------------------------+-----------+-------------+ +|Danpex ('Planet Japan' in Japan?) | | | +| EN-9400 |21040 |Pentium | ++-------------------------------------+-----------+-------------+ +|Cogent | | | +| EM110 |21140 |Pentium | ++-------------------------------------+-----------+-------------+ + +Pentium: PCI machine with Pentium CPU +UDB: Universal Desktop Box(aka Multia) with Alpha 21066 CPU + +Known bug(s) +============ +This driver's media detection is very simple and sometimes +it causes serious problem. The driver automatically switches +media when it causes timeout. If you want to speficy or to fix +a media; + +- Modify TULIP_PORT in tulip.c, line 33. +- Uncommennt the definition of TULIP_FIX_PORT in tulip.c, line 40. + +or + +- Use patched ifconfig command and specify 'link='. The patch + against ifconfig.c in net-tools-1.3.50-BETA6e is included in + this file. + +Thanks +====== + +o becker@CESDIS.gsfc.nasa.gov (author of the tulip.c driver) +o davies@wanton.lkg.dec.com (author of the de4x5.c driver) + +o siekas@mailhost.tcs.tulane.edu + +o jheiss@calvin.caltech.edu (providing information about smc8432 card) +o goto@plathome.co.jp (lending me a DE450 card) +o ted@physics.ucsb.edu +o pmheuvel@xs4all.nl +o hjl@lucon.org (EN-9400) +o niles@axp745.gsfc.nasa.gov (ZNYX312) +o pkc@scs.carleton.ca (EM110) +o and testers... + +----------------------------------------------------------------------- +*** ifconfig.c-dist Wed Jan 17 07:25:36 1996 +--- ifconfig.c Tue Apr 9 15:24:25 1996 +*************** +*** 765,770 **** +--- 766,786 ---- + continue; + } + ifr.ifr_map.irq = atoi(*spp); ++ if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { ++ fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno)); ++ goterr = 1; ++ } ++ spp++; ++ continue; ++ } ++ ++ if (!strcmp(*spp, "link")) { ++ if (*++spp == NULL) usage(); ++ if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) { ++ goterr = 1; ++ continue; ++ } ++ ifr.ifr_map.port = atoi(*spp); + if (ioctl(skfd, SIOCSIFMAP, &ifr) < 0) { + fprintf(stderr, "SIOCSIFMAP: %s\n", strerror(errno)); + goterr = 1; diff -u --recursive --new-file v1.3.90/linux/MAINTAINERS linux/MAINTAINERS --- v1.3.90/linux/MAINTAINERS Wed Apr 17 09:06:31 1996 +++ linux/MAINTAINERS Thu Apr 18 14:56:45 1996 @@ -102,6 +102,18 @@ L: linux-scsi@vger.rutgers.edu S: Maintained +EATA ISA/EISA SCSI DRIVER +P: Dario Ballabio +M: dario@milano.europe.dg.com +L: linux-kernel@vger.rutgers.edu +S: Maintained + +U14-34F SCSI DRIVER +P: Dario Ballabio +M: dario@milano.europe.dg.com +L: linux-kernel@vger.rutgers.edu +S: Maintained + EATA-DMA SCSI DRIVER P: Michael Neuffer M: mike@i-Connect.Net @@ -205,7 +217,7 @@ L: samba@listproc.anu.edu.au S: Odd Fixes -SMP: +SMP: (except SPARC) P: Alan Cox M: smp-patches@lxorguk.ukuu.org.uk L: linux-smp@vger.rutgers.edu @@ -227,6 +239,18 @@ P: Christoph Lameter M: clameter@fuller.edu L: digiboard@list.fuller.edu +S: Maintained + +MOUSE AND MISC DEVICES [GENERAL] +P: Alessandro Rubini +M: rubini@ipvvis.unipv.it +L: linux-kernel@vger.rutgers.edu +S: Mantained + +MENUCONFIG: +P: William Roadcap +M: roadcapw@cfw.com +L: linux-kernel@vger.rutgers.edu S: Maintained REST: diff -u --recursive --new-file v1.3.90/linux/Makefile linux/Makefile --- v1.3.90/linux/Makefile Mon Apr 15 12:20:17 1996 +++ linux/Makefile Tue Apr 16 19:52:36 1996 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 89 +SUBLEVEL = 91 ARCH = i386 diff -u --recursive --new-file v1.3.90/linux/arch/alpha/kernel/alcor.c linux/arch/alpha/kernel/alcor.c --- v1.3.90/linux/arch/alpha/kernel/alcor.c Wed Feb 28 15:48:17 1996 +++ linux/arch/alpha/kernel/alcor.c Wed Apr 17 09:01:18 1996 @@ -410,6 +410,20 @@ hwrpb->max_asn = MAX_ASN; } + /* + * Finally, clear the CIA_CFG register, which gets used + * for PCI Config Space accesses. That is the way + * we want to use it, and we do not want to depend on + * what ARC or SRM might have left behind... + */ + { +#if 0 + unsigned int cia_cfg = *((unsigned int *)ALCOR_IOC_CFG); mb(); + if (cia_cfg) printk("alcor_init: CFG was 0x%x\n", cia_cfg); +#endif + *((unsigned int *)ALCOR_IOC_CFG) = 0; mb(); + } + return mem_start; } diff -u --recursive --new-file v1.3.90/linux/arch/alpha/kernel/apecs.c linux/arch/alpha/kernel/apecs.c --- v1.3.90/linux/arch/alpha/kernel/apecs.c Sun Mar 31 00:13:16 1996 +++ linux/arch/alpha/kernel/apecs.c Wed Apr 17 09:01:18 1996 @@ -453,6 +453,22 @@ hwrpb->chksum = sum; } #endif /* CONFIG_ALPHA_CABRIOLET */ + + /* + * Finally, clear the HAXR2 register, which gets used + * for PCI Config Space accesses. That is the way + * we want to use it, and we do not want to depend on + * what ARC or SRM might have left behind... + */ + { +#if 0 + unsigned int haxr2 = *((unsigned int *)APECS_IOC_HAXR2); mb(); + if (haxr2) printk("apecs_init: HAXR2 was 0x%x\n", haxr2); +#endif + *((unsigned int *)APECS_IOC_HAXR2) = 0; mb(); + } + + return mem_start; } diff -u --recursive --new-file v1.3.90/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c --- v1.3.90/linux/arch/alpha/kernel/bios32.c Fri Apr 12 15:51:45 1996 +++ linux/arch/alpha/kernel/bios32.c Wed Apr 17 09:01:18 1996 @@ -25,6 +25,10 @@ */ #include +#if 0 +#define DEBUG_PRINT_DEVS 1 +#endif + #ifndef CONFIG_PCI int pcibios_present(void) @@ -265,6 +269,10 @@ pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND, cmd | PCI_COMMAND_MASTER); +#if DEBUG_PRINT_DEVS +printk("layout_dev: bus %d slot 0x%x VID 0x%x DID 0x%x class 0x%x\n", + bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class); +#endif } @@ -274,6 +282,10 @@ struct pci_bus *child; struct pci_dev *dev; +#if DEBUG_PRINT_DEVS +printk("layout_bus: starting bus %d\n", bus->number); +#endif + if (!bus->devices && !bus->children) return; @@ -302,6 +314,10 @@ /* * Allocate space to each device: */ +#if DEBUG_PRINT_DEVS +printk("layout_bus: starting bus %d devices\n", bus->number); +#endif + for (dev = bus->devices; dev; dev = dev->sibling) { if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) { layout_dev(dev); @@ -310,6 +326,10 @@ /* * Recursively allocate space for all of the sub-buses: */ +#if DEBUG_PRINT_DEVS +printk("layout_bus: starting bus %d children\n", bus->number); +#endif + for (child = bus->children; child; child = child->next) { layout_bus(child); } @@ -560,9 +580,9 @@ } } - if (ide_base) { - enable_ide(ide_base); - } + } + if (ide_base) { + enable_ide(ide_base); } } @@ -732,7 +752,7 @@ */ const unsigned int route_tab = 0x0b0a090f; unsigned int level_bits; - unsigned char pin; + unsigned char pin, slot; int pirq; pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60, route_tab); @@ -742,23 +762,41 @@ */ level_bits = inb(0x4d0) | (inb(0x4d1) << 8); for (dev = pci_devices; dev; dev = dev->next) { + if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) + continue; dev->irq = 0; if (dev->bus->number != 0) { - printk("bios32.sio_fixup: don't know how to fixup devices on bus %d\n", - dev->bus->number); - continue; - } - if (PCI_SLOT(dev->devfn) < 6 || - PCI_SLOT(dev->devfn) >= 6 + sizeof(pirq_tab)/sizeof(pirq_tab[0])) - { - printk("bios32.sio_fixup: " - "weird, found device %04x:%04x in non-existent slot %d!!\n", - dev->vendor, dev->device, PCI_SLOT(dev->devfn)); - continue; + struct pci_dev *curr = dev ; + /* read the pin and do the PCI-PCI bridge + interrupt pin swizzle */ + pcibios_read_config_byte(dev->bus->number, dev->devfn, + PCI_INTERRUPT_PIN, &pin); + /* cope with 0 */ + if (pin == 0) pin = 1 ; + /* follow the chain of bridges, swizzling as we go */ + do { + /* swizzle */ + pin = bridge_swizzle(pin, PCI_SLOT(curr->devfn)) ; + /* move up the chain of bridges */ + curr = curr->bus->self ; + } while (curr->bus->self) ; + /* The slot is the slot of the last bridge. */ + slot = PCI_SLOT(curr->devfn) ; + } else { + /* work out the slot */ + slot = PCI_SLOT(dev->devfn) ; + /* read the pin */ + pcibios_read_config_byte(dev->bus->number, dev->devfn, + PCI_INTERRUPT_PIN, &pin); } - pcibios_read_config_byte(dev->bus->number, dev->devfn, - PCI_INTERRUPT_PIN, &pin); - pirq = pirq_tab[PCI_SLOT(dev->devfn) - 6][pin]; + + pirq = pirq_tab[slot - 6][pin]; + +#if DEBUG_PRINT_DEVS +printk("sio_fixup: bus %d slot 0x%x VID 0x%x DID 0x%x int_slot 0x%x int_pin 0x%x, pirq 0x%x\n", + dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, slot, pin, pirq); +#endif + if (pirq < 0) { continue; } @@ -790,6 +828,7 @@ * these registers must be accessed byte-wise. outw() doesn't * work. */ + level_bits |= (inb(0x4d0) | (inb(0x4d1) << 8)); outb((level_bits >> 0) & 0xff, 0x4d0); outb((level_bits >> 8) & 0xff, 0x4d1); enable_ide(0x26e); diff -u --recursive --new-file v1.3.90/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c --- v1.3.90/linux/arch/alpha/kernel/signal.c Mon Mar 11 09:39:33 1996 +++ linux/arch/alpha/kernel/signal.c Thu Apr 18 14:00:23 1996 @@ -194,7 +194,9 @@ put_fs_quad(0x43ecf40047de0410, sc->sc_retcode+0); put_fs_quad(0x0000000000000083, sc->sc_retcode+1); regs->r26 = (unsigned long) sc->sc_retcode; - regs->r16 = signr; + regs->r16 = signr; /* a0: signal number */ + regs->r17 = 0; /* a1: exception code; see gentrap.h */ + regs->r18 = (unsigned long) sc; /* a2: sigcontext pointer */ *fp = sc; } diff -u --recursive --new-file v1.3.90/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c --- v1.3.90/linux/arch/i386/kernel/signal.c Wed Apr 17 09:06:31 1996 +++ linux/arch/i386/kernel/signal.c Wed Apr 17 14:04:29 1996 @@ -4,6 +4,8 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ +#include + #include #include #include @@ -42,6 +44,42 @@ } /* + * FIXME. We don't currently restore emulator state + */ +#define restore_i387_soft(x) do { } while (0) + +static inline void restore_i387_hard(struct _fpstate *buf) +{ +#ifdef __SMP__ + if (current->flags & PF_USEDFPU) { + stts(); + } +#else + if (current == last_task_used_math) { + last_task_used_math = NULL; + stts(); + } +#endif + current->used_math = 1; + current->flags &= PF_USEDFPU; + memcpy_fromfs(¤t->tss.i387.hard, buf, sizeof(*buf)); +} + +static void restore_i387(struct _fpstate *buf) +{ +#ifndef CONFIG_MATH_EMULATION + restore_i387_hard(buf); +#else + if (hard_math) { + restore_i387_hard(buf); + return; + } + restore_i387_soft(buf); +#endif +} + + +/* * This sets regs->esp even though we don't actually use sigstacks yet.. */ asmlinkage int sys_sigreturn(unsigned long __unused) @@ -73,12 +111,56 @@ regs->eflags &= ~0x40DD5; regs->eflags |= context.eflags & 0x40DD5; regs->orig_eax = -1; /* disable syscall checks */ + if (context.fpstate) { + struct _fpstate * buf = context.fpstate; + if (verify_area(VERIFY_READ, buf, sizeof(*buf))) + goto badframe; + restore_i387(buf); + } return context.eax; badframe: do_exit(SIGSEGV); } /* + * FIXME. We currently don't save 387 state if we use emulation + */ +#define save_i387_soft(x) NULL + +static inline struct _fpstate * save_i387_hard(struct _fpstate * buf) +{ +#ifdef __SMP__ + if (current->flags & PF_USEDFPU) { + __asm__ __volatile__("fnsave %0":"=m" (current->tss.i387.hard)); + stts(); + current->flags &= PF_USEDFPU; + } +#else + if (current == last_task_used_math) { + __asm__ __volatile__("fnsave %0":"=m" (current->tss.i387.hard)); + last_task_used_math = NULL; + __asm__ __volatile__("fwait"); /* not needed on 486+ */ + stts(); + } +#endif + current->tss.i387.hard.status = current->tss.i387.hard.swd; + memcpy_tofs(buf, ¤t->tss.i387.hard, sizeof(*buf)); + current->used_math = 0; + return buf; +} + +static struct _fpstate * save_i387(struct _fpstate * buf) +{ +#ifndef CONFIG_MATH_EMULATION + return save_i387_hard(buf); +#else + if (hard_math) + return save_i387_hard(buf); + return save_i387_soft(buf); +#endif +} + +/* * Set up a signal frame... Make the stack look the way iBCS2 expects * it to look. */ @@ -91,8 +173,8 @@ frame = (unsigned long *) regs->esp; if (regs->ss != USER_DS && sa->sa_restorer) frame = (unsigned long *) sa->sa_restorer; - frame -= 32; - if (verify_area(VERIFY_WRITE,frame,32*4)) + frame -= 64; + if (verify_area(VERIFY_WRITE,frame,64*4)) do_exit(SIGSEGV); /* set up the "normal" stack seen by the signal handler (iBCS2) */ @@ -122,7 +204,7 @@ put_user(regs->eflags, frame+18); put_user(regs->esp, frame+19); put_user(regs->ss, frame+20); - put_user(NULL,frame+21); + put_user(save_i387((struct _fpstate *)(frame+32)),frame+21); /* non-iBCS2 extensions.. */ put_user(oldmask, frame+22); put_user(current->tss.cr2, frame+23); diff -u --recursive --new-file v1.3.90/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- v1.3.90/linux/arch/i386/kernel/traps.c Fri Apr 12 15:51:46 1996 +++ linux/arch/i386/kernel/traps.c Thu Apr 18 14:09:12 1996 @@ -241,37 +241,36 @@ */ void math_error(void) { - struct i387_hard_struct * env; + struct task_struct * task; + + clts(); #ifdef __SMP__ - env=¤t->tss.i387.hard; - send_sig(SIGFPE, current, 1); + task = current; +#else + task = last_task_used_math; + last_task_used_math = NULL; + if (!task) { + __asm__("fnclex"); + return; + } +#endif /* * Save the info for the exception handler */ - __asm__ __volatile__("fnsave %0":"=m" (*env)); - current->flags&=~PF_USEDFPU; + __asm__ __volatile__("fnsave %0":"=m" (task->tss.i387.hard)); + task->flags&=~PF_USEDFPU; + + send_sig(SIGFPE, task, 1); + task->tss.trap_no = 16; + task->tss.error_code = 0; + /* - * Cause a trap if they use the FPU again. + * Give the process a clean slate next time they use + * the FPU (and if they haven't accepted the SIGFP before + * that, it's their problem..) */ stts(); -#else - clts(); - if (!last_task_used_math) { - __asm__("fnclex"); - return; - } - env = &last_task_used_math->tss.i387.hard; - send_sig(SIGFPE, last_task_used_math, 1); - last_task_used_math->tss.trap_no = 16; - last_task_used_math->tss.error_code = 0; - __asm__ __volatile__("fnsave %0":"=m" (*env)); - last_task_used_math = NULL; - stts(); - env->fcs = (env->swd & 0x0000ffff) | (env->fcs & 0xffff0000); - env->fos = env->twd; - env->swd &= 0xffff3800; - env->twd = 0xffffffff; -#endif + task->used_math = 0; } asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code) @@ -289,7 +288,8 @@ */ asmlinkage void math_state_restore(void) { -#ifdef __SMP__ + __asm__ __volatile__("clts"); /* Allow maths ops (or we recurse) */ + /* * SMP is actually simpler than uniprocessor for once. Because * we can't pull the delayed FPU switching trick Linus does @@ -297,10 +297,17 @@ * set the flag. switch_to() will always save the state in * case we swap processors. We also don't use the coprocessor * timer - IRQ 13 mode isn't used with SMP machines (thank god). - * - * If this actually works it will be a miracle however */ - __asm__ __volatile__("clts"); /* Allow maths ops (or we recurse) */ +#ifndef __SMP__ + if (last_task_used_math == current) + return; + if (last_task_used_math) + __asm__("fnsave %0":"=m" (last_task_used_math->tss.i387)); + else + __asm__("fnclex"); + last_task_used_math = current; +#endif + if(current->used_math) __asm__("frstor %0": :"m" (current->tss.i387)); else @@ -312,25 +319,6 @@ current->used_math = 1; } current->flags|=PF_USEDFPU; /* So we fnsave on switch_to() */ -#else - __asm__ __volatile__("clts"); - if (last_task_used_math == current) - return; - timer_table[COPRO_TIMER].expires = jiffies+50; - timer_active |= 1<tss.i387)); - else - __asm__("fnclex"); - last_task_used_math = current; - if (current->used_math) { - __asm__("frstor %0": :"m" (current->tss.i387)); - } else { - __asm__("fninit"); - current->used_math=1; - } - timer_active &= ~(1< #endif -#include +#include #define MAJOR_NR MD_MAJOR #define MD_DRIVER diff -u --recursive --new-file v1.3.90/linux/drivers/char/ChangeLog linux/drivers/char/ChangeLog --- v1.3.90/linux/drivers/char/ChangeLog Fri Apr 12 15:51:51 1996 +++ linux/drivers/char/ChangeLog Wed Apr 17 09:01:18 1996 @@ -1,3 +1,33 @@ +Mon Apr 1 10:22:01 1996 + + * serial.c (rs_close): Cleaned up modularization changes. + Remove code which forced line discpline back to N_TTY + this is done in the tty upper layers, and there's no + reason to do it here. (Making this change also + removed the requirement that the serial module access + the internal kernel symbol "ldiscs".) + + * tty_io.c (tty_init): Formally register a tty_driver entry for + /dev/tty (device 4, 0) and /dev/console (device 5, 0). + This guarantees that major device numbers 4 and 5 will be + reserved for the tty subsystem (as they have to be because + of /dev/tty and /dev/console). Removed tty_regdev, as + this interface is no longer necessary. + +Sun Mar 17 20:42:47 GMT 1996 + + * serial.c : modularisation (changes in linux/fs/device.c allow + kerneld to automatically load the serial module). + + * Makefile, Config.in : serial modularisation adds. + + * tty_io.c : tty_init_ctty used by to register "cua" driver just + for the /dev/tty device (5,0). Added tty_regdev. + + * serial.c (shutdown, rs_ioctl) : when port shuts down wakeup processes + waiting on delta_msr_wait. The TIOCMIWAIT ioctl returns EIO + if no change was done since the time of call. + Sat Mar 16 14:33:13 1996 * tty_io.c (disassociate_ctty): If disassociate_ctty is called by diff -u --recursive --new-file v1.3.90/linux/drivers/char/Config.in linux/drivers/char/Config.in --- v1.3.90/linux/drivers/char/Config.in Mon Apr 15 12:20:17 1996 +++ linux/drivers/char/Config.in Wed Apr 17 09:17:46 1996 @@ -4,7 +4,7 @@ mainmenu_option next_comment comment 'Character devices' -bool 'Standard/generic serial support' CONFIG_SERIAL +tristate 'Standard/generic serial support' CONFIG_SERIAL bool 'Digiboard PC/X Support' CONFIG_DIGI tristate 'Cyclades async mux support' CONFIG_CYCLADES bool 'Stallion multiport serial support' CONFIG_STALDRV diff -u --recursive --new-file v1.3.90/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v1.3.90/linux/drivers/char/Makefile Mon Apr 15 12:20:17 1996 +++ linux/drivers/char/Makefile Wed Apr 17 09:17:46 1996 @@ -25,7 +25,11 @@ defkeymap.o consolemap.o selection.o ifeq ($(CONFIG_SERIAL),y) -L_OBJS += serial.o +LX_OBJS += serial.o +else + ifeq ($(CONFIG_SERIAL),m) + MX_OBJS += serial.o + endif endif ifeq ($(CONFIG_DIGI),y) diff -u --recursive --new-file v1.3.90/linux/drivers/char/README.stallion linux/drivers/char/README.stallion --- v1.3.90/linux/drivers/char/README.stallion Wed Mar 27 08:19:28 1996 +++ linux/drivers/char/README.stallion Wed Apr 17 15:08:57 1996 @@ -26,9 +26,9 @@ The following ftp sites (and their mirrors) definitely have the stallion driver utility package: ftp.stallion.com, tsx-11.mit.edu, sunsite.unc.edu. -ftp.stallion.com:/drivers/ata5/Linux/stallion-1.0.7.tar.gz -tsx-11.mit.edu:/pub/linux/BETA/serial/stallion/stallion-1.0.7.tar.gz -sunsite.unc.edu:/pub/Linux/kernel/patches/serial/stallion-1.0.7.tar.gz +ftp.stallion.com:/drivers/ata5/Linux/stallion-1.1.0.tar.gz +tsx-11.mit.edu:/pub/linux/BETA/serial/stallion/stallion-1.1.0.tar.gz +sunsite.unc.edu:/pub/Linux/kernel/patches/serial/stallion-1.1.0.tar.gz If you are using the EasyIO or EasyConnection 8/32 boards then you don't need this package. Although it does have a handy script to create the @@ -250,11 +250,11 @@ possible, most system utilities should work as they do for the standard COM ports. Most importantly "stty" works as expected and "setserial" can be also be used (excepting the ability to auto-configure the I/O and IRQ -addresses of boards). Higher baud rates are supported in the -usual fashion through setserial or using the CBAUDEX extensions. Note that -the EasyIO and EasyConnection (all types) support 57600 and 115200 baud. The -older boards including ONboard, Brumby and the original Stallion support a -maximum baud rate of 38400. +addresses of boards). Higher baud rates are supported in the usual fashion +through setserial or using the CBAUDEX extensions. Note that the EasyIO and +EasyConnection (all types) support 57600 and 115200 baud. The older boards +including ONboard, Brumby and the original Stallion support a maximum baud +rate of 38400. If you are unfamiliar with how to use serial ports, then get the Serial-HOWTO by Greg Hankins. It will explain everything you need to know! @@ -280,12 +280,12 @@ they can be very difficult to get into a system. If you have 16 Mb of RAM then you have no choice but to put them somewhere in the 640K -> 1Mb range. ONboards require 64K, so typically 0xd0000 is good, or 0xe0000 on some -systems. If you have an original Stallion board, "V4.0" or Rev.O, -then you need a 64K memory address space, so again 0xd0000 and 0xe0000 are -good. Older Stallion boards are a much bigger problem. They need 128K of -address space and must be on a 128K boundary. If you don't have a VGA card -then 0xc0000 might be usable - there is really no other place you can put -them below 1Mb. +systems. If you have an original Stallion board, "V4.0" or Rev.O, then you +need a 64K memory address space, so again 0xd0000 and 0xe0000 are good. +Older Stallion boards are a much bigger problem. They need 128K of address +space and must be on a 128K boundary. If you don't have a VGA card then +0xc0000 might be usable - there is really no other place you can put them +below 1Mb. Both the ONboard and old Stallion boards can use higher memory addresses as well, but you must have less than 16Mb of RAM to be able to use them. Usual diff -u --recursive --new-file v1.3.90/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c --- v1.3.90/linux/drivers/char/apm_bios.c Mon Apr 8 19:01:43 1996 +++ linux/drivers/char/apm_bios.c Wed Apr 17 09:01:18 1996 @@ -319,7 +319,6 @@ #ifdef CONFIG_APM_CPU_IDLE static int clock_slowed = 0; #endif -static int apm_major; static int suspends_pending = 0; static int standbys_pending = 0; diff -u --recursive --new-file v1.3.90/linux/drivers/char/digi.h linux/drivers/char/digi.h --- v1.3.90/linux/drivers/char/digi.h Wed Apr 3 16:06:55 1996 +++ linux/drivers/char/digi.h Wed Apr 17 08:12:58 1996 @@ -1,41 +1,41 @@ /* Definitions for DigiBoard ditty(1) command. */ #if !defined(TIOCMODG) -#define TIOCMODG ('d'<<8) | 250 /* get modem ctrl state */ -#define TIOCMODS ('d'<<8) | 251 /* set modem ctrl state */ +#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */ +#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */ #endif #if !defined(TIOCMSET) -#define TIOCMSET ('d'<<8) | 252 /* set modem ctrl state */ -#define TIOCMGET ('d'<<8) | 253 /* set modem ctrl state */ +#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */ +#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */ #endif #if !defined(TIOCMBIC) -#define TIOCMBIC ('d'<<8) | 254 /* set modem ctrl state */ -#define TIOCMBIS ('d'<<8) | 255 /* set modem ctrl state */ +#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */ +#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */ #endif #if !defined(TIOCSDTR) -#define TIOCSDTR ('e'<<8) | 0 /* set DTR */ -#define TIOCCDTR ('e'<<8) | 1 /* clear DTR */ +#define TIOCSDTR (('e'<<8) | 0) /* set DTR */ +#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */ #endif /************************************************************************ * Ioctl command arguments for DIGI parameters. ************************************************************************/ -#define DIGI_GETA ('e'<<8) | 94 /* Read params */ +#define DIGI_GETA (('e'<<8) | 94) /* Read params */ -#define DIGI_SETA ('e'<<8) | 95 /* Set params */ -#define DIGI_SETAW ('e'<<8) | 96 /* Drain & set params */ -#define DIGI_SETAF ('e'<<8) | 97 /* Drain, flush & set params */ +#define DIGI_SETA (('e'<<8) | 95) /* Set params */ +#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */ +#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */ -#define DIGI_GETFLOW ('e'<<8) | 99 /* Get startc/stopc flow */ +#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */ /* control characters */ -#define DIGI_SETFLOW ('e'<<8) | 100 /* Set startc/stopc flow */ +#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */ /* control characters */ -#define DIGI_GETAFLOW ('e'<<8) | 101 /* Get Aux. startc/stopc */ +#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */ /* flow control chars */ -#define DIGI_SETAFLOW ('e'<<8) | 102 /* Set Aux. startc/stopc */ +#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */ /* flow control chars */ struct digiflow_struct { diff -u --recursive --new-file v1.3.90/linux/drivers/char/istallion.c linux/drivers/char/istallion.c --- v1.3.90/linux/drivers/char/istallion.c Fri Apr 12 15:51:52 1996 +++ linux/drivers/char/istallion.c Wed Apr 17 15:08:57 1996 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -167,12 +168,6 @@ #define STL_DRVTYPSERIAL 1 #define STL_DRVTYPCALLOUT 2 -#define STL_MAXBRDS 4 -#define STL_MAXPANELS 4 -#define STL_MAXPORTS 64 -#define STL_MAXCHANS (STL_MAXPORTS + 1) -#define STL_MAXDEVS (STL_MAXBRDS * STL_MAXPORTS) - /*****************************************************************************/ /* @@ -180,7 +175,7 @@ * all the local structures required by a serial tty driver. */ static char *stli_drvname = "Stallion Intelligent Multiport Serial Driver"; -static char *stli_drvversion = "1.0.8"; +static char *stli_drvversion = "1.1.1"; static char *stli_serialname = "ttyE"; static char *stli_calloutname = "cue"; @@ -236,92 +231,11 @@ static comstats_t stli_comstats; static combrd_t stli_brdstats; static asystats_t stli_cdkstats; +static stlibrd_t stli_dummybrd; +static stliport_t stli_dummyport; /*****************************************************************************/ -/* - * Define a set of structures to hold all the board/panel/port info - * for our ports. These will be dynamically allocated as required at - * driver initialization time. - */ - -/* - * Port and board structures to hold status info about each object. - * The board structure contains pointers to structures for each port - * connected to it. Panels are not distinguished here, since - * communication with the slave board will always be on a per port - * basis. - */ -typedef struct { - int portnr; - int panelnr; - int brdnr; - unsigned long state; - int devnr; - int flags; - int baud_base; - int custom_divisor; - int close_delay; - int closing_wait; - int refcount; - int openwaitcnt; - int rc; - int argsize; - void *argp; - long session; - long pgrp; - unsigned int rxmarkmsk; - struct tty_struct *tty; - struct wait_queue *open_wait; - struct wait_queue *close_wait; - struct wait_queue *raw_wait; - struct tq_struct tqhangup; - struct termios normaltermios; - struct termios callouttermios; - asysigs_t asig; - unsigned long addr; - unsigned long rxoffset; - unsigned long txoffset; - unsigned long sigs; - unsigned long pflag; - unsigned int rxsize; - unsigned int txsize; - unsigned char reqbit; - unsigned char portidx; - unsigned char portbit; -} stliport_t; - -/* - * Use a structure of function pointers to do board level operations. - * These include, enable/disable, paging shared memory, interrupting, etc. - */ -typedef struct stlbrd { - int brdnr; - int brdtype; - int state; - int nrpanels; - int nrports; - int nrdevs; - unsigned int iobase; - unsigned long memaddr; - void *membase; - int memsize; - int pagesize; - int hostoffset; - int slaveoffset; - int bitsize; - int panels[STL_MAXPANELS]; - int panelids[STL_MAXPANELS]; - void (*init)(struct stlbrd *brdp); - void (*enable)(struct stlbrd *brdp); - void (*reenable)(struct stlbrd *brdp); - void (*disable)(struct stlbrd *brdp); - char *(*getmemptr)(struct stlbrd *brdp, unsigned long offset, int line); - void (*intr)(struct stlbrd *brdp); - void (*reset)(struct stlbrd *brdp); - stliport_t *ports[STL_MAXPORTS]; -} stlibrd_t; - static stlibrd_t *stli_brds[STL_MAXBRDS]; static int stli_shared = 0; @@ -674,6 +588,8 @@ static int stli_getbrdstats(combrd_t *bp); static int stli_getportstats(stliport_t *portp, comstats_t *cp); static int stli_clrportstats(stliport_t *portp, comstats_t *cp); +static int stli_getportstruct(unsigned long arg); +static int stli_getbrdstruct(unsigned long arg); static void *stli_memalloc(int len); static void stli_ecpinit(stlibrd_t *brdp); @@ -1378,13 +1294,22 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp) { unsigned long flags; - int rc; + int rc, doclocal; #if DEBUG printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n", (int) brdp, (int) portp, (int) filp); #endif rc = 0; + doclocal = 0; + + if (portp->flags & ASYNC_CALLOUT_ACTIVE) { + if (portp->normaltermios.c_cflag & CLOCAL) + doclocal++; + } else { + if (portp->tty->termios->c_cflag & CLOCAL) + doclocal++; + } save_flags(flags); cli(); @@ -1407,8 +1332,7 @@ } if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) && ((portp->flags & ASYNC_CLOSING) == 0) && - ((portp->tty->termios->c_cflag & CLOCAL) || - (portp->sigs & TIOCM_CD))) { + (doclocal || (portp->sigs & TIOCM_CD))) { break; } if (current->signal & ~current->blocked) { @@ -2540,10 +2464,12 @@ if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) wake_up_interruptible(&portp->open_wait); if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) { - if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) && - (portp->flags & ASYNC_CALLOUT_NOHUP))) { - if (tty != (struct tty_struct *) NULL) - queue_task_irq_off(&portp->tqhangup, &tq_scheduler); + if (portp->flags & ASYNC_CHECK_CD) { + if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) && + (portp->flags & ASYNC_CALLOUT_NOHUP))) { + if (tty != (struct tty_struct *) NULL) + queue_task_irq_off(&portp->tqhangup, &tq_scheduler); + } } } } @@ -2552,8 +2478,10 @@ clear_bit(ST_TXBUSY, &portp->state); if (nt.data & (DT_TXEMPTY | DT_TXLOW)) { if (tty != (struct tty_struct *) NULL) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { (tty->ldisc.write_wakeup)(tty); + EBRDENABLE(brdp); + } wake_up_interruptible(&tty->write_wait); } } @@ -2565,8 +2493,10 @@ *tty->flip.flag_buf_ptr++ = TTY_BREAK; *tty->flip.char_buf_ptr++ = 0; #ifndef MODULE - if (portp->flags & ASYNC_SAK) + if (portp->flags & ASYNC_SAK) { do_SAK(tty); + EBRDENABLE(brdp); + } #endif tty_schedule_flip(tty); } @@ -2798,6 +2728,14 @@ portp->rxmarkmsk |= BRKINT; /* + * Set up clocal processing as required. + */ + if (tiosp->c_cflag & CLOCAL) + portp->flags &= ~ASYNC_CHECK_CD; + else + portp->flags |= ASYNC_CHECK_CD; + +/* * Transfer any persistent flags into the asyport structure. */ pp->pflag = portp->pflag; @@ -2876,6 +2814,7 @@ } memset(portp, 0, sizeof(stliport_t)); + portp->magic = STLI_PORTMAGIC; portp->portnr = i; portp->brdnr = brdp->brdnr; portp->panelnr = panelnr; @@ -4061,6 +4000,7 @@ } memset(brdp, 0, sizeof(stlibrd_t)); + brdp->magic = STLI_BOARDMAGIC; brdp->brdnr = stli_nrbrds++; eid = inb(iobase + 0xc82); if (eid == ECP_EISAID) @@ -4114,6 +4054,7 @@ } memset(brdp, 0, sizeof(stlibrd_t)); + brdp->magic = STLI_BOARDMAGIC; brdp->brdnr = i; brdp->brdtype = confp->brdtype; brdp->iobase = confp->ioaddr1; @@ -4336,6 +4277,7 @@ static int stli_getportstats(stliport_t *portp, comstats_t *cp) { + unsigned long flags; stlibrd_t *brdp; int rc; @@ -4353,23 +4295,28 @@ if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, &stli_cdkstats, sizeof(asystats_t), 1)) < 0) return(rc); + memset(&stli_comstats, 0, sizeof(comstats_t)); + stli_comstats.brd = portp->brdnr; + stli_comstats.panel = portp->panelnr; + stli_comstats.port = portp->portnr; stli_comstats.state = portp->state; stli_comstats.flags = portp->flags; + + save_flags(flags); + cli(); if (portp->tty != (struct tty_struct *) NULL) { - stli_comstats.ttystate = portp->tty->flags; - stli_comstats.cflags = portp->tty->termios->c_cflag; - stli_comstats.iflags = portp->tty->termios->c_iflag; - stli_comstats.oflags = portp->tty->termios->c_oflag; - stli_comstats.lflags = portp->tty->termios->c_lflag; - stli_comstats.rxbuffered = portp->tty->flip.count; - } else { - stli_comstats.ttystate = 0; - stli_comstats.cflags = 0; - stli_comstats.iflags = 0; - stli_comstats.oflags = 0; - stli_comstats.lflags = 0; - stli_comstats.rxbuffered = 0; + if (portp->tty->driver_data == portp) { + stli_comstats.ttystate = portp->tty->flags; + stli_comstats.rxbuffered = portp->tty->flip.count; + if (portp->tty->termios != (struct termios *) NULL) { + stli_comstats.cflags = portp->tty->termios->c_cflag; + stli_comstats.iflags = portp->tty->termios->c_iflag; + stli_comstats.oflags = portp->tty->termios->c_oflag; + stli_comstats.lflags = portp->tty->termios->c_lflag; + } + } } + restore_flags(flags); stli_comstats.txtotal = stli_cdkstats.txchars; stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover; @@ -4432,6 +4379,45 @@ /*****************************************************************************/ /* + * Return the entire driver ports structure to a user app. + */ + +static int stli_getportstruct(unsigned long arg) +{ + stliport_t *portp; + + memcpy_fromfs(&stli_dummyport, (void *) arg, sizeof(stliport_t)); + portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr, + stli_dummyport.portnr); + if (portp == (stliport_t *) NULL) + return(-ENODEV); + memcpy_tofs((void *) arg, portp, sizeof(stliport_t)); + return(0); +} + +/*****************************************************************************/ + +/* + * Return the entire driver board structure to a user app. + */ + +static int stli_getbrdstruct(unsigned long arg) +{ + stlibrd_t *brdp; + + memcpy_fromfs(&stli_dummybrd, (void *) arg, sizeof(stlibrd_t)); + if ((stli_dummybrd.brdnr < 0) || (stli_dummybrd.brdnr >= STL_MAXBRDS)) + return(-ENODEV); + brdp = stli_brds[stli_dummybrd.brdnr]; + if (brdp == (stlibrd_t *) NULL) + return(-ENODEV); + memcpy_tofs((void *) arg, brdp, sizeof(stlibrd_t)); + return(0); +} + +/*****************************************************************************/ + +/* * The "staliomem" device is also required to do some special operations on * the board. We need to be able to send an interrupt to the board, * reset it, and start/stop it. @@ -4486,6 +4472,14 @@ case COM_GETBRDSTATS: if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(combrd_t))) == 0) rc = stli_getbrdstats((combrd_t *) arg); + break; + case COM_READPORT: + if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stliport_t))) == 0) + rc = stli_getportstruct(arg); + break; + case COM_READBOARD: + if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stlibrd_t))) == 0) + rc = stli_getbrdstruct(arg); break; default: rc = -ENOIOCTLCMD; diff -u --recursive --new-file v1.3.90/linux/drivers/char/misc.c linux/drivers/char/misc.c --- v1.3.90/linux/drivers/char/misc.c Mon Apr 15 12:20:17 1996 +++ linux/drivers/char/misc.c Wed Apr 17 09:22:07 1996 @@ -176,8 +176,8 @@ X(misc_register), X(misc_deregister), #ifndef MODULE - X(set_selection), /* used by the kmisc module, can only */ - X(clear_selection), /* be exported if misc.c is in linked in */ + X(set_selection), /* used by the kmouse module, can only */ + X(paste_selection), /* be exported if misc.c is in linked in */ #endif #include }; @@ -196,7 +196,7 @@ #ifdef CONFIG_BUSMOUSE bus_mouse_init(); #endif -#if defined CONFIG_PSMOUSE || defined CONFIG_82C710_MOUSE +#if defined CONFIG_PSMOUSE psaux_init(); #endif #ifdef CONFIG_MS_BUSMOUSE diff -u --recursive --new-file v1.3.90/linux/drivers/char/pcxx.c linux/drivers/char/pcxx.c --- v1.3.90/linux/drivers/char/pcxx.c Fri Apr 12 15:51:52 1996 +++ linux/drivers/char/pcxx.c Wed Apr 17 08:12:58 1996 @@ -28,6 +28,8 @@ * 1.5.5 April 5, 1996 Major device numbers corrected. * Mike McLagan: Add setup * variable handling, instead of using the old pcxxconfig.h + * 1.5.6 April 16, 1996 Christoph Lameter: Pointer cleanup, macro cleanup. + * Call out devices changed to /dev/cudxx. * */ @@ -64,8 +66,8 @@ #include #include -#define VERSION "1.5.5" -static char *banner = "Digiboard PC/X{i,e,eve,em} driver v1.5.5. Christoph Lameter ."; +#define VERSION "1.5.6" +static char *banner = "Digiboard PC/X{i,e,eve} driver v1.5.6. Christoph Lameter ."; /*#define DEFAULT_HW_FLOW 1 */ /*#define DEBUG_IOCTL */ @@ -81,16 +83,13 @@ */ static struct board_info boards[MAX_DIGI_BOARDS] = { { ENABLED, 0, ON, 16, 0x200, 0xd0000,0 } }; -static int numcards = 1; -static int nbdevs = 0; +static int numcards = 1; +static int nbdevs = 0; -/* C is a pain! I want a pointer to an array of structs */ -static struct channel *(*digi_channels); - -/* this is supposed to be a pointer to an array of pointers */ -static struct tty_struct *(*pcxe_table)[]; -static struct termios *(*pcxe_termios)[]; -static struct termios *(*pcxe_termios_locked)[]; +static struct channel *digi_channels; +static struct tty_struct **pcxe_table; +static struct termios **pcxe_termios; +static struct termios **pcxe_termios_locked; int pcxx_ncook=sizeof(pcxx_cook); int pcxx_nbios=sizeof(pcxx_bios); @@ -150,7 +149,7 @@ { if (tty) { register struct channel *ch=(struct channel *)tty->driver_data; - if ((ch >= &((*digi_channels)[0])) && (ch < &((*digi_channels)[nbdevs]))) { + if (ch >= digi_channels && ch < digi_channels+nbdevs) { if (ch->magic==PCXX_MAGIC) return ch; } @@ -319,7 +318,7 @@ return(-ENODEV); } - ch = &((*digi_channels)[line]); + ch = digi_channels+line; if(ch->brdchan == 0) { tty->driver_data = NULL; @@ -990,22 +989,21 @@ /* * this turns out to be more memory efficient, as there are no - * unused spaces. There is *NO* way I'm going to explain these - * convoluted casts, suffice it to say they WORK! :) + * unused spaces. */ - digi_channels = (struct channel **) kmalloc(sizeof(struct channel) * nbdevs, GFP_KERNEL); + digi_channels = kmalloc(sizeof(struct channel) * nbdevs, GFP_KERNEL); if (!digi_channels) panic("Unable to allocate digi_channel struct"); - pcxe_table = (struct tty_struct *(*)[]) kmalloc(sizeof(struct tty_struct *) * nbdevs, GFP_KERNEL); + pcxe_table = kmalloc(sizeof(struct tty_struct *) * nbdevs, GFP_KERNEL); if (!pcxe_table) panic("Unable to allocate pcxe_table struct"); - pcxe_termios = (struct termios *(*)[]) kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL); + pcxe_termios = kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL); if (!pcxe_termios) panic("Unable to allocate pcxe_termios struct"); - pcxe_termios_locked = (struct termios *(*)[]) kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL); + pcxe_termios_locked = kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL); if (!pcxe_termios_locked) panic("Unable to allocate pcxe_termios_locked struct"); @@ -1018,7 +1016,7 @@ memset(&pcxe_driver, 0, sizeof(struct tty_driver)); pcxe_driver.magic = TTY_DRIVER_MAGIC; - pcxe_driver.name = "ttyd"; + pcxe_driver.name = "cud"; pcxe_driver.major = DIGI_MAJOR; pcxe_driver.minor_start = 0; @@ -1031,9 +1029,9 @@ pcxe_driver.flags = TTY_DRIVER_REAL_RAW; pcxe_driver.refcount = &pcxe_refcount; - pcxe_driver.table = *pcxe_table; - pcxe_driver.termios = *pcxe_termios; - pcxe_driver.termios_locked = *pcxe_termios_locked; + pcxe_driver.table = pcxe_table; + pcxe_driver.termios = pcxe_termios; + pcxe_driver.termios_locked = pcxe_termios_locked; pcxe_driver.open = pcxe_open; pcxe_driver.close = pcxe_close; @@ -1259,8 +1257,8 @@ if(bd->status == DISABLED) continue; - ch = &((*digi_channels)[bd->first_minor]); - pcxxassert(ch < &((*digi_channels)[nbdevs]), "ch out of range"); + ch = digi_channels+bd->first_minor; + pcxxassert(ch < digi_channels+nbdevs, "ch out of range"); bc = (volatile struct board_chan *)((ulong)memaddr + CHANSTRUCT); gd = (volatile struct global_data *)((ulong)memaddr + GLOBAL); @@ -1391,7 +1389,7 @@ for(crd=0; crd < numcards; crd++) { bd = &boards[crd]; - ch = &((*digi_channels)[bd->first_minor]); + ch = digi_channels+bd->first_minor; if(bd->status == DISABLED) continue; @@ -1428,8 +1426,8 @@ bd = &boards[crd]; - chan0 = &((*digi_channels)[bd->first_minor]); - pcxxassert(chan0 < &((*digi_channels)[nbdevs]), "ch out of range"); + chan0 = digi_channels+bd->first_minor; + pcxxassert(chan0 < digi_channels+nbdevs, "ch out of range"); assertgwinon(chan0); diff -u --recursive --new-file v1.3.90/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v1.3.90/linux/drivers/char/serial.c Mon Apr 8 19:01:43 1996 +++ linux/drivers/char/serial.c Wed Apr 17 09:01:19 1996 @@ -11,7 +11,9 @@ * set_serial_info fixed to set the flags, custom divisor, and uart * type fields. Fix suggested by Michael K. Johnson 12/12/92. * - * TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis + * 11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis + * + * 03/96: Modularised by Angelo Haritsis * * This module exports the following rs232 io functions: * @@ -19,6 +21,7 @@ * int rs_open(struct tty_struct * tty, struct file * filp) */ +#include #include #include #include @@ -41,6 +44,9 @@ #include #include +static char *serial_name = "Serial driver"; +static char *serial_version = "4.12"; + DECLARE_TASK_QUEUE(tq_serial); struct tty_driver serial_driver, callout_driver; @@ -80,6 +86,13 @@ #define _INLINE_ inline +#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) +#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ + kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s) +#else +#define DBG_CNT(s) +#endif + /* * IRQ_timeout - How long the timeout should be for each IRQ * should be after the IRQ has been active. @@ -1076,6 +1089,12 @@ #endif save_flags(flags); cli(); /* Disable interrupts */ + + /* + * clear delta_msr_wait queue to avoid mem leaks: we may free the irq + * here so the queue might never be waken up + */ + wake_up_interruptible(&info->delta_msr_wait); /* * First unlink the serial port from the IRQ chain... @@ -2002,6 +2021,9 @@ cli(); cnow = info->icount; /* atomic copy */ sti(); + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) + return -EIO; /* no change => error */ if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || @@ -2089,6 +2111,8 @@ save_flags(flags); cli(); if (tty_hung_up_p(filp)) { + DBG_CNT("before DEC-hung"); + MOD_DEC_USE_COUNT; restore_flags(flags); return; } @@ -2114,6 +2138,8 @@ info->count = 0; } if (info->count) { + DBG_CNT("before DEC-2"); + MOD_DEC_USE_COUNT; restore_flags(flags); return; } @@ -2165,14 +2191,6 @@ tty->closing = 0; info->event = 0; info->tty = 0; - if (tty->ldisc.num != ldiscs[N_TTY].num) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); - tty->ldisc = ldiscs[N_TTY]; - tty->termios->c_line = N_TTY; - if (tty->ldisc.open) - (tty->ldisc.open)(tty); - } if (info->blocked_open) { if (info->close_delay) { current->state = TASK_INTERRUPTIBLE; @@ -2184,6 +2202,7 @@ info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); + MOD_DEC_USE_COUNT; restore_flags(flags); } @@ -2387,6 +2406,7 @@ if (retval) return retval; + MOD_INC_USE_COUNT; retval = block_til_ready(tty, filp, info); if (retval) { #ifdef SERIAL_DEBUG_OPEN @@ -2428,7 +2448,7 @@ */ static void show_serial_version(void) { - printk("Serial driver version 4.11a with"); + printk("%s version %s with", serial_name, serial_version); #ifdef CONFIG_HUB6 printk(" HUB-6"); #define SERIAL_OPT @@ -2663,6 +2683,16 @@ restore_flags(flags); } +int register_serial(struct serial_struct *req); +void unregister_serial(int line); + +static struct symbol_table serial_syms = { +#include + X(register_serial), + X(unregister_serial), +#include +}; + /* * The serial driver boot-time initialization code! */ @@ -2791,6 +2821,7 @@ break; } } + register_symtab(&serial_syms); return 0; } @@ -2867,3 +2898,30 @@ printk("tty%02d unloaded\n", info->line); restore_flags(flags); } + +#ifdef MODULE +int init_module(void) +{ + return rs_init(); +} + +void cleanup_module(void) +{ + unsigned long flags; + int e1, e2; + + /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ + save_flags(flags); + cli(); + timer_active &= ~(1 << RS_TIMER); + timer_table[RS_TIMER].fn = NULL; + timer_table[RS_TIMER].expires = 0; + if ((e1 = tty_unregister_driver(&serial_driver))) + printk("SERIAL: failed to unregister serial driver (%d)\n", + e1); + if ((e2 = tty_unregister_driver(&callout_driver))) + printk("SERIAL: failed to unregister callout driver (%d)\n", + e2); + restore_flags(flags); +} +#endif /* MODULE */ diff -u --recursive --new-file v1.3.90/linux/drivers/char/stallion.c linux/drivers/char/stallion.c --- v1.3.90/linux/drivers/char/stallion.c Sat Apr 13 18:22:06 1996 +++ linux/drivers/char/stallion.c Wed Apr 17 15:08:57 1996 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -124,12 +125,6 @@ #define STL_DRVTYPSERIAL 1 #define STL_DRVTYPCALLOUT 2 -#define STL_MAXBRDS 4 -#define STL_MAXPANELS 4 -#define STL_PORTSPERPANEL 16 -#define STL_MAXPORTS 64 -#define STL_MAXDEVS (STL_MAXBRDS * STL_MAXPORTS) - /* * I haven't really decided (or measured) what TX buffer size gives * a good balance between performance and memory usage. These seem @@ -145,7 +140,7 @@ * all the local structures required by a serial tty driver. */ static char *stl_drvname = "Stallion Multiport Serial Driver"; -static char *stl_drvversion = "1.0.8"; +static char *stl_drvversion = "1.1.1"; static char *stl_serialname = "ttyE"; static char *stl_calloutname = "cue"; @@ -186,6 +181,8 @@ */ static comstats_t stl_comstats; static combrd_t stl_brdstats; +static stlbrd_t stl_dummybrd; +static stlport_t stl_dummyport; /* * Keep track of what interrupts we have requested for us. @@ -197,98 +194,6 @@ /*****************************************************************************/ -/* - * Define a set of structures to hold all the board/panel/port info - * for our ports. These will be dynamically allocated as required. - */ - -/* - * Define a ring queue structure for each port. This will hold the - * TX data waiting to be output. Characters are fed into this buffer - * from the line discipline (or even direct from user space!) and - * then fed into the UARTs during interrupts. Will use a classic ring - * queue here for this. The good thing about this type of ring queue - * is that the head and tail pointers can be updated without interrupt - * protection - since "write" code only needs to change the head, and - * interrupt code only needs to change the tail. - */ -typedef struct { - char *buf; - char *head; - char *tail; -} stlrq_t; - -/* - * Port, panel and board structures to hold status info about each. - * The board structure contains pointers to structures for each panel - * connected to it, and in turn each panel structure contains pointers - * for each port structure for each port on that panel. Note that - * the port structure also contains the board and panel number that it - * is associated with, this makes it (fairly) easy to get back to the - * board/panel info for a port. - */ -typedef struct { - int portnr; - int panelnr; - int brdnr; - int ioaddr; - int uartaddr; - int pagenr; - int istate; - int flags; - int baud_base; - int custom_divisor; - int close_delay; - int closing_wait; - int refcount; - int openwaitcnt; - int brklen; - long session; - long pgrp; - unsigned int sigs; - unsigned int rxignoremsk; - unsigned int rxmarkmsk; - unsigned long clk; - unsigned long hwid; - struct tty_struct *tty; - struct wait_queue *open_wait; - struct wait_queue *close_wait; - struct termios normaltermios; - struct termios callouttermios; - struct tq_struct tqueue; - comstats_t stats; - stlrq_t tx; -} stlport_t; - -typedef struct { - int panelnr; - int brdnr; - int pagenr; - int nrports; - int iobase; - unsigned int hwid; - unsigned int ackmask; - stlport_t *ports[STL_PORTSPERPANEL]; -} stlpanel_t; - -typedef struct { - int brdnr; - int brdtype; - int state; - int nrpanels; - int nrports; - int irq; - int irqtype; - unsigned int ioaddr1; - unsigned int ioaddr2; - unsigned int iostatus; - unsigned int ioctrl; - unsigned int ioctrlval; - unsigned int hwid; - unsigned long clk; - stlpanel_t *panels[STL_MAXPANELS]; -} stlbrd_t; - static stlbrd_t *stl_brds[STL_MAXBRDS]; /* @@ -501,6 +406,8 @@ static int stl_getbrdstats(combrd_t *bp); static int stl_getportstats(stlport_t *portp, comstats_t *cp); static int stl_clrportstats(stlport_t *portp, comstats_t *cp); +static int stl_getportstruct(unsigned long arg); +static int stl_getbrdstruct(unsigned long arg); static void stl_setreg(stlport_t *portp, int regnr, int value); static int stl_getreg(stlport_t *portp, int regnr); static int stl_updatereg(stlport_t *portp, int regnr, int value); @@ -785,13 +692,22 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) { unsigned long flags; - int rc; + int rc, doclocal; #if DEBUG printk("stl_waitcarrier(portp=%x,filp=%x)\n", (int) portp, (int) filp); #endif rc = 0; + doclocal = 0; + + if (portp->flags & ASYNC_CALLOUT_ACTIVE) { + if (portp->normaltermios.c_cflag & CLOCAL) + doclocal++; + } else { + if (portp->tty->termios->c_cflag & CLOCAL) + doclocal++; + } save_flags(flags); cli(); @@ -811,8 +727,7 @@ } if (((portp->flags & ASYNC_CALLOUT_ACTIVE) == 0) && ((portp->flags & ASYNC_CLOSING) == 0) && - ((portp->tty->termios->c_cflag & CLOCAL) || - (portp->sigs & TIOCM_CD))) { + (doclocal || (portp->sigs & TIOCM_CD))) { break; } if (current->signal & ~current->blocked) { @@ -1747,8 +1662,10 @@ if (status & ST_BREAK) { status = TTY_BREAK; #ifndef MODULE - if (portp->flags & ASYNC_SAK) + if (portp->flags & ASYNC_SAK) { do_SAK(tty); + BRDENABLE(portp->brdnr, portp->pagenr); + } #endif } else if (status & ST_PARITY) { status = TTY_PARITY; @@ -1995,9 +1912,11 @@ if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) wake_up_interruptible(&portp->open_wait); if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) { - if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) && - (portp->flags & ASYNC_CALLOUT_NOHUP))) { - tty_hangup(tty); + if (portp->flags & ASYNC_CHECK_CD) { + if (! ((portp->flags & ASYNC_CALLOUT_ACTIVE) && + (portp->flags & ASYNC_CALLOUT_NOHUP))) { + tty_hangup(tty); + } } } } @@ -2164,6 +2083,9 @@ mcor1 |= MCOR1_DCD; mcor2 |= MCOR2_DCD; sreron |= SRER_MODEM; + portp->flags |= ASYNC_CHECK_CD; + } else { + portp->flags &= ~ASYNC_CHECK_CD; } /* @@ -2533,6 +2455,7 @@ break; } memset(portp, 0, sizeof(stlport_t)); + portp->magic = STL_PORTMAGIC; portp->portnr = i; portp->brdnr = panelp->brdnr; portp->panelnr = panelp->panelnr; @@ -2617,6 +2540,7 @@ } memset(panelp, 0, sizeof(stlpanel_t)); + panelp->magic = STL_PANELMAGIC; panelp->brdnr = brdp->brdnr; panelp->panelnr = 0; panelp->nrports = brdp->nrports; @@ -2722,6 +2646,7 @@ break; } memset(panelp, 0, sizeof(stlpanel_t)); + panelp->magic = STL_PANELMAGIC; panelp->brdnr = brdp->brdnr; panelp->panelnr = panelnr; panelp->iobase = ioaddr; @@ -2854,6 +2779,7 @@ return(-ENOMEM); } memset(brdp, 0, sizeof(stlbrd_t)); + brdp->magic = STL_BOARDMAGIC; brdp->brdnr = stl_nrbrds++; brdp->brdtype = BRD_ECHPCI; @@ -2923,6 +2849,7 @@ } memset(brdp, 0, sizeof(stlbrd_t)); + brdp->magic = STL_BOARDMAGIC; brdp->brdnr = i; brdp->brdtype = confp->brdtype; brdp->ioaddr1 = confp->ioaddr1; @@ -3020,6 +2947,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t *cp) { unsigned char *head, *tail; + unsigned long flags; if (portp == (stlport_t *) NULL) { memcpy_fromfs(&stl_comstats, cp, sizeof(comstats_t)); @@ -3031,21 +2959,29 @@ portp->stats.state = portp->istate; portp->stats.flags = portp->flags; portp->stats.hwid = portp->hwid; + + portp->stats.ttystate = 0; + portp->stats.cflags = 0; + portp->stats.iflags = 0; + portp->stats.oflags = 0; + portp->stats.lflags = 0; + portp->stats.rxbuffered = 0; + + save_flags(flags); + cli(); if (portp->tty != (struct tty_struct *) NULL) { - portp->stats.ttystate = portp->tty->flags; - portp->stats.cflags = portp->tty->termios->c_cflag; - portp->stats.iflags = portp->tty->termios->c_iflag; - portp->stats.oflags = portp->tty->termios->c_oflag; - portp->stats.lflags = portp->tty->termios->c_lflag; - portp->stats.rxbuffered = portp->tty->flip.count; - } else { - portp->stats.ttystate = 0; - portp->stats.cflags = 0; - portp->stats.iflags = 0; - portp->stats.oflags = 0; - portp->stats.lflags = 0; - portp->stats.rxbuffered = 0; + if (portp->tty->driver_data == portp) { + portp->stats.ttystate = portp->tty->flags; + portp->stats.rxbuffered = portp->tty->flip.count; + if (portp->tty->termios != (struct termios *) NULL) { + portp->stats.cflags = portp->tty->termios->c_cflag; + portp->stats.iflags = portp->tty->termios->c_iflag; + portp->stats.oflags = portp->tty->termios->c_oflag; + portp->stats.lflags = portp->tty->termios->c_lflag; + } + } } + restore_flags(flags); head = portp->tx.head; tail = portp->tx.tail; @@ -3083,6 +3019,45 @@ /*****************************************************************************/ /* + * Return the entire driver ports structure to a user app. + */ + +static int stl_getportstruct(unsigned long arg) +{ + stlport_t *portp; + + memcpy_fromfs(&stl_dummyport, (void *) arg, sizeof(stlport_t)); + portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr, + stl_dummyport.portnr); + if (portp == (stlport_t *) NULL) + return(-ENODEV); + memcpy_tofs((void *) arg, portp, sizeof(stlport_t)); + return(0); +} + +/*****************************************************************************/ + +/* + * Return the entire driver board structure to a user app. + */ + +static int stl_getbrdstruct(unsigned long arg) +{ + stlbrd_t *brdp; + + memcpy_fromfs(&stl_dummybrd, (void *) arg, sizeof(stlbrd_t)); + if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS)) + return(-ENODEV); + brdp = stl_brds[stl_dummybrd.brdnr]; + if (brdp == (stlbrd_t *) NULL) + return(-ENODEV); + memcpy_tofs((void *) arg, brdp, sizeof(stlbrd_t)); + return(0); +} + +/*****************************************************************************/ + +/* * The "staliomem" device is also required to do some special operations * on the board and/or ports. In this driver it is mostly used for stats * collection. @@ -3118,6 +3093,14 @@ case COM_GETBRDSTATS: if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(combrd_t))) == 0) rc = stl_getbrdstats((combrd_t *) arg); + break; + case COM_READPORT: + if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stlport_t))) == 0) + rc = stl_getportstruct(arg); + break; + case COM_READBOARD: + if ((rc = verify_area(VERIFY_WRITE, (void *) arg, sizeof(stlbrd_t))) == 0) + rc = stl_getbrdstruct(arg); break; default: rc = -ENOIOCTLCMD; diff -u --recursive --new-file v1.3.90/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v1.3.90/linux/drivers/char/tty_io.c Wed Apr 3 16:06:55 1996 +++ linux/drivers/char/tty_io.c Wed Apr 17 09:01:19 1996 @@ -1763,6 +1763,9 @@ else if (p->major == driver->major) othername = p->name; } + + if (!found) + return -ENOENT; if (othername == NULL) { retval = unregister_chrdev(driver->major, driver->name); @@ -1814,6 +1817,8 @@ return con_init(kmem_start); } +static struct tty_driver dev_tty_driver, dev_console_driver; + /* * Ok, now we can initialize the rest of the tty devices and can count * on memory allocations, interrupts etc.. @@ -1822,6 +1827,31 @@ { if (sizeof(struct tty_struct) > PAGE_SIZE) panic("size of tty structure > PAGE_SIZE!"); + + /* + * dev_tty_driver and dev_console_driver are actually magic + * devices which get redirected at open time. Nevertheless, + * we register them so that register_chrdev is called + * appropriately. + */ + memset(&dev_tty_driver, 0, sizeof(struct tty_driver)); + dev_tty_driver.magic = TTY_DRIVER_MAGIC; + dev_tty_driver.name = "tty"; + dev_tty_driver.name_base = 0; + dev_tty_driver.major = TTY_MAJOR; + dev_tty_driver.minor_start = 0; + dev_tty_driver.num = 1; + + if (tty_register_driver(&dev_tty_driver)) + panic("Couldn't register /dev/tty driver\n"); + + dev_console_driver = dev_tty_driver; + dev_console_driver.name = "console"; + dev_console_driver.major = TTYAUX_MAJOR; + + if (tty_register_driver(&dev_console_driver)) + panic("Couldn't register /dev/console driver\n"); + kbd_init(); #ifdef CONFIG_SERIAL rs_init(); @@ -1843,10 +1873,6 @@ #endif pty_init(); vcs_init(); - if (register_chrdev(TTY_MAJOR,"tty",&tty_fops)) - panic("unable to get major %d for tty device", TTY_MAJOR); - if (register_chrdev(TTYAUX_MAJOR,"cua",&tty_fops)) - panic("unable to get major %d for tty device", TTYAUX_MAJOR); - return 0; } + diff -u --recursive --new-file v1.3.90/linux/drivers/net/3c505.c linux/drivers/net/3c505.c --- v1.3.90/linux/drivers/net/3c505.c Fri Apr 12 15:51:54 1996 +++ linux/drivers/net/3c505.c Wed Apr 17 07:20:07 1996 @@ -10,7 +10,7 @@ * be here without 3C505 technical reference provided by * 3Com. * - * $Id: 3c505.c,v 1.7 1996/04/09 19:01:30 phil Exp phil $ + * $Id: 3c505.c,v 1.10 1996/04/16 13:06:27 phil Exp $ * * Authors: Linux 3c505 device driver by * Craig Southeren, @@ -174,8 +174,7 @@ * Last element MUST BE 0! *****************************************************************/ -const int addr_list[] = -{0x300, 0x280, 0x310, 0}; +const int addr_list[] = {0x300, 0x280, 0x310, 0}; /* Dma Memory related stuff */ @@ -249,10 +248,6 @@ * *****************************************************************/ -/* We allocate 8k of DMA buffer for each adapter. This gives us one buffer for - * received data, and four for the transmit backlog. - */ - #define DMA_BUFFER_SIZE 1600 #define BACKLOG_SIZE 4 @@ -364,6 +359,10 @@ printk("%s: start receive command failed \n", dev->name); } +/* Check to make sure that a DMA transfer hasn't timed out. This should never happen + * in theory, but seems to occur occasionally if the card gets prodded at the wrong + * time. + */ static inline void check_dma(struct device *dev) { elp_device *adapter = dev->priv; @@ -407,9 +406,6 @@ return TRUE; } -static int - start_receive(struct device *dev, pcb_struct * tx_pcb); - /* Check to see if the receiver needs restarting, and kick it if so */ static inline void prime_rx(struct device *dev) { @@ -871,18 +867,15 @@ printk("%s: interrupt - packet sent\n", dev->name); if (dev->start == 0) break; - if (adapter->irx_pcb.data.xmit_resp.c_stat != 0) { - if (elp_debug >= 0) - printk("%s: interrupt - error sending packet %4.4x\n", - dev->name, adapter->irx_pcb.data.xmit_resp.c_stat); - switch (adapter->irx_pcb.data.xmit_resp.c_stat) { - case 0xffff: - adapter->stats.tx_aborted_errors++; - break; - case 0xfffe: - adapter->stats.tx_fifo_errors++; - break; - } + switch (adapter->irx_pcb.data.xmit_resp.c_stat) { + case 0xffff: + adapter->stats.tx_aborted_errors++; + printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name); + break; + case 0xfffe: + adapter->stats.tx_fifo_errors++; + printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name); + break; } dev->tbusy = 0; mark_bh(NET_BH); @@ -892,7 +885,7 @@ * some unknown PCB */ default: - printk("%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command); + printk(KERN_DEBUG "%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command); break; } } else { @@ -1147,7 +1140,7 @@ return 1; stat = inb_status(dev->base_addr); - printk("%s: transmit timed out, %s?\n", dev->name, (stat & ACRF) ? "IRQ conflict" : "network cable problem"); + printk("%s: transmit timed out, lost %s?\n", dev->name, (stat & ACRF) ? "interrupt" : "command"); if (elp_debug >= 1) printk("%s: status %#02x\n", dev->name, stat); dev->trans_start = jiffies; @@ -1200,8 +1193,7 @@ * ******************************************************/ -static struct enet_statistics * - elp_get_stats(struct device *dev) +static struct enet_statistics *elp_get_stats(struct device *dev) { elp_device *adapter = (elp_device *) dev->priv; @@ -1544,27 +1536,27 @@ /* Nope, it's ignoring the command register. This means that * either it's still booting up, or it's died. */ - printk("%s: command register wouldn't drain, assuming ", dev->name); + printk("%s: command register wouldn't drain, ", dev->name); if ((inb_status(dev->base_addr) & 7) == 3) { /* If the adapter status is 3, it *could* still be booting. * Give it the benefit of the doubt for 10 seconds. */ - printk("3c505 still starting\n"); + printk("assuming 3c505 still starting\n"); timeout = jiffies + 10 * HZ; while (jiffies < timeout && (inb_status(dev->base_addr) & 7)); if (inb_status(dev->base_addr) & 7) { printk("%s: 3c505 failed to start\n", dev->name); - continue; + } else { + okay = 1; /* It started */ } } else { /* Otherwise, it must just be in a strange state. We probably * need to kick it. */ - printk("3c505 dead\n"); - continue; + printk("3c505 is sulking\n"); } } - for (tries = 0; tries < 5; tries++) { + for (tries = 0; tries < 5 && okay; tries++) { /* * Try to set the Ethernet address, to make sure that the board @@ -1598,7 +1590,7 @@ outb_control(inb_control(dev->base_addr) | FLSH | ATTN, dev->base_addr); outb_control(inb_control(dev->base_addr) & ~(FLSH | ATTN), dev->base_addr); } - printk("%s: 3c505 is sulking, giving up\n", dev->name); + printk("%s: failed to initialise 3c505\n", dev->name); return -ENODEV; okay: @@ -1696,8 +1688,7 @@ } #ifdef MODULE -static char devicename[9] = -{0,}; +static char devicename[9] = {0,}; static struct device dev_3c505 = { devicename, /* device name is inserted by linux/drivers/net/net_init.c */ @@ -1715,7 +1706,6 @@ dev_3c505.base_addr = io; dev_3c505.irq = irq; if (register_netdev(&dev_3c505) != 0) { - printk("3c505: register_netdev() returned non-zero.\n"); return -EIO; } return 0; diff -u --recursive --new-file v1.3.90/linux/drivers/net/CONFIG linux/drivers/net/CONFIG --- v1.3.90/linux/drivers/net/CONFIG Wed Mar 6 14:53:46 1996 +++ linux/drivers/net/CONFIG Wed Apr 17 08:32:47 1996 @@ -60,6 +60,14 @@ # The DC21040 will default to TP if TP_NW is specified # The DC21041 will default to BNC if BNC_AUI is specified # +# TULIP Tulip (dc21040/dc21041/ds21140) driver +# TULIP_PORT specify default if_port +# 0: 10TP +# 1: 100Tx(ds21140)/AUI(dc2104x) +# 2: BNC(dc2104x) +# TULIP_FIX_PORT don't change if_port automatically if defined +# TULIP_MAX_CARDS maximum number of probed card +# # The following options exist, but cannot be set in this file. # lance.c @@ -83,4 +91,4 @@ EWRK3_OPTS = DE4X5_OPTS = -DDE4X5_AUTOSENSE=AUTO ELP_OPTS = -DELP_DEBUG=1 -DELP_NEED_HARD_RESET=0 - +TULIP_OPTS = diff -u --recursive --new-file v1.3.90/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v1.3.90/linux/drivers/net/Config.in Wed Apr 10 17:02:24 1996 +++ linux/drivers/net/Config.in Wed Apr 17 08:32:47 1996 @@ -79,7 +79,7 @@ fi tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5 - tristate 'DEC 21040 PCI support' CONFIG_DEC_ELCP + tristate 'DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP # bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 # bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 bool 'Zenith Z-Note support' CONFIG_ZNET diff -u --recursive --new-file v1.3.90/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v1.3.90/linux/drivers/net/Makefile Fri Apr 12 15:51:54 1996 +++ linux/drivers/net/Makefile Wed Apr 17 08:32:47 1996 @@ -526,3 +526,5 @@ dlci.o: dlci.c CONFIG +tulip.o: tulip.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(TULIP_OPTS) -c $< diff -u --recursive --new-file v1.3.90/linux/drivers/net/eql.c linux/drivers/net/eql.c --- v1.3.90/linux/drivers/net/eql.c Fri Apr 12 15:51:55 1996 +++ linux/drivers/net/eql.c Thu Apr 18 14:35:33 1996 @@ -17,7 +17,7 @@ */ static const char *version = - "Equalizer: $Revision: 3.12 $ $Date: 1995/01/19 $ Simon Janes (simon@ncm.com)\n"; + "Equalizer1996: $Revision: 1.2 $ $Date: 1996/04/11 17:51:52 $ Simon Janes (simon@ncm.com)\n"; /* * Sources: @@ -31,6 +31,12 @@ /* * $Log: eql.c,v $ + * Revision 1.2 1996/04/11 17:51:52 guru + * Added one-line eql_remove_slave patch. + * + * Revision 1.1 1996/04/11 17:44:17 guru + * Initial revision + * * Revision 3.13 1996/01/21 15:17:18 alan * tx_queue_len changes. * reformatted. @@ -287,6 +293,8 @@ printk ("%s: open\n", dev->name); #endif + printk ("%s: remember to turn off Van-Jacobson compression on your slave devices.\n", dev->name); + new_queue = eql_new_slave_queue (dev); if (new_queue != 0) @@ -431,8 +439,14 @@ int err; err = verify_area(VERIFY_READ, (void *)srqp, sizeof (slaving_request_t)); - if (err) + if (err) + { +#ifdef EQL_DEBUG + if (eql_debug >= 20) + printk ("EQL enslave: error detected by verify_area\n"); +#endif return err; + } memcpy_fromfs (&srq, srqp, sizeof (slaving_request_t)); #ifdef EQL_DEBUG @@ -458,8 +472,17 @@ eql_insert_slave (eql->queue, s); return 0; } +#ifdef EQL_DEBUG + if (eql_debug >= 20) + printk ("EQL enslsave: slave is master or slave is already slave\n"); +#endif + return -EINVAL; } +#ifdef EQL_DEBUG + if (eql_debug >= 20) + printk ("EQL enslave: master or slave are NULL"); +#endif return -EINVAL; } @@ -798,6 +821,7 @@ { prev->next = curr->next; queue->num_slaves--; + curr->dev->flags = curr->dev->flags & ~IFF_SLAVE; sti(); return curr; } @@ -806,30 +830,6 @@ } -#if 0 -static int eql_insert_slave_dev(slave_queue_t *queue, struct device *dev) -{ - slave_t *slave; - cli (); - - if ( ! eql_is_full (queue) ) - { - slave = eql_new_slave (); - slave->dev = dev; - slave->priority = EQL_DEFAULT_SLAVE_PRIORITY; - slave->priority_bps = EQL_DEFAULT_SLAVE_PRIORITY; - slave->priority_Bps = EQL_DEFAULT_SLAVE_PRIORITY / 8; - slave->next = queue->head->next; - queue->head->next = slave; - sti (); - return 0; - } - sti (); - return 1; -} -#endif - - static int eql_remove_slave_dev(slave_queue_t *queue, struct device *dev) { slave_t *prev; @@ -931,6 +931,7 @@ { slave_load = (ULONG_MAX - (ULONG_MAX / 2)) - (priority_Bps) + bytes_queued * 8; + if (slave_load < best_load) { best_load = slave_load; @@ -995,42 +996,6 @@ static inline void eql_set_best_slave(slave_queue_t *queue, slave_t *slave) { queue->best_slave = slave; -} - -#if 0 -static inline int eql_lock_slave_queue(slave_queue_t *queue) -{ - int result = 0; - - printk ("eql: lock == %d\n", queue->lock); - if (queue->lock) - { - printk ("eql: lock_slave-q sleeping for lock\n"); - sleep_on (&eql_queue_lock); - printk ("eql: lock_slave-q woken up\n"); - queue->lock = 1; - } - queue->lock = 1; - return result; -} - -static inline int eql_unlock_slave_queue(slave_queue_t *queue) -{ - int result = 0; - - if (queue->lock != 0) - { - queue->lock = 0; - printk ("eql: unlock_slave-q waking up lock waiters\n"); - wake_up (&eql_queue_lock); - } - return result; -} -#endif - -static inline int eql_is_locked_slave_queue(slave_queue_t *queue) -{ - return test_bit(1, (void *) &queue->lock); } static void eql_timer(unsigned long param) diff -u --recursive --new-file v1.3.90/linux/drivers/net/tulip.c linux/drivers/net/tulip.c --- v1.3.90/linux/drivers/net/tulip.c Mon Apr 15 12:20:18 1996 +++ linux/drivers/net/tulip.c Wed Apr 17 09:31:21 1996 @@ -16,16 +16,18 @@ static char *version = "tulip.c:v0.10 8/11/95 becker@cesdis.gsfc.nasa.gov\n" -" +0.68 3/09/96 " -"http://www.dsl.tutics.tut.ac.jp/~manabe/linux/tulip.html\n"; +" +0.72 4/17/96 " +"http://www.dsl.tutics.tut.ac.jp/~linux/tulip\n"; /* A few user-configurable values. */ -/* Default to using 10baseT (i.e. non-AUI/10base2/100baseT port) port. */ +/* Default to using 10baseT (i.e. AUI/10base2/100baseT port) port. */ #define TULIP_10TP_PORT 0 #define TULIP_100TP_PORT 1 #define TULIP_AUI_PORT 1 #define TULIP_BNC_PORT 2 +#define TULIP_MAX_PORT 3 +#define TULIP_AUTO_PORT -1 #ifndef TULIP_PORT #define TULIP_PORT TULIP_10TP_PORT @@ -34,36 +36,13 @@ /* Define to force full-duplex operation on all Tulip interfaces. */ /* #define TULIP_FULL_DUPLEX 1 */ -/* Define to probe only first detected device */ -/* #define TULIP_ONLY_ONE 1 */ - -#include +/* Define to fix port. */ +/* #define TULIP_FIX_PORT 1 */ -#if defined(MODULE) && defined(CONFIG_MODVERSIONS) -#define MODVERSIONS -#include -#endif - -#include +/* Define to probe only first detected device */ +/*#define TULIP_MAX_CARDS 1*/ -#if LINUX_VERSION_CODE < 0x10300 -/* i.e. version 1.2.x */ -#define virt_to_bus(address) (unsigned long)(address) -#define bus_to_virt(address) (void *)(address) -#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 -#ifdef MODULE -#include -char kernel_version[] = UTS_RELEASE; -#else -#undef MOD_INC_USE_COUNT -#undef MOD_DEC_USE_COUNT -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif -#else -/* i.e. version 1.3.x */ #include -#endif #include #include @@ -75,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -88,12 +68,6 @@ longword-wide registers on a quadword boundary. */ #define TULIP_TOTAL_SIZE 0x80 -#ifdef TULIP_DEBUG -int tulip_debug = TULIP_DEBUG; -#else -int tulip_debug = 3; -#endif - /* Theory of Operation @@ -151,7 +125,6 @@ register of the set CSR12-15 written. Hmmm, now how is that possible? */ - /* A few values that may be tweaked. */ /* Keep the ring sizes a power of two for efficiency. */ #define TX_RING_SIZE 4 @@ -266,9 +239,15 @@ #define TINTR_ENABLE 0xFFFFFFFF #define TINTR_DISABLE 0x00000000 +/* description of CSR11 G.P. timer (21041/21140) register */ +#define TGEPT_COUNT 0x0001FFFF + /* description of CSR12 SIA status(2104x)/GP(21140) register */ #define TSIAS_CONERROR 0x00000002 /* connection error */ #define TSIAS_LNKERROR 0x00000004 /* link error */ +#define TSIAS_ACTERROR 0x00000200 /* port Rx activity */ +#define TSIAS_RxACTIVE 0x00000100 /* port Rx activity */ + #define TGEPR_LK10NG 0x00000080 /* 10Mbps N.G. (R) */ #define TGEPR_LK100NG 0x00000040 /* 100Mbps N.G. (R) */ #define TGEPR_DETECT 0x00000020 /* detect signal (R) */ @@ -354,12 +333,13 @@ struct enet_statistics stats; int setup_frame[48]; /* Pseudo-Tx frame to init address table. */ void (*port_select)(struct device *dev); - int (*port_error)(struct device *dev); + int (*port_fail)(struct device *dev); char *signature; unsigned int cur_rx, cur_tx; /* The next free ring entry */ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ unsigned int tx_full:1; /* The Tx queue is full. */ unsigned int full_duplex:1; /* Full-duplex operation requested. */ + unsigned int port_fix:1; /* Fix if_port to specified port. */ }; struct eeprom { @@ -384,55 +364,55 @@ static void tulip_init_ring(struct device *dev); static int tulip_start_xmit(struct sk_buff *skb, struct device *dev); static int tulip_rx(struct device *dev); -static void tulip_interrupt(int irq, struct pt_regs *regs); +static void tulip_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int tulip_close(struct device *dev); static struct enet_statistics *tulip_get_stats(struct device *dev); static struct device *tulip_alloc(struct device *dev); -#if LINUX_VERSION_CODE < 0x10300 -static void set_multicast_list(struct device *dev, int num_addrs, - void *addrs); -#else static void set_multicast_list(struct device *dev); -#endif -#define generic21140_error NULL +#define generic21140_fail NULL static void generic21040_select(struct device *dev); static void generic21140_select(struct device *dev); static void generic21041_select(struct device *dev); static void auto21140_select(struct device *dev); -static int generic21040_error(struct device *dev); -static int generic21041_error(struct device *dev); +static void cogent21140_select(struct device *dev); +static int generic21040_fail(struct device *dev); +static int generic21041_fail(struct device *dev); static struct { void (*port_select)(struct device *dev); - int (*port_error)(struct device *dev); + int (*port_fail)(struct device *dev); unsigned int vendor_id, device_id; char *signature; - unsigned int port_auto:1; + unsigned int array:1; } cardVendor[] = { - {generic21140_select, generic21140_error, + {generic21140_select, generic21140_fail, 0x0000c000, PCI_DEVICE_ID_DEC_TULIP_FAST, "smc9332", 0}, - {generic21041_select, generic21041_error, + {generic21041_select, generic21041_fail, 0x0000c000, PCI_DEVICE_ID_DEC_TULIP_PLUS, "smc8432", 0}, - {generic21040_select, generic21040_error, + {generic21040_select, generic21040_fail, 0x0000c000, PCI_DEVICE_ID_DEC_TULIP, "old smc8432", 0}, - {auto21140_select, generic21140_error, - 0x0000f400, PCI_DEVICE_ID_DEC_TULIP_FAST, "LA100PCI", 1}, - {generic21140_select, generic21140_error, + {auto21140_select, generic21140_fail, + 0x0000f400, PCI_DEVICE_ID_DEC_TULIP_FAST, "LA100PCI", 0}, + {cogent21140_select, generic21140_fail, + 0x00009200, PCI_DEVICE_ID_DEC_TULIP_FAST, "cogent_em110", 0}, + {generic21140_select, generic21140_fail, 0x0000f800, PCI_DEVICE_ID_DEC_TULIP_FAST, "DE500", 0}, - {generic21041_select, generic21041_error, + {generic21041_select, generic21041_fail, 0x0000f800, PCI_DEVICE_ID_DEC_TULIP_PLUS, "DE450", 0}, - {generic21040_select, generic21040_error, + {generic21040_select, generic21040_fail, 0x0000f800, PCI_DEVICE_ID_DEC_TULIP, "DE43x", 0}, - {generic21040_select, generic21040_error, + {generic21040_select, generic21040_fail, 0x0040c700, PCI_DEVICE_ID_DEC_TULIP, "EN9400", 0}, - {generic21040_select, generic21040_error, - 0x00c09500, PCI_DEVICE_ID_DEC_TULIP, "ZNYX312", 0}, - {generic21040_select, generic21040_error, + {generic21040_select, generic21040_fail, + 0x00c09500, PCI_DEVICE_ID_DEC_TULIP, "ZNYX312", 1}, + {generic21040_select, generic21040_fail, + 0x08002b00, PCI_DEVICE_ID_DEC_TULIP, "QSILVER's", 0}, + {generic21040_select, generic21040_fail, 0, PCI_DEVICE_ID_DEC_TULIP, "21040", 0}, - {generic21140_select, generic21140_error, + {generic21140_select, generic21140_fail, 0, PCI_DEVICE_ID_DEC_TULIP_FAST, "21140", 0}, - {generic21041_select, generic21041_error, + {generic21041_select, generic21041_fail, 0, PCI_DEVICE_ID_DEC_TULIP_PLUS, "21041", 0}, {NULL, NULL, 0, 0, "Unknown", 0} }; @@ -449,26 +429,23 @@ #define EE_DATA_READ 0x08 /* EEPROM chip data out. */ #define EE_ENB (0x4800 | EE_CS) -/* Delay between EEPROM clock transitions. - This is a "nasty" timing loop, but PC compatible machines are *supposed* - to delay an ISA compatible period for the SLOW_DOWN_IO macro. */ - -#define eeprom_delay(nanosec)\ - do { int _i = 3; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0) - /* The EEPROM commands include the alway-set leading bit. */ #define EE_WRITE_CMD (5 << 6) #define EE_READ_CMD (6 << 6) #define EE_ERASE_CMD (7 << 6) #ifdef MODULE -static u_long alloc_size; +static int if_port=TULIP_AUTO_PORT; +static size_t alloc_size; +#ifdef TULIP_FULL_DUPLEX +static int full_duplex=1; +#else +static int full_duplex=0; +#endif #endif -#ifdef __i386__ #define tio_write(val, port) outl(val, ioaddr + port) #define tio_read(port) inl(ioaddr + port) -#endif static void inline tio_sia_write(u32 ioaddr, u32 val13, u32 val14, u32 val15) @@ -479,7 +456,11 @@ tio_write(val13,CSR13); } -static char * +/* + card_type returns 1 if the card is 'etherarray' +*/ + +static int card_type(struct tulip_private *tp, int device_id, int vendor_id) { int n; @@ -489,9 +470,9 @@ && (cardVendor[n].vendor_id == vendor_id || cardVendor[n].vendor_id == 0)) break; tp->port_select = cardVendor[n].port_select; - tp->port_error = cardVendor[n].port_error; + tp->port_fail = cardVendor[n].port_fail; tp->signature = cardVendor[n].signature; - return(cardVendor[n].signature); + return(cardVendor[n].array ? 1: 0); } static int @@ -510,22 +491,21 @@ for (i = 10; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; tio_write(EE_ENB | dataval, CSR9); - eeprom_delay(100); + udelay(100); tio_write(EE_ENB | dataval | EE_SHIFT_CLK, CSR9); - eeprom_delay(150); + udelay(150); tio_write(EE_ENB | dataval, CSR9); - /* Finish EEPROM a clock tick. */ - eeprom_delay(250); + udelay(250); } tio_write(EE_ENB, CSR9); for (i = 16; i > 0; i--) { tio_write(EE_ENB | EE_SHIFT_CLK, CSR9); - eeprom_delay(100); + udelay(100); val = (val << 1) | ((tio_read(CSR9) & EE_DATA_READ) ? 1 : 0); tio_write(EE_ENB, CSR9); - eeprom_delay(100); + udelay(100); } /* Terminate the EEPROM access. */ @@ -540,9 +520,9 @@ return(-1); /* broken */ } -/* Is this correct ? */ +/* Is this required ? */ static int -generic21040_error(struct device *dev) +generic21040_fail(struct device *dev) { int ioaddr = dev->base_addr; @@ -550,37 +530,38 @@ } static int -generic21041_error(struct device *dev) +generic21041_fail(struct device *dev) { int ioaddr = dev->base_addr; + u32 csr12 = tio_read(CSR12); - return(tio_read(CSR12) & TSIAS_LNKERROR); + return((!(csr12 & TSIAS_CONERROR) + || !(csr12 & TSIAS_LNKERROR)) ? 0: 1); } static void generic21040_select(struct device *dev) { int ioaddr = dev->base_addr; - const char *if_port; + const char *media; dev->if_port &= 3; switch (dev->if_port) { case TULIP_10TP_PORT: - if_port = "10baseT"; + media = "10baseT"; break; - case TULIP_100TP_PORT: - /* TULIP_AUI_PORT is the same as TULIP_100TP_PORT. */ - if_port = "100baseT/AUI"; + case TULIP_AUI_PORT: + media = "AUI"; break; case TULIP_BNC_PORT: - if_port = "BNC"; + media = "BNC"; break; default: - if_port = "unknown type"; + media = "unknown type"; break; } - printk("%s: enabling %s port.\n", dev->name, if_port); + printk("%s: enabling %s port.\n", dev->name, media); /* Set the full duplex match frame. */ tio_write(FULL_DUPLEX_MAGIC, CSR11); tio_write(TSIAC_RESET, CSR13); @@ -588,6 +569,17 @@ tio_write((dev->if_port ? TSIAC_NO10TP: 0) | TSIAC_C21040, CSR13); } +#if 0 +static void +generic_timer(struct device *dev, u32 count) +{ + int ioaddr = dev->base_addr; + + tio_write(count, CSR11); + while (tio_read(CSR11) & TGEPT_COUNT); +} +#endif + static void generic21041_select(struct device *dev) { @@ -596,33 +588,32 @@ u32 tsiax = TSIAX_10TP; u32 tsiag = TSIAG_10TP; - printk("%s: enabling ", dev->name); switch(dev->if_port) { case TULIP_AUI_PORT: tsiac |= TSIAC_NO10TP; tsiax = TSIAX_NO10TP; tsiag = TSIAG_AUI; - printk("AUI"); break; case TULIP_BNC_PORT: tsiac |= TSIAC_NO10TP; tsiax = TSIAX_NO10TP; tsiag = TSIAG_BNC; - printk("BNC"); break; default: dev->if_port = TULIP_10TP_PORT; - printk("10TP"); break; } tio_sia_write(ioaddr, tsiac, tsiax, tsiag); - printk(" port.\n"); + if (dev->start) + printk("%s: enabling %s port.\n", dev->name, + (dev->if_port == TULIP_AUI_PORT) ? "AUI": + (dev->if_port == TULIP_BNC_PORT) ? "BNC": "10TP"); } static void auto21140_select(struct device *dev) { - int ioaddr = dev->base_addr; + int i, ioaddr = dev->base_addr; struct tulip_private *tp = (struct tulip_private *)dev->priv; /* kick port */ @@ -631,15 +622,35 @@ tio_write(TCMOD_AUTO|TCMOD_TRxSTART, CSR6); dev->if_port = !(tio_read(CSR12) & TGEPR_FORCEALED); printk("%s: probed %s port.\n", - dev->name, dev->if_port ? "100baseTx" : "10baseT"); + dev->name, dev->if_port ? "100TX" : "10TP"); tio_write((dev->if_port ? TGEPR_FORCE100: 0) | (tp->full_duplex ? 0:TGEPR_HALFDUPLEX), CSR12); tio_write(TINTR_DISABLE, CSR7); - tio_read(CSR8) & 0xffff; + i = tio_read(CSR8) & 0xffff; tio_write(TCMOD_AUTO, CSR6); } static void +cogent21140_select(struct device *dev) +{ + int ioaddr = dev->base_addr, csr6; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + dev->if_port &= 1; + csr6 = tio_read(CSR6) & + ~(TCMOD_10TP|TCMOD_100TP|TCMOD_TRxSTART|TCMOD_SCRM); + /* Stop the transmit process. */ + tio_write(csr6 | TCMOD_RxSTART, CSR6); + printk("%s: enabling %s port.\n", + dev->name, dev->if_port ? "100baseTx" : "10baseT"); + /* Turn on the output drivers */ + tio_write(0x0000013F, CSR12); + tio_write((dev->if_port ? TGEPR_FORCE100: 0) + | (tp->full_duplex ? 0:TGEPR_HALFDUPLEX), CSR12); + tio_write((dev->if_port ? TCMOD_100TP: TCMOD_10TP) + | TCMOD_TRxSTART | TCMOD_TH128 | csr6, CSR6); +} + +static void generic21140_select(struct device *dev) { int ioaddr = dev->base_addr, csr6; @@ -651,8 +662,9 @@ /* Stop the transmit process. */ tio_write(csr6 | TCMOD_RxSTART, CSR6); - printk("%s: enabling %s port.\n", - dev->name, dev->if_port ? "100baseTx" : "10baseT"); + if (dev->start) + printk("%s: enabling %s port.\n", + dev->name, dev->if_port ? "100TX" : "10TP"); tio_write((dev->if_port ? TCMOD_100TP: TCMOD_10TP) | TCMOD_TRxSTART | TCMOD_TH128 | csr6, CSR6); tio_write((dev->if_port ? TGEPR_FORCE100: 0) @@ -667,31 +679,16 @@ /* Reset the chip, holding bit 0 set at least 10 PCI cycles. */ tio_write(tio_read(CSR0)|TBMOD_RESET, CSR0); -/* tio_write(TBMOD_RESERVED|TBMOD_RESET, CSR0);*/ - SLOW_DOWN_IO; + udelay(1000); /* Deassert reset. Set 8 longword cache alignment, 8 longword burst. -> Set 32 longword cache alignment, unlimited longword burst ? Wait the specified 50 PCI cycles after a reset by initializing Tx and Rx queues and the address filter list. */ tio_write(tio_read(CSR0)|TBMOD_ALIGN32|TBMOD_BURST0, CSR0); -/* tio_write(TBMOD_RESERVED|TBMOD_ALIGN32|TBMOD_BURST0, CSR0);*/ - if (irq2dev_map[dev->irq] != NULL - || (irq2dev_map[dev->irq] = dev) == NULL - || dev->irq == 0 -#if LINUX_VERSION_CODE < 0x10346 - || request_irq(dev->irq, &tulip_interrupt, 0, tp->signature)) { -#else - || request_irq(dev->irq, (void *)&tulip_interrupt, 0, - tp->signature, dev)) { -#endif + if (request_irq(dev->irq, (void *)&tulip_interrupt, SA_SHIRQ, + tp->signature, dev)) return -EAGAIN; - } - -/* - if (tulip_debug > 1) - printk("%s: tulip_open() irq %d.\n", dev->name, dev->irq); -*/ tulip_init_ring(dev); @@ -722,8 +719,12 @@ tio_write(virt_to_bus(tp->rx_ring), CSR3); tio_write(virt_to_bus(tp->tx_ring), CSR4); - dev->if_port = TULIP_PORT; + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + if (tp->port_select) tp->port_select(dev); + /* Start the chip's Tx and Rx processes. */ tio_write(tio_read(CSR6) | TCMOD_TRxSTART | (tp->full_duplex ? TCMOD_FULLDUPLEX:0), CSR6); @@ -731,10 +732,6 @@ /* Trigger an immediate transmit demand to process the setup frame. */ tio_write(TPOLL_TRIGGER, CSR1); - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; - /* Enable interrupts by setting the interrupt mask. */ tio_write(TINTR_ENABLE, CSR7); @@ -778,13 +775,12 @@ int entry; /* Transmitter timeout, serious problems. */ - if (dev->tbusy) { + if (dev->tbusy || (tp->port_fail && tp->port_fail(dev))) { int tickssofar = jiffies - dev->trans_start; int i; if (tickssofar < 40) return(1); - if (tp->port_select - && (!tp->port_error || tp->port_error(dev))) { - dev->if_port ++; + if (tp->port_select) { + if (!tp->port_fix) dev->if_port ++; tp->port_select(dev); dev->trans_start = jiffies; return(0); @@ -793,10 +789,14 @@ "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n", dev->name, tio_read(CSR5), tio_read(CSR12), tio_read(CSR13), tio_read(CSR14), tio_read(CSR15)); +#ifndef __alpha__ printk(" Rx ring %8.8x: ", (int)tp->rx_ring); +#endif for (i = 0; i < RX_RING_SIZE; i++) printk(" %8.8x", (unsigned int)tp->rx_ring[i].status); +#ifndef __alpha__ printk("\n Tx ring %8.8x: ", (int)tp->tx_ring); +#endif for (i = 0; i < TX_RING_SIZE; i++) printk(" %8.8x", (unsigned int)tp->tx_ring[i].status); printk("\n"); @@ -856,9 +856,9 @@ /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void tulip_interrupt(int irq, struct pt_regs *regs) +static void tulip_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)(irq2dev_map[irq]); + struct device *dev = (struct device *)dev_id; struct tulip_private *lp; int csr5, ioaddr, boguscnt=10; @@ -878,7 +878,6 @@ csr5 = tio_read(CSR5); /* Acknowledge all of the current interrupt sources ASAP. */ tio_write(csr5 & TSTAT_CLEARINTR, CSR5); - /* check interrupt ? */ if ((csr5 & (TSTAT_NORINTR|TSTAT_ABNINTR)) == 0) break; @@ -967,11 +966,7 @@ if (dev->start == 0 && --stopit < 0) { printk("%s: Emergency stop, looping startup interrupt.\n", dev->name); -#if LINUX_VERSION_CODE < 0x10346 - free_irq(irq); -#else free_irq(irq, dev); -#endif } } @@ -1005,11 +1000,7 @@ short pkt_len = lp->rx_ring[entry].status >> 16; struct sk_buff *skb; -#if LINUX_VERSION_CODE < 0x10300 - skb = alloc_skb(pkt_len, GFP_ATOMIC); -#else skb = dev_alloc_skb(pkt_len + 2); -#endif if (skb == NULL) { printk("%s: Memory squeeze, deferring packet.\n", dev->name); @@ -1027,17 +1018,11 @@ break; } skb->dev = dev; -#if LINUX_VERSION_CODE < 0x10300 - skb->len = pkt_len; - memcpy(skb->data, bus_to_virt(lp->rx_ring[entry].buffer1), - pkt_len); -#else skb_reserve(skb, 2); memcpy(skb_put(skb, pkt_len), bus_to_virt(lp->rx_ring[entry].buffer1), pkt_len); /* Needed for 1.3.x */ skb->protocol = eth_type_trans(skb,dev); -#endif netif_rx(skb); lp->stats.rx_packets++; } @@ -1069,24 +1054,29 @@ tio_write(0, CSR13); /* tio_write(0, CSR8); wake up chip ? */ -#if LINUX_VERSION_CODE < 0x10346 - free_irq(dev->irq); -#else free_irq(dev->irq, dev); -#endif - irq2dev_map[dev->irq] = 0; MOD_DEC_USE_COUNT; return(0); } +static int +tulip_config(struct device *dev, struct ifmap *map) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + + if (map->port == 0xff) return(-EINVAL); + dev->if_port = map->port; + tp->port_fix = 1; + if (tp->port_select) tp->port_select(dev); + return(0); +} + static struct enet_statistics * tulip_get_stats(struct device *dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; - short ioaddr = dev->base_addr; - - tp->stats.rx_missed_errors += tio_read(CSR8) & 0xffff; + /* short ioaddr = dev->base_addr;*/ return(&tp->stats); } @@ -1095,12 +1085,7 @@ * Set or clear the multicast filter for this adaptor. */ -#if LINUX_VERSION_CODE < 0x10300 -static void set_multicast_list(struct device *dev, int num_addrs, - void *addrs) -#else static void set_multicast_list(struct device *dev) -#endif { short ioaddr = dev->base_addr; int csr6 = tio_read(CSR6) & ~(TCMOD_MODEMASK|TCMOD_FILTERMASK); @@ -1128,12 +1113,9 @@ 16 address perfect filtering of the Tulip. Note that only the low shortword of setup_frame[] is valid. */ tio_write(csr6 | 0x0000, CSR6); - i=0; - while(dmi) - { + for (i = 0; i < dev->mc_count; i ++) { eaddrs=(unsigned short *)dmi->dmi_addr; dmi=dmi->next; - i++; *setup_frm++ = *eaddrs++; *setup_frm++ = *eaddrs++; *setup_frm++ = *eaddrs++; @@ -1150,28 +1132,12 @@ } } -#if 0 -static int -set_mac_address(struct device *dev, void *addr) -{ - int i; - struct sockaddr *sa=(struct sockaddr *)addr; - if (dev->start) - return -EBUSY; - printk("%s: Setting MAC address to ", dev->name); - for (i = 0; i < ETH_ALEN - 1; i++) - printk("%2.2x:", dev->dev_addr[i] = sa->sa_data[i]); - printk("%2.2x.\n", dev->dev_addr[i] = sa->sa_data[i]); - return 0; -} -#endif - static struct device *tulip_alloc(struct device *dev) { struct tulip_private *tp; char *buff; #ifndef MODULE - int alloc_size; + size_t alloc_size; #endif if (!dev || dev->priv) { struct device *olddev = dev; @@ -1210,14 +1176,14 @@ int irq, int device_id) { /* See note below on the Znyx 315 etherarray. */ - unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'}; - char detect_mesg[80], *mesgp=detect_mesg, *card_name=NULL; + static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'}; + char detect_mesg[80], *mesgp=detect_mesg; struct tulip_private *tp = (struct tulip_private *)dev->priv; int i; unsigned short sum, bitsum; if (check_region(ioaddr, TULIP_TOTAL_SIZE) != 0) { - printk("tulip_alloc: region already allocated at %#3x.\n", + printk("tulip_hwinit: region already allocated at %#3x.\n", ioaddr); return(-1); } @@ -1229,11 +1195,11 @@ /* Stop the chip's Tx and Rx processes. */ tio_write(tio_read(CSR6) & ~TCMOD_TRxSTART, CSR6); /* Clear the missed-packet counter. */ - tio_read(CSR8) & 0xffff; + i = tio_read(CSR8) & 0xffff; if (device_id == PCI_DEVICE_ID_DEC_TULIP_PLUS && (tio_read(CSR9) & 0x8000)) { - mesgp += sprintf(mesgp, "treat as 21040 "); + mesgp += sprintf(mesgp, " treat as 21040"); device_id = PCI_DEVICE_ID_DEC_TULIP; } @@ -1252,7 +1218,7 @@ value = tio_read(CSR9); while (value < 0 && --boguscnt > 0); dev->dev_addr[i] = value; - sum += value; + sum += value & 0xFF; bitsum &= value; } } else { @@ -1282,41 +1248,50 @@ dev->dev_addr[i] = last_phys_addr[i] + 1; } for (i = 0; i < ETH_ALEN - 1; i++) - mesgp += sprintf(mesgp, "%2.2x:", - last_phys_addr[i] = dev->dev_addr[i]); + mesgp += sprintf(mesgp, "%2.2x:", dev->dev_addr[i]); mesgp += sprintf(mesgp, "%2.2x, IRQ %d\n", last_phys_addr[i] = dev->dev_addr[i], irq); - card_name = card_type(tp, device_id, - htonl((*(int*)dev->dev_addr) & 0xFFFFFF)); - + /* copy ethernet address */ + if (card_type(tp, device_id, + htonl((*(int*)dev->dev_addr) & 0xFFFFFF))) + for (i = 0; i < ETH_ALEN - 1; i++) + last_phys_addr[i] = dev->dev_addr[i]; /* We do a request_region() only to register /proc/ioports info. */ request_region(ioaddr, TULIP_TOTAL_SIZE, tp->signature); dev->base_addr = ioaddr; dev->irq = irq; -#ifdef TULIP_FULL_DUPLEX - tp->full_duplex = 1; -#endif - /* The Tulip-specific entries in the device structure. */ dev->open = &tulip_open; dev->hard_start_xmit = &tulip_start_xmit; dev->stop = &tulip_close; dev->get_stats = &tulip_get_stats; + dev->set_config = &tulip_config; dev->set_multicast_list = &set_multicast_list; -#if 0 - dev->set_mac_address = &set_mac_address; -#endif #ifdef MODULE ether_setup(dev); + if (if_port == TULIP_AUTO_PORT) + if_port = TULIP_PORT; + else + tp->port_fix = 1; + dev->if_port = if_port; + tp->full_duplex = full_duplex; #else +#ifdef TULIP_FULL_DUPLEX + tp->full_duplex = 1; +#endif init_etherdev(dev, 0); + dev->if_port = TULIP_PORT; #endif - printk("%s: %s %s", dev->name, card_name, detect_mesg); +#ifdef TULIP_FIX_PORT + tp->port_fix = 1; +#endif + + printk("%s: %s %s", dev->name, tp->signature, detect_mesg); /* Reset the xcvr interface and turn on heartbeat. */ tio_write(TSIAC_RESET, CSR13); @@ -1327,11 +1302,11 @@ int tulip_probe(struct device *dev) { - static u_short probed_irqs=0; + static struct device *tulip_head=NULL; u_char pci_bus, pci_device_fn, pci_latency, pci_irq; u_int pci_ioaddr; u_short pci_command; - u_long pci_chips[] = { + u_int pci_chips[] = { PCI_DEVICE_ID_DEC_TULIP, PCI_DEVICE_ID_DEC_TULIP_FAST, PCI_DEVICE_ID_DEC_TULIP_PLUS, @@ -1349,27 +1324,32 @@ pci_chips[cno], pci_index, &pci_bus, &pci_device_fn) == 0) { - /* get IRQ */ - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - if (probed_irqs & (1 << pci_irq)) continue; + struct device *dp; + /* get IO address */ pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_0, &pci_ioaddr); /* Remove I/O space marker in bit 0. */ pci_ioaddr &= ~3; + for (dp = tulip_head; dp != NULL; dp = dp->next) + if (dp->base_addr == pci_ioaddr) break; + if (dp) continue; + /* get IRQ */ + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); #ifdef MODULE /* compare requested IRQ/IO address */ - if (dev && dev->irq && dev->base_addr && - (dev->irq != pci_irq - || dev->base_addr != pci_ioaddr)) continue; + if (dev && dev->base_addr && + dev->base_addr != pci_ioaddr) continue; #else if ((dev = tulip_alloc(dev)) == NULL) break; #endif - if (!probed_irqs) printk(version); - probed_irqs |= (1 << pci_irq); - + if (!tulip_head) { + printk(version); + tulip_head = dev; + } + /* Get and check the bus-master and latency values. */ pcibios_read_config_word(pci_bus, pci_device_fn, PCI_COMMAND, &pci_command); @@ -1393,17 +1373,27 @@ if (tulip_hwinit(dev, pci_ioaddr, pci_irq, pci_chips[cno]) < 0) continue; num ++; -#if defined(MODULE) || defined(TULIP_ONLY_ONE) +#ifdef MODULE return(0); #endif +#ifdef TULIP_MAX_CARDS + if (num >= TULIP_MAX_CARDS) return(0); +#endif } } return(num > 0 ? 0: -ENODEV); } #ifdef MODULE -static int io = 0xfc00; -static int irq = 9; +#ifdef __alpha__ +#if 1 +static int io = 0xb000; +#else +static int io = 0x10400; +#endif +#else +static int io = 0xfc80; +#endif static struct device *mod_dev; @@ -1412,7 +1402,7 @@ if ((mod_dev = tulip_alloc(0)) == NULL) return(-EIO); mod_dev->base_addr = io; - mod_dev->irq = irq; + mod_dev->irq = 0; mod_dev->init = &tulip_probe; if (register_netdev(mod_dev)) { diff -u --recursive --new-file v1.3.90/linux/drivers/net/wic.c linux/drivers/net/wic.c --- v1.3.90/linux/drivers/net/wic.c Mon Apr 15 12:20:18 1996 +++ linux/drivers/net/wic.c Thu Apr 18 14:35:33 1996 @@ -1,6 +1,7 @@ /* $Id: wic.c,v 1.0 1995/02/11 10:26:05 hayes Exp $ */ /* WIC: A parallel port "network" driver for Linux. */ /* based on the plip network driver */ +/* Modified for Linux 1.3.x by Alan Cox */ char *version = "NET3 WIC version 0.9 hayes@netplumbing.com"; @@ -90,8 +91,7 @@ int ack_resp(struct device *dev); int check_bfr(struct device *dev); void wic_reset(struct device *dev); -void wic_set_multicast_list(struct device *dev, int num_addrs, - void *addrs); +void wic_set_multicast_list(struct device *dev); #define LOOPCNT 30000 unsigned char tog = 3; @@ -249,12 +249,12 @@ nl->nibble = WIC_NIBBLE_WAIT; /* Initialize task queue structures */ - nl->immediate.next = &tq_last; + nl->immediate.next = NULL; nl->immediate.sync = 0; nl->immediate.routine = (void *)(void *)wic_bh; nl->immediate.data = dev; - nl->deferred.next = &tq_last; + nl->deferred.next = NULL; nl->deferred.sync = 0; nl->deferred.routine = (void *)(void *)wic_kick_bh; nl->deferred.data = dev; @@ -309,7 +309,7 @@ }; void -wic_set_multicast_list(struct device *dev, int num_addrs, void *addrs) +wic_set_multicast_list(struct device *dev) { struct wicconf wc; struct wic_net *wn; @@ -327,16 +327,22 @@ while ((wc.len == 1) && (wc.data[0] == 0x7)) /* controller int */ wc.len = recv_cmd_resp(dev, (unsigned char *)&wc.data); wn = (struct wic_net *)&wc.data; - switch (num_addrs) { - case -1: /* promiscuous mode */ - wn->mode |= (NET_MODE_ME | NET_MODE_BCAST | - NET_MODE_MCAST | NET_MODE_PROM); - printk("%s: Setting promiscuous mode\n", dev->name); - break; - default: /* my address and bcast addresses */ - wn->mode &= ~(NET_MODE_PROM | NET_MODE_MCAST); - wn->mode |= (NET_MODE_ME | NET_MODE_BCAST); - /* break; */ + if(dev->flags&IFF_PROMISC) + { + /* promiscuous mode */ + wn->mode |= (NET_MODE_ME | NET_MODE_BCAST | + NET_MODE_MCAST | NET_MODE_PROM); + printk("%s: Setting promiscuous mode\n", dev->name); + } + else if((dev->flags&IFF_ALLMULTI) || dev->mc_count) + { + wn->mode &= ~NET_MODE_PROM; + wn->mode |= (NET_MODE_MCAST | NET_MODE_ME | NET_MODE_BCAST); + } + else + { + wn->mode &= ~(NET_MODE_PROM | NET_MODE_MCAST); + wn->mode |= (NET_MODE_ME | NET_MODE_BCAST); } wc.len = 23; wc.pcmd = WIC_SETNET; @@ -1381,8 +1387,6 @@ } #ifdef MODULE -char kernel_version[] = UTS_RELEASE; - struct device dev_wic0 = { "wic0" /*"wic"*/, diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c --- v1.3.90/linux/drivers/scsi/BusLogic.c Wed Apr 17 09:06:32 1996 +++ linux/drivers/scsi/BusLogic.c Wed Apr 17 09:01:19 1996 @@ -25,7 +25,7 @@ #define BusLogic_DriverVersion "1.3.2" -#define BusLogic_DriverDate "13 April 1996" +#define BusLogic_DriverDate "16 April 1996" #include @@ -1676,15 +1676,15 @@ return true; } /* - Issue the Inquire Devices command for "W" and "C" Series boards or the - Inquire Installed Devices ID 0 to 7 command for "S" and "A" Series boards. + Issue the Inquire Devices command for boards with firmware version 4.25 or + later, or the Inquire Installed Devices ID 0 to 7 command for older boards. This is necessary to force Synchronous Transfer Negotiation so that the Inquire Setup Information and Inquire Synchronous Period commands will return valid data. The Inquire Devices command is preferable to Inquire Installed Devices ID 0 to 7 since it only probes Logical Unit 0 of each Target Device. */ - if (HostAdapter->FirmwareVersion[0] >= '4') + if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) { if (BusLogic_Command(HostAdapter, BusLogic_InquireDevices, NULL, 0, &InstalledDevices, sizeof(InstalledDevices)) @@ -2342,7 +2342,7 @@ { BusLogic_ResetHostAdapter(HostAdapter, NULL, 0); HostAdapter->HostAdapterResetRequested = false; - scsi_mark_host_bus_reset(HostAdapter->SCSI_Host); + scsi_mark_host_reset(HostAdapter->SCSI_Host); } } @@ -2788,7 +2788,7 @@ } for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) HostAdapter->LastResetTime[TargetID] = jiffies; - Result = SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET; + Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET; /* Release exclusive access to Host Adapter. */ @@ -2973,7 +2973,9 @@ HostAdapter->HostNumber, TargetID); } if (ErrorRecoveryStrategy == BusLogic_ErrorRecovery_Default) - if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET) + if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET) + ErrorRecoveryStrategy = BusLogic_ErrorRecovery_HardReset; + else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET) ErrorRecoveryStrategy = BusLogic_ErrorRecovery_HardReset; else ErrorRecoveryStrategy = BusLogic_ErrorRecovery_BusDeviceReset; switch (ErrorRecoveryStrategy) diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/ChangeLog linux/drivers/scsi/ChangeLog --- v1.3.90/linux/drivers/scsi/ChangeLog Mon Apr 15 12:20:19 1996 +++ linux/drivers/scsi/ChangeLog Wed Apr 17 09:01:19 1996 @@ -1,4 +1,4 @@ -Sat Apr 13 13:58:00 1996 Leonard N. Zubkoff +Tue Apr 16 21:00:00 1996 Leonard N. Zubkoff * BusLogic Driver Version 1.3.2 Released. diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/README.BusLogic linux/drivers/scsi/README.BusLogic --- v1.3.90/linux/drivers/scsi/README.BusLogic Mon Apr 15 12:20:19 1996 +++ linux/drivers/scsi/README.BusLogic Wed Apr 17 09:01:19 1996 @@ -3,7 +3,7 @@ Version 1.2.2 for Linux 1.2.13 Version 1.3.2 for Linux 1.3.88 - 13 April 1996 + 16 April 1996 Leonard N. Zubkoff Dandelion Digital diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c --- v1.3.90/linux/drivers/scsi/eata.c Fri Mar 1 07:50:52 1996 +++ linux/drivers/scsi/eata.c Thu Apr 18 14:56:45 1996 @@ -1,6 +1,9 @@ /* * eata.c - Low-level driver for EATA/DMA SCSI host adapters. * + * 16 Apr 1996 rev. 2.10 for linux 1.3.90 + * New argument "reset_flags" to the reset routine. + * * 6 Jul 1995 rev. 2.01 for linux 1.3.7 * Update required by the new /proc/scsi support. * @@ -64,7 +67,7 @@ * This driver is based on the CAM (Common Access Method Committee) * EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol. * - * Copyright (C) 1994, 1995 Dario Ballabio (dario@milano.europe.dg.com) + * Copyright (C) 1994, 1995, 1996 Dario Ballabio (dario@milano.europe.dg.com) * */ @@ -581,7 +584,7 @@ } if (j > 0) - printk("EATA/DMA 2.0x: Copyright (C) 1994, 1995 Dario Ballabio.\n"); + printk("EATA/DMA 2.0x: Copyright (C) 1994, 1995, 1996 Dario Ballabio.\n"); restore_flags(flags); return j; @@ -639,7 +642,8 @@ if (HD(j)->in_reset) printk("%s: qcomm, already in reset.\n", BN(j)); - else if (eata2x_reset(SCpnt) == SCSI_RESET_SUCCESS) + else if (eata2x_reset(SCpnt, SCSI_RESET_SUGGEST_BUS_RESET) + == SCSI_RESET_SUCCESS) panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j)); SCpnt->result = DID_BUS_BUSY << 16; @@ -772,7 +776,7 @@ panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); } -int eata2x_reset (Scsi_Cmnd *SCarg) { +int eata2x_reset (Scsi_Cmnd *SCarg, unsigned int reset_flags) { unsigned int i, j, flags, time, k, limit = 0; int arg_done = FALSE; Scsi_Cmnd *SCpnt; @@ -780,8 +784,8 @@ save_flags(flags); cli(); j = ((struct hostdata *) SCarg->host->hostdata)->board_number; - printk("%s: reset, enter, target %d, pid %ld.\n", - BN(j), SCarg->target, SCarg->pid); + printk("%s: reset, enter, target %d, pid %ld, reset_flags %u.\n", + BN(j), SCarg->target, SCarg->pid, reset_flags); if (SCarg->host_scribble == NULL) printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); @@ -847,7 +851,7 @@ HD(j)->in_reset = TRUE; sti(); time = jiffies; - while (jiffies < (time + 100) && limit++ < 100000000); + while ((jiffies - time) < HZ && limit++ < 100000000); cli(); printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/eata.h linux/drivers/scsi/eata.h --- v1.3.90/linux/drivers/scsi/eata.h Thu Sep 21 09:01:48 1995 +++ linux/drivers/scsi/eata.h Thu Apr 18 14:56:45 1996 @@ -1,6 +1,5 @@ /* * eata.h - used by the low-level driver for EATA/DMA SCSI host adapters. - * */ #ifndef _EATA_H #define _EATA_H @@ -10,9 +9,9 @@ int eata2x_detect(Scsi_Host_Template *); int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int eata2x_abort(Scsi_Cmnd *); -int eata2x_reset(Scsi_Cmnd *); +int eata2x_reset(Scsi_Cmnd *, unsigned int); -#define EATA_VERSION "2.01.00" +#define EATA_VERSION "2.10.00" #define EATA { \ diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c --- v1.3.90/linux/drivers/scsi/g_NCR5380.c Mon Apr 15 12:20:19 1996 +++ linux/drivers/scsi/g_NCR5380.c Wed Apr 17 09:01:18 1996 @@ -50,6 +50,23 @@ * * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an * IRQ line if overridden on the command line. + * + * 3. When included as a module, with arguments passed on the command line: + * ncr_irq=xx the interrupt + * ncr_addr=xx the port or base address (for port or memory + * mapped, resp.) + * ncr_dma=xx the DMA + * ncr_5380=1 to set up for a NCR5380 board + * ncr_53c400=1 to set up for a NCR53C400 board + * e.g. + * modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1 + * for a port mapped NCR5380 board or + * modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1 + * for a memory mapped NCR53C400 board with interrupts disabled. + * + * 255 should be specified for no or DMA interrupt, 254 to autoprobe for an + * IRQ line if overridden on the command line. + * */ /* @@ -93,6 +110,13 @@ S_IFDIR | S_IRUGO | S_IXUGO, 2 }; +#define NCR_NOT_SET 0 +static int ncr_irq=NCR_NOT_SET; +static int ncr_dma=NCR_NOT_SET; +static int ncr_addr=NCR_NOT_SET; +static int ncr_5380=NCR_NOT_SET; +static int ncr_53c400=NCR_NOT_SET; + static struct override { NCR5380_implementation_fields; int irq; @@ -189,6 +213,17 @@ int flags = 0; struct Scsi_Host *instance; + if (ncr_irq != NCR_NOT_SET) + overrides[0].irq=ncr_irq; + if (ncr_dma != NCR_NOT_SET) + overrides[0].dma=ncr_dma; + if (ncr_addr != NCR_NOT_SET) + overrides[0].NCR5380_map_name=(NCR5380_map_type)ncr_addr; + if (ncr_5380 != NCR_NOT_SET) + overrides[0].board=BOARD_NCR5380; + else if (ncr_53c400 != NCR_NOT_SET) + overrides[0].board=BOARD_NCR53C400; + tpnt->proc_dir = &proc_scsi_g_ncr5380; for (count = 0; current_override < NO_OVERRIDES; ++current_override) { @@ -253,7 +288,8 @@ NCR5380_setup(instance); - free_irq(instance->irq, NULL); + if (instance->irq != IRQ_NONE) + free_irq(instance->irq, NULL); return 0; } diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v1.3.90/linux/drivers/scsi/scsi.c Wed Apr 17 09:06:32 1996 +++ linux/drivers/scsi/scsi.c Wed Apr 17 09:01:19 1996 @@ -1935,14 +1935,25 @@ /* Mark all SCSI Devices on a specific Host as having been reset. */ -void scsi_mark_host_bus_reset(struct Scsi_Host *Host) +void scsi_mark_host_reset(struct Scsi_Host *Host) { Scsi_Cmnd *SCpnt; - for(SCpnt = Host->host_queue; SCpnt; SCpnt = SCpnt->next) + for (SCpnt = Host->host_queue; SCpnt; SCpnt = SCpnt->next) scsi_mark_device_reset(SCpnt->device); } +/* Mark all SCSI Devices on a specific Host Bus as having been reset. */ + +void scsi_mark_bus_reset(struct Scsi_Host *Host, int channel) +{ + Scsi_Cmnd *SCpnt; + for (SCpnt = Host->host_queue; SCpnt; SCpnt = SCpnt->next) + if (SCpnt->channel == channel) + scsi_mark_device_reset(SCpnt->device); +} + + int scsi_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags) { int temp; @@ -2071,8 +2082,10 @@ */ switch(temp & SCSI_RESET_ACTION) { case SCSI_RESET_SUCCESS: - if (temp & SCSI_RESET_BUS_RESET) - scsi_mark_host_bus_reset(host); + if (temp & SCSI_RESET_HOST_RESET) + scsi_mark_host_reset(host); + else if (temp & SCSI_RESET_BUS_RESET) + scsi_mark_bus_reset(host, SCpnt->channel); else scsi_mark_device_reset(SCpnt->device); save_flags(flags); cli(); @@ -2080,8 +2093,10 @@ restore_flags(flags); return 0; case SCSI_RESET_PENDING: - if (temp & SCSI_RESET_BUS_RESET) - scsi_mark_host_bus_reset(host); + if (temp & SCSI_RESET_HOST_RESET) + scsi_mark_host_reset(host); + else if (temp & SCSI_RESET_BUS_RESET) + scsi_mark_bus_reset(host, SCpnt->channel); else scsi_mark_device_reset(SCpnt->device); case SCSI_RESET_NOT_RUNNING: return 0; @@ -2090,8 +2105,10 @@ scsi_request_sense (SCpnt); return 0; case SCSI_RESET_WAKEUP: - if (temp & SCSI_RESET_BUS_RESET) - scsi_mark_host_bus_reset(host); + if (temp & SCSI_RESET_HOST_RESET) + scsi_mark_host_reset(host); + else if (temp & SCSI_RESET_BUS_RESET) + scsi_mark_bus_reset(host, SCpnt->channel); else scsi_mark_device_reset(SCpnt->device); SCpnt->internal_timeout &= ~IN_RESET; scsi_request_sense (SCpnt); diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h --- v1.3.90/linux/drivers/scsi/scsi.h Wed Apr 17 09:06:32 1996 +++ linux/drivers/scsi/scsi.h Wed Apr 17 09:01:19 1996 @@ -317,13 +317,18 @@ #define SCSI_RESET_SYNCHRONOUS 0x01 #define SCSI_RESET_ASYNCHRONOUS 0x02 #define SCSI_RESET_SUGGEST_BUS_RESET 0x04 - +#define SCSI_RESET_SUGGEST_HOST_RESET 0x08 /* * This is a bitmask that is ored with one of the above codes. * It tells the mid-level code that we did a hard reset. */ #define SCSI_RESET_BUS_RESET 0x100 /* + * This is a bitmask that is ored with one of the above codes. + * It tells the mid-level code that we did a host adapter reset. + */ +#define SCSI_RESET_HOST_RESET 0x200 +/* * Used to mask off bits and to obtain the basic action that was * performed. */ @@ -477,7 +482,8 @@ extern void print_driverbyte(int scsiresult); extern void print_hostbyte(int scsiresult); -extern void scsi_mark_host_bus_reset(struct Scsi_Host *Host); +extern void scsi_mark_host_reset(struct Scsi_Host *Host); +extern void scsi_mark_bus_reset(struct Scsi_Host *Host, int channel); #if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR) #include "hosts.h" diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c --- v1.3.90/linux/drivers/scsi/scsi_syms.c Thu Feb 15 09:21:30 1996 +++ linux/drivers/scsi/scsi_syms.c Wed Apr 17 09:01:19 1996 @@ -61,7 +61,8 @@ X(need_isa_buffer), X(request_queueable), X(print_Scsi_Cmnd), - X(scsi_mark_host_bus_reset), + X(scsi_mark_host_reset), + X(scsi_mark_bus_reset), #if defined(CONFIG_PROC_FS) X(proc_print_scsidevice), #endif diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c --- v1.3.90/linux/drivers/scsi/u14-34f.c Fri Apr 12 15:52:01 1996 +++ linux/drivers/scsi/u14-34f.c Thu Apr 18 14:56:45 1996 @@ -1,9 +1,15 @@ /* * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. * + * 16 Apr 1996 rev. 2.10 for linux 1.3.90 + * New argument "reset_flags" to the reset routine. + * + * 21 Jul 1995 rev. 2.02 for linux 1.3.11 + * Fixed Data Transfer Direction for some SCSI commands. + * * 13 Jun 1995 rev. 2.01 for linux 1.2.10 - * HAVE_OLD_UX4F_FIRMWARE should be defined for U34F boards when - * the firmware prom is not the latest one (28008-006). + * HAVE_OLD_UX4F_FIRMWARE should be defined for U34F boards when + * the firmware prom is not the latest one (28008-006). * * 11 Mar 1995 rev. 2.00 for linux 1.2.0 * Fixed a bug which prevented media change detection for removable @@ -55,7 +61,7 @@ * * Multiple U14F and/or U34F host adapters are supported. * - * Copyright (C) 1994, 1995 Dario Ballabio (dario@milano.europe.dg.com) + * Copyright (C) 1994, 1995, 1996 Dario Ballabio (dario@milano.europe.dg.com) * * WARNING: if your 14/34F board has an old firmware revision (see below) * you must change "#undef" into "#define" in the following @@ -226,6 +232,8 @@ #define ASOK 0x00 #define ASST 0x91 +#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0]) + #define PACKED __attribute__((packed)) /* MailBox SCSI Command Packet */ @@ -330,7 +338,7 @@ sti(); time = jiffies; - while (jiffies < (time + 100) && limit++ < 100000000); + while ((jiffies - time) < HZ && limit++ < 100000000); cli(); if (cpp->adapter_status || HD(j)->cp_stat[0] != FREE) { @@ -540,7 +548,7 @@ } if (j > 0) - printk("UltraStor 14F/34F: Copyright (C) 1994, 1995 Dario Ballabio.\n"); + printk("UltraStor 14F/34F: Copyright (C) 1994, 1995, 1996 Dario Ballabio.\n"); restore_flags(flags); return j; @@ -567,6 +575,12 @@ unsigned int i, j, k, flags; struct mscp *cpp; + static const unsigned char data_out_cmds[] = { + 0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x0b, 0x10, 0x16, 0x18, 0x1d, + 0x24, 0x2b, 0x2e, 0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, + 0x3f, 0x40, 0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea + }; + save_flags(flags); cli(); /* j is the board number */ @@ -593,7 +607,8 @@ if (HD(j)->in_reset) printk("%s: qcomm, already in reset.\n", BN(j)); - else if (u14_34f_reset(SCpnt) == SCSI_RESET_SUCCESS) + else if (u14_34f_reset(SCpnt, SCSI_RESET_SUGGEST_BUS_RESET) + == SCSI_RESET_SUCCESS) panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j)); SCpnt->result = DID_BUS_BUSY << 16; @@ -615,8 +630,15 @@ if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n", BN(j), i, SCpnt->target, SCpnt->pid); + cpp->xdir = DTD_IN; + + for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++) + if (SCpnt->cmnd[0] == data_out_cmds[k]) { + cpp->xdir = DTD_OUT; + break; + } + cpp->opcode = OP_SCSI; - cpp->xdir = DTD_SCSI; cpp->target = SCpnt->target; cpp->lun = SCpnt->lun; cpp->SCpnt = SCpnt; @@ -715,7 +737,7 @@ panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); } -int u14_34f_reset(Scsi_Cmnd * SCarg) { +int u14_34f_reset(Scsi_Cmnd * SCarg, unsigned int reset_flags) { unsigned int i, j, flags, time, k, limit = 0; int arg_done = FALSE; Scsi_Cmnd *SCpnt; @@ -723,8 +745,8 @@ save_flags(flags); cli(); j = ((struct hostdata *) SCarg->host->hostdata)->board_number; - printk("%s: reset, enter, target %d, pid %ld.\n", - BN(j), SCarg->target, SCarg->pid); + printk("%s: reset, enter, target %d, pid %ld, reset_flags %u.\n", + BN(j), SCarg->target, SCarg->pid, reset_flags); if (SCarg->host_scribble == NULL) printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); @@ -791,7 +813,7 @@ HD(j)->in_reset = TRUE; sti(); time = jiffies; - while (jiffies < (time + 100) && limit++ < 100000000); + while ((jiffies - time) < HZ && limit++ < 100000000); cli(); printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); diff -u --recursive --new-file v1.3.90/linux/drivers/scsi/u14-34f.h linux/drivers/scsi/u14-34f.h --- v1.3.90/linux/drivers/scsi/u14-34f.h Mon Sep 18 08:54:10 1995 +++ linux/drivers/scsi/u14-34f.h Thu Apr 18 14:56:45 1996 @@ -7,10 +7,10 @@ int u14_34f_detect(Scsi_Host_Template *); int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int u14_34f_abort(Scsi_Cmnd *); -int u14_34f_reset(Scsi_Cmnd *); +int u14_34f_reset(Scsi_Cmnd *, unsigned int); int u14_34f_biosparam(Disk *, kdev_t, int *); -#define U14_34F_VERSION "2.01.00" +#define U14_34F_VERSION "2.10.00" #define ULTRASTOR_14_34F { \ NULL, /* Ptr for modules */ \ diff -u --recursive --new-file v1.3.90/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c --- v1.3.90/linux/drivers/sound/dmabuf.c Fri Apr 12 15:52:02 1996 +++ linux/drivers/sound/dmabuf.c Thu Apr 18 08:22:20 1996 @@ -770,6 +770,13 @@ } break; + case SNDCTL_DSP_SETDUPLEX: + if (audio_devs[dev]->flags & DMA_DUPLEX) + return 0; + else + return -EIO; + break; + case SNDCTL_DSP_SETFRAGMENT: { int fact = get_fs_long ((long *) arg); diff -u --recursive --new-file v1.3.90/linux/fs/devices.c linux/fs/devices.c --- v1.3.90/linux/fs/devices.c Tue Jan 9 12:26:53 1996 +++ linux/fs/devices.c Wed Apr 17 09:01:19 1996 @@ -19,6 +19,13 @@ #include #ifdef CONFIG_KERNELD #include + +#include + +/* serial module kerneld load support */ +struct tty_driver *get_tty_driver(kdev_t device); +#define isa_tty_dev(ma) (ma == TTY_MAJOR || ma == TTYAUX_MAJOR) +#define need_serial(ma,mi) (get_tty_driver(to_kdev_t(MKDEV(ma,mi))) == NULL) #endif struct device_struct { @@ -53,17 +60,20 @@ } return len; } + /* Return the function table of a device. Load the driver if needed. */ static struct file_operations * get_fops( unsigned int major, + unsigned int minor, unsigned int maxdev, const char *mangle, /* String to use to build the module name */ struct device_struct tb[]) { struct file_operations *ret = NULL; + if (major < maxdev){ #ifdef CONFIG_KERNELD /* @@ -75,8 +85,14 @@ * it locks the reboot process :-( * * Jacques Gelinas (jacques@solucorp.qc.ca) + * + * A. Haritsis : fix for serial module + * though we need the minor here to check if serial dev, + * we pass only the normal major char dev to kerneld + * as there is no other loadable dev on these majors */ - if (!tb[major].fops && major != 0) { + if ((isa_tty_dev(major) && need_serial(major,minor)) || + (major != 0 && !tb[major].fops)) { char name[20]; sprintf(name, mangle, major); request_module(name); @@ -94,12 +110,12 @@ */ struct file_operations * get_blkfops(unsigned int major) { - return get_fops (major,MAX_BLKDEV,"block-major-%d",blkdevs); + return get_fops (major,0,MAX_BLKDEV,"block-major-%d",blkdevs); } -struct file_operations * get_chrfops(unsigned int major) +struct file_operations * get_chrfops(unsigned int major, unsigned int minor) { - return get_fops (major,MAX_CHRDEV,"char-major-%d",chrdevs); + return get_fops (major,minor,MAX_CHRDEV,"char-major-%d",chrdevs); } int register_chrdev(unsigned int major, const char * name, struct file_operations *fops) @@ -271,7 +287,8 @@ int chrdev_open(struct inode * inode, struct file * filp) { int ret = -ENODEV; - filp->f_op = get_chrfops(MAJOR(inode->i_rdev)); + + filp->f_op = get_chrfops(MAJOR(inode->i_rdev), MINOR(inode->i_rdev)); if (filp->f_op != NULL){ ret = 0; if (filp->f_op->open != NULL) diff -u --recursive --new-file v1.3.90/linux/fs/inode.c linux/fs/inode.c --- v1.3.90/linux/fs/inode.c Mon Apr 8 19:01:44 1996 +++ linux/fs/inode.c Wed Apr 17 10:56:16 1996 @@ -497,7 +497,7 @@ repeat: inode = first_inode; best = NULL; - for (i = 0; ii_next, i++) { + for (i = nr_inodes/2; i > 0; i--,inode = inode->i_next) { if (!inode->i_count) { unsigned long i = value(inode); if (i < badness) { diff -u --recursive --new-file v1.3.90/linux/fs/isofs/rock.c linux/fs/isofs/rock.c --- v1.3.90/linux/fs/isofs/rock.c Mon Apr 15 12:20:21 1996 +++ linux/fs/isofs/rock.c Wed Apr 17 08:26:43 1996 @@ -255,6 +255,7 @@ struct inode * inode){ int len; unsigned char * chr; + int symlink_len = 0; CONTINUE_DECLS; if (!inode->i_sb->u.isofs_sb.s_rock) return 0; @@ -334,7 +335,7 @@ struct SL_component * slp; slen = rr->len - 5; slp = &rr->u.SL.link; - inode->i_size = 0; + inode->i_size = symlink_len; while (slen > 1){ rootflag = 0; switch(slp->flags &~1){ @@ -359,8 +360,9 @@ if(slen < 2) break; if(!rootflag) inode->i_size += 1; - }; - }; + } + } + symlink_len = inode->i_size; break; case SIG('R','E'): printk("Attempt to read inode for relocated directory\n"); @@ -458,7 +460,6 @@ repeat: while (len > 1){ /* There may be one byte for padding somewhere */ - if (rpnt) break; rr = (struct rock_ridge *) chr; if (rr->len == 0) goto out; /* Something got screwed up here */ sig = (chr[0] << 8) + chr[1]; diff -u --recursive --new-file v1.3.90/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c --- v1.3.90/linux/fs/ncpfs/dir.c Wed Apr 3 16:06:56 1996 +++ linux/fs/ncpfs/dir.c Wed Apr 17 07:02:16 1996 @@ -189,12 +189,30 @@ static int c_seen_eof; static int c_last_returned_index; static struct ncp_dirent* c_entry = NULL; +static int c_lock = 0; +static struct wait_queue *c_wait = NULL; + +static inline void +ncp_lock_dircache(void) +{ + while (c_lock) + sleep_on(&c_wait); + c_lock = 1; +} + +static inline void +ncp_unlock_dircache(void) +{ + c_lock = 0; + wake_up(&c_wait); +} static int ncp_readdir(struct inode *inode, struct file *filp, void *dirent, filldir_t filldir) { - int result, i = 0; + int result = 0; + int i = 0; int index = 0; struct ncp_dirent *entry = NULL; struct ncp_server *server = NCP_SERVER(inode); @@ -215,6 +233,8 @@ return -EIO; } + ncp_lock_dircache(); + if (c_entry == NULL) { i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE; @@ -222,7 +242,8 @@ if (c_entry == NULL) { printk("ncp_readdir: no MEMORY for cache\n"); - return -ENOMEM; + result = -ENOMEM; + goto finished; } } @@ -232,7 +253,7 @@ if (filldir(dirent,".",1, filp->f_pos, ncp_info_ino(server, dir)) < 0) { - return 0; + goto finished; } filp->f_pos += 1; } @@ -242,7 +263,7 @@ if (filldir(dirent,"..",2, filp->f_pos, ncp_info_ino(server, dir->dir)) < 0) { - return 0; + goto finished; } filp->f_pos += 1; } @@ -261,42 +282,44 @@ } if ((entry == NULL) && c_seen_eof) { - return 0; + goto finished; } } if (entry == NULL) { + int entries; DDPRINTK("ncp_readdir: Not found in cache.\n"); if (ncp_is_server_root(inode)) { - result = ncp_read_volume_list(server, filp->f_pos, - NCP_READDIR_CACHE_SIZE); - DPRINTK("ncp_read_volume_list returned %d\n", result); + entries = ncp_read_volume_list(server, filp->f_pos, + NCP_READDIR_CACHE_SIZE); + DPRINTK("ncp_read_volume_list returned %d\n", entries); } else { - result = ncp_do_readdir(server, inode, filp->f_pos, - NCP_READDIR_CACHE_SIZE, - c_entry); - DPRINTK("ncp_readdir returned %d\n", result); + entries = ncp_do_readdir(server, inode, filp->f_pos, + NCP_READDIR_CACHE_SIZE, + c_entry); + DPRINTK("ncp_readdir returned %d\n", entries); } - if (result < 0) + if (entries < 0) { c_dev = 0; c_ino = 0; - return result; + result = entries; + goto finished; } - if (result > 0) + if (entries > 0) { - c_seen_eof = (result < NCP_READDIR_CACHE_SIZE); + c_seen_eof = (entries < NCP_READDIR_CACHE_SIZE); c_dev = inode->i_dev; c_ino = inode->i_ino; - c_size = result; + c_size = entries; entry = c_entry; c_last_returned_index = 0; index = 0; @@ -311,7 +334,7 @@ if (entry == NULL) { /* Nothing found, even from a ncp call */ - return 0; + goto finished; } while (index < c_size) @@ -363,7 +386,9 @@ index += 1; entry += 1; } - return 0; + finished: + ncp_unlock_dircache(); + return result; } static int @@ -809,6 +834,7 @@ server. */ found_in_cache = 0; + ncp_lock_dircache(); if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino)) { @@ -832,6 +858,7 @@ } while (i != first); } + ncp_unlock_dircache(); if (found_in_cache == 0) { diff -u --recursive --new-file v1.3.90/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- v1.3.90/linux/fs/ncpfs/inode.c Fri Apr 12 15:52:04 1996 +++ linux/fs/ncpfs/inode.c Wed Apr 17 07:02:16 1996 @@ -91,7 +91,7 @@ inode->i_nlink = 1; inode->i_uid = NCP_SERVER(inode)->m.uid; inode->i_gid = NCP_SERVER(inode)->m.gid; - inode->i_blksize = 1024; + inode->i_blksize = 512; inode->i_rdev = 0; if ((inode->i_blksize != 0) && (inode->i_size != 0)) @@ -370,8 +370,10 @@ void ncp_trigger_message(struct ncp_server *server) { +#ifdef CONFIG_KERNELD char command[ sizeof(server->m.mount_point) + sizeof(NCP_MSG_COMMAND) + 2]; +#endif if (server == NULL) { diff -u --recursive --new-file v1.3.90/linux/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c --- v1.3.90/linux/fs/ncpfs/sock.c Wed Apr 3 16:06:56 1996 +++ linux/fs/ncpfs/sock.c Wed Apr 17 07:02:16 1996 @@ -330,6 +330,7 @@ int timeout; int retrans; int major_timeout_seen; + int acknowledge_seen; char *server_name; int n; int addrlen; @@ -352,9 +353,10 @@ return -EBADF; } init_timeout = server->m.time_out; - max_timeout = NCP_MAX_RPC_TIMEOUT*HZ/10; + max_timeout = NCP_MAX_RPC_TIMEOUT; retrans = server->m.retry_count; major_timeout_seen = 0; + acknowledge_seen = 0; server_name = server->m.server_name; old_mask = current->blocked; current->blocked |= ~(_S(SIGKILL) @@ -405,12 +407,15 @@ { if (timeout > max_timeout) { - /* JEJB/JSP 2/7/94 - * This is useful to see if the system is - * hanging */ - printk("NCP max timeout reached on %s\n", - server_name); - timeout = max_timeout; + /* JEJB/JSP 2/7/94 + * This is useful to see if the system is + * hanging */ + if (acknowledge_seen == 0) + { + printk("NCP max timeout reached on " + "%s\n", server_name); + } + timeout = max_timeout; } current->timeout = jiffies + timeout; schedule(); @@ -438,8 +443,8 @@ init_timeout <<= 1; if (!major_timeout_seen) { - printk("NCP server %s not responding, " - "still trying\n", server_name); + printk("NCP server %s not responding, " + "still trying\n", server_name); } major_timeout_seen = 1; continue; @@ -484,6 +489,9 @@ DPRINTK("ncp_rpc_call: got positive acknowledge\n"); _recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0, NULL, &addrlen); + n = 0; + timeout = max_timeout; + acknowledge_seen = 1; goto re_select; } diff -u --recursive --new-file v1.3.90/linux/fs/nfs/dir.c linux/fs/nfs/dir.c --- v1.3.90/linux/fs/nfs/dir.c Sat Apr 13 18:22:07 1996 +++ linux/fs/nfs/dir.c Wed Apr 17 07:50:07 1996 @@ -671,7 +671,6 @@ if (inode->i_size != fattr->size) NFS_CACHEINV(inode); inode->i_size = fattr->size; - inode->i_blksize = fattr->blocksize; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) inode->i_rdev = to_kdev_t(fattr->rdev); else diff -u --recursive --new-file v1.3.90/linux/fs/nfs/inode.c linux/fs/nfs/inode.c --- v1.3.90/linux/fs/nfs/inode.c Mon Apr 15 12:20:21 1996 +++ linux/fs/nfs/inode.c Wed Apr 17 07:50:07 1996 @@ -62,6 +62,12 @@ */ static void nfs_read_inode(struct inode * inode) { + int rsize = inode->i_sb->u.nfs_sb.s_server.rsize; + int size = inode->i_sb->u.nfs_sb.s_server.wsize; + + if (rsize > size) + size = rsize; + inode->i_blksize = size; inode->i_mode = 0; inode->i_op = NULL; NFS_CACHEINV(inode); diff -u --recursive --new-file v1.3.90/linux/fs/proc/array.c linux/fs/proc/array.c --- v1.3.90/linux/fs/proc/array.c Mon Apr 15 12:20:21 1996 +++ linux/fs/proc/array.c Thu Apr 18 14:35:33 1996 @@ -686,8 +686,8 @@ nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY; return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ -%lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu \ -%lu %lu %lu %lu\n", +%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \ +%lu %lu %lu %lu %lu %lu %lu %lu\n", pid, tsk->comm, state, @@ -722,7 +722,9 @@ tsk->blocked, sigignore, sigcatch, - wchan); + wchan, + tsk->nswap, + tsk->cnswap); } static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size, diff -u --recursive --new-file v1.3.90/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h --- v1.3.90/linux/include/asm-i386/processor.h Thu Mar 21 08:55:09 1996 +++ linux/include/asm-i386/processor.h Wed Apr 17 11:20:47 1996 @@ -52,6 +52,7 @@ long foo; long fos; long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ + long status; /* software status information */ }; struct i387_soft_struct { diff -u --recursive --new-file v1.3.90/linux/include/asm-i386/sigcontext.h linux/include/asm-i386/sigcontext.h --- v1.3.90/linux/include/asm-i386/sigcontext.h Thu Jul 20 09:13:26 1995 +++ linux/include/asm-i386/sigcontext.h Wed Apr 17 12:23:31 1996 @@ -1,6 +1,31 @@ #ifndef _ASMi386_SIGCONTEXT_H #define _ASMi386_SIGCONTEXT_H +/* + * As documented in the iBCS2 standard.. + * + * The first part of "struct _fpstate" is just the + * normal i387 hardware setup, the extra "status" + * word is used to save the coprocessor status word + * before entering the handler. + */ +struct _fpreg { + unsigned short significand[4]; + unsigned short exponent; +}; + +struct _fpstate { + unsigned long cw, + sw, + tag, + ipoff, + cssel, + dataoff, + datasel; + struct _fpreg _st[8]; + unsigned long status; +}; + struct sigcontext_struct { unsigned short gs, __gsh; unsigned short fs, __fsh; @@ -21,7 +46,7 @@ unsigned long eflags; unsigned long esp_at_signal; unsigned short ss, __ssh; - unsigned long i387; + struct _fpstate * fpstate; unsigned long oldmask; unsigned long cr2; }; diff -u --recursive --new-file v1.3.90/linux/include/linux/comstats.h linux/include/linux/comstats.h --- v1.3.90/linux/include/linux/comstats.h Fri Apr 12 15:52:07 1996 +++ linux/include/linux/comstats.h Wed Apr 17 15:08:58 1996 @@ -104,5 +104,15 @@ #define COM_CLRPORTSTATS _IO('c',31) #define COM_GETBRDSTATS _IO('c',32) + +/* + * Define the set of ioctls that give user level access to the + * private port, panel and board structures. The argument required + * will be driver dependant! + */ +#define COM_READPORT _IO('c',40) +#define COM_READBOARD _IO('c',41) +#define COM_READPANEL _IO('c',42) + /*****************************************************************************/ #endif diff -u --recursive --new-file v1.3.90/linux/include/linux/fs.h linux/include/linux/fs.h --- v1.3.90/linux/include/linux/fs.h Mon Apr 15 12:20:21 1996 +++ linux/include/linux/fs.h Thu Apr 18 15:21:09 1996 @@ -36,7 +36,7 @@ /* And dynamically-tunable limits and defaults: */ extern int max_inodes, nr_inodes; extern int max_files, nr_files; -#define NR_INODE 2048 /* this should be bigger than NR_FILE */ +#define NR_INODE 3072 /* this should be bigger than NR_FILE */ #define NR_FILE 1024 /* this can well be larger on a larger system */ #define MAY_EXEC 1 diff -u --recursive --new-file v1.3.90/linux/include/linux/istallion.h linux/include/linux/istallion.h --- v1.3.90/linux/include/linux/istallion.h Thu Jan 1 02:00:00 1970 +++ linux/include/linux/istallion.h Wed Apr 17 15:08:58 1996 @@ -0,0 +1,131 @@ +/*****************************************************************************/ + +/* + * istallion.h -- stallion intelligent multiport serial driver. + * + * Copyright (C) 1994-1996 Greg Ungerer (gerg@stallion.oz.au). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*****************************************************************************/ +#ifndef _ISTALLION_H +#define _ISTALLION_H +/*****************************************************************************/ + +/* + * Define important driver constants here. + */ +#define STL_MAXBRDS 4 +#define STL_MAXPANELS 4 +#define STL_MAXPORTS 64 +#define STL_MAXCHANS (STL_MAXPORTS + 1) +#define STL_MAXDEVS (STL_MAXBRDS * STL_MAXPORTS) + + +/* + * Define a set of structures to hold all the board/panel/port info + * for our ports. These will be dynamically allocated as required at + * driver initialization time. + */ + +/* + * Port and board structures to hold status info about each object. + * The board structure contains pointers to structures for each port + * connected to it. Panels are not distinguished here, since + * communication with the slave board will always be on a per port + * basis. + */ +typedef struct { + unsigned long magic; + int portnr; + int panelnr; + int brdnr; + unsigned long state; + int devnr; + int flags; + int baud_base; + int custom_divisor; + int close_delay; + int closing_wait; + int refcount; + int openwaitcnt; + int rc; + int argsize; + void *argp; + long session; + long pgrp; + unsigned int rxmarkmsk; + struct tty_struct *tty; + struct wait_queue *open_wait; + struct wait_queue *close_wait; + struct wait_queue *raw_wait; + struct tq_struct tqhangup; + struct termios normaltermios; + struct termios callouttermios; + asysigs_t asig; + unsigned long addr; + unsigned long rxoffset; + unsigned long txoffset; + unsigned long sigs; + unsigned long pflag; + unsigned int rxsize; + unsigned int txsize; + unsigned char reqbit; + unsigned char portidx; + unsigned char portbit; +} stliport_t; + +/* + * Use a structure of function pointers to do board level operations. + * These include, enable/disable, paging shared memory, interrupting, etc. + */ +typedef struct stlibrd { + unsigned long magic; + int brdnr; + int brdtype; + int state; + int nrpanels; + int nrports; + int nrdevs; + unsigned int iobase; + unsigned long memaddr; + void *membase; + int memsize; + int pagesize; + int hostoffset; + int slaveoffset; + int bitsize; + int panels[STL_MAXPANELS]; + int panelids[STL_MAXPANELS]; + void (*init)(struct stlibrd *brdp); + void (*enable)(struct stlibrd *brdp); + void (*reenable)(struct stlibrd *brdp); + void (*disable)(struct stlibrd *brdp); + char *(*getmemptr)(struct stlibrd *brdp, unsigned long offset, int line); + void (*intr)(struct stlibrd *brdp); + void (*reset)(struct stlibrd *brdp); + stliport_t *ports[STL_MAXPORTS]; +} stlibrd_t; + + +/* + * Define MAGIC numbers used for above structures. + */ +#define STLI_PORTMAGIC 0xe671c7a1 +#define STLI_BOARDMAGIC 0x4bc6c825 + +/*****************************************************************************/ +#endif diff -u --recursive --new-file v1.3.90/linux/include/linux/md.h linux/include/linux/md.h --- v1.3.90/linux/include/linux/md.h Sat Mar 2 21:21:51 1996 +++ linux/include/linux/md.h Wed Apr 17 15:08:58 1996 @@ -18,6 +18,7 @@ #ifndef _MD_H #define _MD_H +#include #include #include #include @@ -60,7 +61,7 @@ #ifdef __KERNEL__ #include -#include +#include #include #include diff -u --recursive --new-file v1.3.90/linux/include/linux/mm.h linux/include/linux/mm.h --- v1.3.90/linux/include/linux/mm.h Wed Apr 17 09:06:32 1996 +++ linux/include/linux/mm.h Thu Apr 18 15:21:09 1996 @@ -175,7 +175,7 @@ * A page may be used for kmalloc() or anyone else who does a * get_free_page(). In this case the page->count is at least 1, and * all other fields are unused but should be 0 or NULL. The - * managament of this page is the responsibility of the one who uses + * management of this page is the responsibility of the one who uses * it. * * The other pages (we may call them "process pages") are completely diff -u --recursive --new-file v1.3.90/linux/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h --- v1.3.90/linux/include/linux/ncp_fs.h Mon Mar 25 10:26:16 1996 +++ linux/include/linux/ncp_fs.h Thu Apr 18 15:26:45 1996 @@ -63,7 +63,7 @@ #define NCP_READDIR_CACHE_SIZE 64 -#define NCP_MAX_RPC_TIMEOUT (60) /* 6 seconds */ +#define NCP_MAX_RPC_TIMEOUT (6*HZ) /* Guess, what 0x564c is :-) */ #define NCP_SUPER_MAGIC 0x564c diff -u --recursive --new-file v1.3.90/linux/include/linux/netrom.h linux/include/linux/netrom.h --- v1.3.90/linux/include/linux/netrom.h Wed Aug 16 15:10:11 1995 +++ linux/include/linux/netrom.h Thu Apr 18 14:35:33 1996 @@ -5,11 +5,15 @@ #define NETROM_T2 2 #define NETROM_N2 3 #define NETROM_HDRINCL 4 +#define NETROM_PACLEN 5 + +#define NETROM_KILL 99 #define SIOCNRGETPARMS (SIOCPROTOPRIVATE+0) #define SIOCNRSETPARMS (SIOCPROTOPRIVATE+1) #define SIOCNRDECOBS (SIOCPROTOPRIVATE+2) #define SIOCNRRTCTL (SIOCPROTOPRIVATE+3) +#define SIOCNRCTLCON (SIOCPROTOPRIVATE+4) struct nr_route_struct { #define NETROM_NEIGH 0 @@ -32,4 +36,12 @@ unsigned int busy_delay; unsigned int tries; unsigned int window; + unsigned int paclen; +}; + +struct nr_ctl_struct { + unsigned char index; + unsigned char id; + unsigned int cmd; + unsigned long arg; }; diff -u --recursive --new-file v1.3.90/linux/include/linux/stallion.h linux/include/linux/stallion.h --- v1.3.90/linux/include/linux/stallion.h Thu Jan 1 02:00:00 1970 +++ linux/include/linux/stallion.h Wed Apr 17 15:08:58 1996 @@ -0,0 +1,142 @@ +/*****************************************************************************/ + +/* + * stallion.h -- stallion multiport serial driver. + * + * Copyright (C) 1994-1996 Greg Ungerer (gerg@stallion.oz.au). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*****************************************************************************/ +#ifndef _STALLION_H +#define _STALLION_H +/*****************************************************************************/ + +/* + * Define important driver constants here. + */ +#define STL_MAXBRDS 4 +#define STL_MAXPANELS 4 +#define STL_PORTSPERPANEL 16 +#define STL_MAXPORTS 64 +#define STL_MAXDEVS (STL_MAXBRDS * STL_MAXPORTS) + + +/* + * Define a set of structures to hold all the board/panel/port info + * for our ports. These will be dynamically allocated as required. + */ + +/* + * Define a ring queue structure for each port. This will hold the + * TX data waiting to be output. Characters are fed into this buffer + * from the line discipline (or even direct from user space!) and + * then fed into the UARTs during interrupts. Will use a clasic ring + * queue here for this. The good thing about this type of ring queue + * is that the head and tail pointers can be updated without interrupt + * protection - since "write" code only needs to change the head, and + * interrupt code only needs to change the tail. + */ +typedef struct { + char *buf; + char *head; + char *tail; +} stlrq_t; + +/* + * Port, panel and board structures to hold status info about each. + * The board structure contains pointers to structures for each panel + * connected to it, and in turn each panel structure contains pointers + * for each port structure for each port on that panel. Note that + * the port structure also contains the board and panel number that it + * is associated with, this makes it (fairly) easy to get back to the + * board/panel info for a port. + */ +typedef struct { + unsigned long magic; + int portnr; + int panelnr; + int brdnr; + int ioaddr; + int uartaddr; + int pagenr; + int istate; + int flags; + int baud_base; + int custom_divisor; + int close_delay; + int closing_wait; + int refcount; + int openwaitcnt; + int brklen; + long session; + long pgrp; + unsigned int sigs; + unsigned int rxignoremsk; + unsigned int rxmarkmsk; + unsigned long clk; + unsigned long hwid; + struct tty_struct *tty; + struct wait_queue *open_wait; + struct wait_queue *close_wait; + struct termios normaltermios; + struct termios callouttermios; + struct tq_struct tqueue; + comstats_t stats; + stlrq_t tx; +} stlport_t; + +typedef struct { + unsigned long magic; + int panelnr; + int brdnr; + int pagenr; + int nrports; + int iobase; + unsigned int hwid; + unsigned int ackmask; + stlport_t *ports[STL_PORTSPERPANEL]; +} stlpanel_t; + +typedef struct { + unsigned long magic; + int brdnr; + int brdtype; + int state; + int nrpanels; + int nrports; + int irq; + int irqtype; + unsigned int ioaddr1; + unsigned int ioaddr2; + unsigned int iostatus; + unsigned int ioctrl; + unsigned int ioctrlval; + unsigned int hwid; + unsigned long clk; + stlpanel_t *panels[STL_MAXPANELS]; +} stlbrd_t; + + +/* + * Define MAGIC numbers used for above structures. + */ +#define STL_PORTMAGIC 0x5a7182c9 +#define STL_PANELMAGIC 0x7ef621a1 +#define STL_BOARDMAGIC 0xa2267f52 + +/*****************************************************************************/ +#endif diff -u --recursive --new-file v1.3.90/linux/include/net/netrom.h linux/include/net/netrom.h --- v1.3.90/linux/include/net/netrom.h Fri Apr 12 15:52:08 1996 +++ linux/include/net/netrom.h Thu Apr 18 14:35:33 1996 @@ -45,6 +45,7 @@ #define NR_DEFAULT_TTL 16 /* Default Time To Live */ #define NR_MODULUS 256 #define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable */ +#define NR_DEFAULT_PACLEN 236 /* Default Packet Length */ typedef struct { ax25_address user_addr, source_addr, dest_addr; @@ -56,7 +57,7 @@ unsigned char n2, n2count; unsigned short t1, t2, rtt; unsigned short t1timer, t2timer, t4timer; - unsigned short fraglen; + unsigned short fraglen, paclen; struct sk_buff_head ack_queue; struct sk_buff_head reseq_queue; struct sk_buff_head frag_queue; diff -u --recursive --new-file v1.3.90/linux/include/net/sock.h linux/include/net/sock.h --- v1.3.90/linux/include/net/sock.h Fri Apr 12 15:52:09 1996 +++ linux/include/net/sock.h Thu Apr 18 15:23:46 1996 @@ -498,8 +498,8 @@ return -ENOMEM; atomic_add(skb->truesize, &sk->rmem_alloc); skb->sk=sk; - skb_queue_tail(&sk->receive_queue,skb); - if(!sk->dead) + __skb_queue_tail(&sk->receive_queue,skb); + if (!sk->dead) sk->data_ready(sk,skb->len); return 0; } diff -u --recursive --new-file v1.3.90/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c --- v1.3.90/linux/net/ax25/af_ax25.c Fri Apr 12 15:52:11 1996 +++ linux/net/ax25/af_ax25.c Thu Apr 18 14:35:34 1996 @@ -534,8 +534,7 @@ * includes a KILL command to abort any connection. * VERY useful for debugging ;-) */ - -static int ax25_ctl_ioctl(const unsigned int cmd, const unsigned long arg) +static int ax25_ctl_ioctl(const unsigned int cmd, void *arg) { struct ax25_ctl_struct ax25_ctl; struct device *dev; @@ -543,10 +542,10 @@ unsigned long flags; int err; - if ((err = verify_area(VERIFY_READ, (void *)arg, sizeof(ax25_ctl))) != 0) + if ((err = verify_area(VERIFY_READ, arg, sizeof(ax25_ctl))) != 0) return err; - memcpy_fromfs(&ax25_ctl, (void *) arg, sizeof(ax25_ctl)); + memcpy_fromfs(&ax25_ctl, arg, sizeof(ax25_ctl)); if ((dev = ax25rtr_get_dev(&ax25_ctl.port_addr)) == NULL) return -ENODEV; @@ -574,6 +573,7 @@ ax25_dama_off(ax25); ax25_set_timer(ax25); break; + case AX25_WINDOW: if (ax25->modulus == MODULUS) { if (ax25_ctl.arg < 1 || ax25_ctl.arg > 7) @@ -584,6 +584,7 @@ } ax25->window = ax25_ctl.arg; break; + case AX25_T1: if (ax25_ctl.arg < 1) return -EINVAL; @@ -594,6 +595,7 @@ ax25->t1timer = ax25->t1; restore_flags(flags); break; + case AX25_T2: if (ax25_ctl.arg < 1) return -EINVAL; @@ -603,12 +605,14 @@ ax25->t2timer = ax25->t2; restore_flags(flags); break; + case AX25_N2: if (ax25_ctl.arg < 1 || ax25_ctl.arg > 31) return -EINVAL; ax25->n2count = 0; ax25->n2 = ax25_ctl.arg; break; + case AX25_T3: if (ax25_ctl.arg < 1) return -EINVAL; @@ -618,6 +622,7 @@ ax25->t3timer = ax25->t3; restore_flags(flags); break; + case AX25_IDLE: if (ax25_ctl.arg < 1) return -EINVAL; @@ -629,20 +634,21 @@ ax25->idletimer = ax25->idle; restore_flags(flags); break; + case AX25_PACLEN: if (ax25_ctl.arg < 16 || ax25_ctl.arg > 65535) return -EINVAL; - if (ax25_ctl.arg > 256) /* we probably want this */ - printk("ax25_ctl_ioctl(): Warning --- huge paclen %d", (int) ax25_ctl.arg); + printk("ax25_ctl_ioctl: Warning --- huge paclen %d\n", (int)ax25_ctl.arg); ax25->paclen = ax25_ctl.arg; break; + case AX25_IPMAXQUEUE: if (ax25_ctl.arg < 1) return -EINVAL; - ax25->maxqueue = ax25_ctl.arg; break; + default: return -EINVAL; } @@ -650,7 +656,6 @@ return 0; } - /* * Create an empty AX.25 control block. */ @@ -1189,6 +1194,7 @@ ax25->t3 = osk->ax25->t3; ax25->n2 = osk->ax25->n2; ax25->idle = osk->ax25->idle; + ax25->paclen = osk->ax25->paclen; ax25->window = osk->ax25->window; @@ -2235,7 +2241,7 @@ case SIOCAX25CTLCON: if (!suser()) return -EPERM; - return ax25_ctl_ioctl(cmd, arg); + return ax25_ctl_ioctl(cmd, (void *)arg); case SIOCGIFADDR: case SIOCSIFADDR: @@ -2250,11 +2256,11 @@ return -EINVAL; default: - return(dev_ioctl(cmd, (void *)arg)); + return dev_ioctl(cmd, (void *)arg); } /*NOTREACHED*/ - return(0); + return 0; } @@ -2534,6 +2540,7 @@ int ax25_rebuild_header(unsigned char *bp, struct device *dev, unsigned long dest, struct sk_buff *skb) { + struct sk_buff *ourskb; int mode; if (arp_find(bp + 1, dest, dev, dev->pa_addr, skb)) @@ -2556,20 +2563,22 @@ * as we have pulled the frame from the queue by * freeing it). */ - struct sk_buff *ourskb=skb_clone(skb, GFP_ATOMIC); - - if(ourskb==NULL) { + if ((ourskb = skb_clone(skb, GFP_ATOMIC)) == NULL) { dev_kfree_skb(skb, FREE_WRITE); return 1; } ourskb->sk = skb->sk; + if (ourskb->sk != NULL) atomic_add(ourskb->truesize, &ourskb->sk->wmem_alloc); dev_kfree_skb(skb, FREE_WRITE); + skb_pull(ourskb, AX25_HEADER_LEN - 1); /* Keep PID */ + ax25_send_frame(ourskb, (ax25_address *)(bp + 8), (ax25_address *)(bp + 1), NULL, dev); + return 1; } } diff -u --recursive --new-file v1.3.90/linux/net/ax25/ax25_subr.c linux/net/ax25/ax25_subr.c --- v1.3.90/linux/net/ax25/ax25_subr.c Fri Apr 12 15:52:11 1996 +++ linux/net/ax25/ax25_subr.c Thu Apr 18 14:35:34 1996 @@ -494,13 +494,9 @@ return 0; } - skbq = (struct sk_buff *) list->next; - - while (skbq != (struct sk_buff *)list) { + for (skbq = list->next; skbq != (struct sk_buff *)list; skbq = skbq->next) if (skb->sk == skbq->sk) count++; - skbq = skbq->next; - } restore_flags(flags); return count; @@ -512,7 +508,7 @@ int ax25_queue_length(ax25_cb *ax25, struct sk_buff *skb) { - return ax25_list_length(&ax25->write_queue, skb)+ax25_list_length(&ax25->ack_queue, skb); + return ax25_list_length(&ax25->write_queue, skb) + ax25_list_length(&ax25->ack_queue, skb); } /* diff -u --recursive --new-file v1.3.90/linux/net/bridge/br.c linux/net/bridge/br.c --- v1.3.90/linux/net/bridge/br.c Fri Apr 12 15:52:11 1996 +++ linux/net/bridge/br.c Thu Apr 18 15:25:53 1996 @@ -16,8 +16,9 @@ * and use a netlink notifier so a daemon can maintain the bridge * port group (could we also do multiple groups ????). * A nice /proc file interface. - * Put the path costs in the port info and devices + * Put the path costs in the port info and devices. * Put the bridge port number in the device structure for speed. + * Bridge SNMP stats. * */ @@ -81,15 +82,14 @@ /** Elements of Procedure (4.6) **/ /* - * this section of code was graciously borrowed from the IEEE 802.1d + * this section of code was gratiously borrowed from the IEEE 802.1d * specification section 4.9.1 starting on pg 69. It has been * modified somewhat to fit within out framework and structure. It * implements the spanning tree algorithm that is the heart of the * 802.1d bridging protocol. */ -void -transmit_config(int port_no) /* (4.6.1) */ +void transmit_config(int port_no) /* (4.6.1) */ { if (hold_timer[port_no].active) { /* (4.6.1.3.1) */ port_info[port_no].config_pending = TRUE; /* (4.6.1.3.1) */ @@ -132,15 +132,13 @@ } } -int -root_bridge(void) +int root_bridge(void) { return (br_cmp(bridge_info.designated_root.BRIDGE_ID, bridge_info.bridge_id.BRIDGE_ID)?FALSE:TRUE); } -int -supersedes_port_info(int port_no, Config_bpdu *config) /* (4.6.2.2) */ +int supersedes_port_info(int port_no, Config_bpdu *config) /* (4.6.2.2) */ { return ( (br_cmp(config->root_id.BRIDGE_ID, @@ -177,8 +175,7 @@ ); } -void -record_config_information(int port_no, Config_bpdu *config) /* (4.6.2) */ +void record_config_information(int port_no, Config_bpdu *config) /* (4.6.2) */ { port_info[port_no].designated_root = config->root_id; /* (4.6.2.3.1) */ port_info[port_no].designated_cost = config->root_path_cost; @@ -187,8 +184,7 @@ start_message_age_timer(port_no, config->message_age); /* (4.6.2.3.2) */ } -void -record_config_timeout_values(Config_bpdu *config) /* (4.6.3) */ +void record_config_timeout_values(Config_bpdu *config) /* (4.6.3) */ { bridge_info.max_age = config->max_age; /* (4.6.3.3) */ bridge_info.hello_time = config->hello_time; @@ -197,8 +193,7 @@ bridge_info.top_change = 1; } -void -config_bpdu_generation(void) +void config_bpdu_generation(void) { /* (4.6.4) */ int port_no; for (port_no = One; port_no <= No_of_ports; port_no++) { /* (4.6.4.3) */ @@ -211,8 +206,7 @@ } } -int -designated_port(int port_no) +int designated_port(int port_no) { return ((br_cmp(port_info[port_no].designated_bridge.BRIDGE_ID, bridge_info.bridge_id.BRIDGE_ID) == 0 @@ -224,14 +218,12 @@ ); } -void -reply(int port_no) /* (4.6.5) */ +void reply(int port_no) /* (4.6.5) */ { transmit_config(port_no); /* (4.6.5.3) */ } -void -transmit_tcn(void) +void transmit_tcn(void) { /* (4.6.6) */ int port_no; @@ -240,8 +232,7 @@ send_tcn_bpdu(port_no, &tcn_bpdu[bridge_info.root_port]); /* (4.6.6.3) */ } -void -configuration_update(void) /* (4.6.7) */ +void configuration_update(void) /* (4.6.7) */ { root_selection(); /* (4.6.7.3.1) */ /* (4.6.8.2) */ @@ -249,8 +240,7 @@ /* (4.6.9.2) */ } -void -root_selection(void) +void root_selection(void) { /* (4.6.8) */ int root_port; int port_no; @@ -330,8 +320,7 @@ } } -void -designated_port_selection(void) +void designated_port_selection(void) { /* (4.6.9) */ int port_no; @@ -368,8 +357,7 @@ } } -void -become_designated_port(int port_no) +void become_designated_port(int port_no) { /* (4.6.10) */ /* (4.6.10.3.1) */ @@ -382,8 +370,7 @@ port_info[port_no].designated_port = port_info[port_no].port_id; } -void -port_state_selection(void) +void port_state_selection(void) { /* (4.6.11) */ int port_no; for (port_no = One; port_no <= No_of_ports; port_no++) { @@ -403,8 +390,7 @@ } -void -make_forwarding(int port_no) +void make_forwarding(int port_no) { /* (4.6.12) */ if (port_info[port_no].state == Blocking) { /* (4.6.12.3) */ set_port_state(port_no, Listening); /* (4.6.12.3.1) */ @@ -412,8 +398,7 @@ } } -void -topology_change_detection(void) +void topology_change_detection(void) { /* (4.6.14) */ if (root_bridge()) { /* (4.6.14.3.1) */ bridge_info.top_change = 1; @@ -425,22 +410,19 @@ bridge_info.top_change = 1; } -void -topology_change_acknowledged(void) +void topology_change_acknowledged(void) { /* (4.6.15) */ bridge_info.top_change_detected = 0; stop_tcn_timer(); /* (4.6.15.3.2) */ } -void -acknowledge_topology_change(int port_no) +void acknowledge_topology_change(int port_no) { /* (4.6.16) */ port_info[port_no].top_change_ack = 1; transmit_config(port_no); /* (4.6.16.3.2) */ } -void -make_blocking(int port_no) /* (4.6.13) */ +void make_blocking(int port_no) /* (4.6.13) */ { if ((port_info[port_no].state != Disabled) @@ -460,14 +442,12 @@ } } -void -set_port_state(int port_no, int state) +void set_port_state(int port_no, int state) { port_info[port_no].state = state; } -void -received_config_bpdu(int port_no, Config_bpdu *config) /* (4.7.1) */ +void received_config_bpdu(int port_no, Config_bpdu *config) /* (4.7.1) */ { int root; @@ -504,8 +484,7 @@ } } -void -received_tcn_bpdu(int port_no, Tcn_bpdu *tcn) /* (4.7.2) */ +void received_tcn_bpdu(int port_no, Tcn_bpdu *tcn) /* (4.7.2) */ { if (port_info[port_no].state != Disabled) { if (designated_port(port_no)) { @@ -516,15 +495,13 @@ } } -void -hello_timer_expiry(void) +void hello_timer_expiry(void) { /* (4.7.3) */ config_bpdu_generation(); /* (4.6.4.2.2) */ start_hello_timer(); } -void -message_age_timer_expiry(int port_no) /* (4.7.4) */ +void message_age_timer_expiry(int port_no) /* (4.7.4) */ { int root; root = root_bridge(); @@ -549,8 +526,7 @@ } } -void -forward_delay_timer_expiry(int port_no) /* (4.7.5) */ +void forward_delay_timer_expiry(int port_no) /* (4.7.5) */ { if (port_info[port_no].state == Listening) { /* (4.7.5.1) */ set_port_state(port_no, Learning); /* (4.7.5.1.1) */ @@ -564,8 +540,7 @@ } } -int -designated_for_some_port(void) +int designated_for_some_port(void) { int port_no; @@ -580,31 +555,27 @@ return (FALSE); } -void -tcn_timer_expiry(void) +void tcn_timer_expiry(void) { /* (4.7.6) */ transmit_tcn(); /* (4.7.6.1) */ start_tcn_timer(); /* (4.7.6.2) */ } -void -topology_change_timer_expiry(void) +void topology_change_timer_expiry(void) { /* (4.7.7) */ bridge_info.top_change_detected = 0; bridge_info.top_change = 0; /* (4.7.7.2) */ } -void -hold_timer_expiry(int port_no) /* (4.7.8) */ +void hold_timer_expiry(int port_no) /* (4.7.8) */ { if (port_info[port_no].config_pending) { transmit_config(port_no); /* (4.7.8.1) */ } /* (4.6.1.2.3) */ } -void -br_init(void) +void br_init(void) { /* (4.8.1) */ int port_no; @@ -633,17 +604,16 @@ config_bpdu_generation(); /* (4.8.1.6) */ /* initialize system timer */ - tl.expires = HZ; /* 1 second */ + tl.expires = jiffies+HZ; /* 1 second */ tl.function = br_tick; add_timer(&tl); register_netdevice_notifier(&br_dev_notifier); - br_stats.flags = BR_UP | BR_DEBUG; /* enable bridge */ - start_hello_timer(); + br_stats.flags = 0; /*BR_UP | BR_DEBUG*/; /* enable bridge */ + /*start_hello_timer();*/ } -void -br_init_port(int port_no) +void br_init_port(int port_no) { become_designated_port(port_no); /* (4.8.1.4.1) */ set_port_state(port_no, Blocking); /* (4.8.1.4.2) */ @@ -654,15 +624,13 @@ stop_hold_timer(port_no); /* (4.8.1.4.7) */ } -void -enable_port(int port_no) /* (4.8.2) */ +void enable_port(int port_no) /* (4.8.2) */ { br_init_port(port_no); port_state_selection(); /* (4.8.2.7) */ } /* */ -void -disable_port(int port_no) /* (4.8.3) */ +void disable_port(int port_no) /* (4.8.3) */ { int root; @@ -687,8 +655,7 @@ } -void -set_bridge_priority(bridge_id_t *new_bridge_id) /* (4.8.4) */ +void set_bridge_priority(bridge_id_t *new_bridge_id) /* (4.8.4) */ { int root; @@ -714,8 +681,7 @@ } } -void -set_port_priority(int port_no, unsigned short new_port_id) /* (4.8.5) */ +void set_port_priority(int port_no, unsigned short new_port_id) /* (4.8.5) */ { if (designated_port(port_no)) { /* (4.8.5.2) */ port_info[port_no].designated_port = new_port_id; @@ -735,16 +701,14 @@ } } -void -set_path_cost(int port_no, unsigned short path_cost) /* (4.8.6) */ +void set_path_cost(int port_no, unsigned short path_cost) /* (4.8.6) */ { port_info[port_no].path_cost = path_cost; /* (4.8.6.1) */ configuration_update(); /* (4.8.6.2) */ port_state_selection(); /* (4.8.6.3) */ } -static void -br_tick(unsigned long arg) +static void br_tick(unsigned long arg) { int port_no; @@ -769,26 +733,23 @@ } } /* call me again sometime... */ - tl.expires = HZ; /* 1 second */ + tl.expires = jiffies+HZ; /* 1 second */ tl.function = br_tick; add_timer(&tl); } -void -start_hello_timer(void) +void start_hello_timer(void) { hello_timer.value = 0; hello_timer.active = TRUE; } -void -stop_hello_timer(void) +void stop_hello_timer(void) { hello_timer.active = FALSE; } -int -hello_timer_expired(void) +int hello_timer_expired(void) { if (hello_timer.active && (++hello_timer.value >= bridge_info.hello_time)) { hello_timer.active = FALSE; @@ -797,21 +758,18 @@ return (FALSE); } -void -start_tcn_timer(void) +void start_tcn_timer(void) { tcn_timer.value = 0; tcn_timer.active = TRUE; } -void -stop_tcn_timer(void) +void stop_tcn_timer(void) { tcn_timer.active = FALSE; } -int -tcn_timer_expired(void) +int tcn_timer_expired(void) { if (tcn_timer.active && (++tcn_timer.value >= bridge_info.bridge_hello_time)) { @@ -822,21 +780,18 @@ } -void -start_topology_change_timer(void) +void start_topology_change_timer(void) { topology_change_timer.value = 0; topology_change_timer.active = TRUE; } -void -stop_topology_change_timer(void) +void stop_topology_change_timer(void) { topology_change_timer.active = FALSE; } -int -topology_change_timer_expired(void) +int topology_change_timer_expired(void) { if (topology_change_timer.active && (++topology_change_timer.value @@ -848,21 +803,18 @@ return (FALSE); } -void -start_message_age_timer(int port_no, unsigned short message_age) +void start_message_age_timer(int port_no, unsigned short message_age) { message_age_timer[port_no].value = message_age; message_age_timer[port_no].active = TRUE; } -void -stop_message_age_timer(int port_no) +void stop_message_age_timer(int port_no) { message_age_timer[port_no].active = FALSE; } -int -message_age_timer_expired(int port_no) +int message_age_timer_expired(int port_no) { if (message_age_timer[port_no].active && (++message_age_timer[port_no].value >= bridge_info.max_age)) { @@ -872,21 +824,18 @@ return (FALSE); } -void -start_forward_delay_timer(int port_no) +void start_forward_delay_timer(int port_no) { forward_delay_timer[port_no].value = 0; forward_delay_timer[port_no].active = TRUE; } -void -stop_forward_delay_timer(int port_no) +void stop_forward_delay_timer(int port_no) { forward_delay_timer[port_no].active = FALSE; } -int -forward_delay_timer_expired(int port_no) +int forward_delay_timer_expired(int port_no) { if (forward_delay_timer[port_no].active && (++forward_delay_timer[port_no].value >= bridge_info.forward_delay)) { @@ -896,22 +845,19 @@ return (FALSE); } -void -start_hold_timer(int port_no) +void start_hold_timer(int port_no) { hold_timer[port_no].value = 0; hold_timer[port_no].active = TRUE; } -void -stop_hold_timer(int port_no) +void stop_hold_timer(int port_no) { hold_timer[port_no].active = FALSE; } -int -hold_timer_expired(int port_no) +int hold_timer_expired(int port_no) { if (hold_timer[port_no].active && (++hold_timer[port_no].value >= bridge_info.hold_time)) { @@ -922,8 +868,7 @@ } -int -send_config_bpdu(int port_no, Config_bpdu *config_bpdu) +int send_config_bpdu(int port_no, Config_bpdu *config_bpdu) { struct sk_buff *skb; struct device *dev = port_info[port_no].dev; @@ -982,8 +927,7 @@ return(0); } -int -send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu) +int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu) { struct sk_buff *skb; struct device *dev = port_info[port_no].dev; @@ -1039,8 +983,7 @@ return(0); } -static int -br_device_event(struct notifier_block *unused, unsigned long event, void *ptr) +static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct device *dev = ptr; int i; @@ -1103,8 +1046,7 @@ * frame, 0 when it does not */ -int -br_receive_frame(struct sk_buff *skb) /* 3.5 */ +int br_receive_frame(struct sk_buff *skb) /* 3.5 */ { int port; @@ -1115,12 +1057,15 @@ printk("no skb!\n"); return(1); } + + skb->pkt_bridged = IS_BRIDGED; + /* check for loopback */ if (skb->dev->flags & IFF_LOOPBACK) return(0); port = find_port(skb->dev); - skb->h.raw = skb->data; + skb->h.raw = skb->mac.raw; if (br_stats.flags & BR_DEBUG) printk("port %i src %02x:%02x:%02x:%02x:%02x:%02x\ dest %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -1139,11 +1084,13 @@ skb->h.eth->h_dest[5]); if (!port) { - printk("\nbr_receive_frame: no port!\n"); + if(br_stats.flags&BR_DEBUG) + printk("\nbr_receive_frame: no port!\n"); return(0); } - switch (port_info[port].state) { + switch (port_info[port].state) + { case Learning: (void) br_learn(skb, port); /* 3.8 */ /* fall through */ @@ -1167,19 +1114,22 @@ (void) br_learn(skb, port); /* 3.8 */ /* process BPDUs */ if (memcmp(skb->h.eth->h_dest, bridge_ula, - ETH_ALEN) == 0) { - printk("frame bpdu processor for me!!!\n"); + ETH_ALEN) == 0) + { + /*printk("frame bpdu processor for me!!!\n");*/ br_bpdu(skb); return(1); /* br_bpdu consumes skb */ } /* is frame for me? */ if (memcmp(skb->h.eth->h_dest, port_info[port].dev->dev_addr, - ETH_ALEN) == 0) { + ETH_ALEN) == 0) + { return(0); /* pass frame up our stack (this will */ /* happen in net_bh() in dev.c) */ } /* ok, forward this frame... */ + skb_device_lock(skb); return(br_forward(skb, port)); default: printk("br_receive_frame: port [%i] unknown state [%i]\n", @@ -1194,13 +1144,13 @@ * 0 when it does not. */ -int -br_tx_frame(struct sk_buff *skb) /* 3.5 */ +int br_tx_frame(struct sk_buff *skb) /* 3.5 */ { int port; /* sanity */ - if (!skb) { + if (!skb) + { printk("br_tx_frame: no skb!\n"); return(0); } @@ -1235,8 +1185,7 @@ * state or lack of resources... */ -int -br_learn(struct sk_buff *skb, int port) /* 3.8 */ +int br_learn(struct sk_buff *skb, int port) /* 3.8 */ { struct fdb *f; @@ -1285,23 +1234,31 @@ * this routine always consumes the frame */ -int -br_drop(struct sk_buff *skb) +int br_drop(struct sk_buff *skb) { kfree_skb(skb, 0); return(1); } /* + * this routine always consumes the frame + */ + +int br_dev_drop(struct sk_buff *skb) +{ + dev_kfree_skb(skb, 0); + return(1); +} + +/* * this routine returns 1 if it consumes the frame, 0 * if not... */ -int -br_forward(struct sk_buff *skb, int port) /* 3.7 */ +int br_forward(struct sk_buff *skb, int port) /* 3.7 */ { -struct fdb *f; -unsigned long flags; + struct fdb *f; + unsigned long flags; /* * flood all ports with frames destined for a group @@ -1310,19 +1267,32 @@ * Multicast frames will also need to be seen * by our upper layers. */ - if (skb->h.eth->h_dest[0] & 0x01) { /* group address */ + if (skb->h.eth->h_dest[0] & 0x01) + { + /* group address */ br_flood(skb, port); + /* + * External groups are fed out via the normal source + * This probably should be dropped since the flood will + * have sent it anyway. + */ if (port == 0) /* locally generated */ - return(br_drop(skb)); + return(br_dev_drop(skb)); return(0); } else { /* locate port to forward to */ f = br_avl_find_addr(skb->h.eth->h_dest); + /* + * Send flood and drop. + */ if (!f | !(f->flags & FDB_ENT_VALID)) { /* not found; flood all ports */ br_flood(skb, port); - return(br_drop(skb)); + return(br_dev_drop(skb)); } + /* + * Sending + */ if (port_info[f->port].state == Forwarding) { /* has entry expired? */ if (f->timer + fdb_aging_time < CURRENT_TIME) { @@ -1330,33 +1300,34 @@ f->flags &= ~FDB_ENT_VALID; if (br_stats.flags & BR_DEBUG) printk("fdb entry expired...\n"); + /* + * Send flood and drop original + */ br_flood(skb, port); - return(br_drop(skb)); + return(br_dev_drop(skb)); } /* mark that's we've been here... */ skb->pkt_bridged = IS_BRIDGED; - /* - * if the frame is originating in this host, - * we may need to resolve the outgoing address - if (port != 0) - skb->arp = 1; - */ - /* reset the skb->ip pointer */ skb->h.raw = skb->data + ETH_HLEN; - /* we must unlock the skb before requeueing it... */ - if (skb_device_locked(skb)) - skb_device_unlock(skb); - - save_flags(flags); /* enter critical section */ - cli(); - skb_queue_head(port_info[f->port].dev->buffs, skb); - restore_flags(flags); /* exit critical section */ + /* + * Send the buffer out. + */ + + skb->dev=port_info[f->port].dev; + + /* + * We send this still locked + */ + dev_queue_xmit(skb, skb->dev,1); return(1); /* skb has been consumed */ } else { - return(br_drop(skb)); + /* + * Arrived on the right port, we discard + */ + return(br_dev_drop(skb)); } } } @@ -1367,40 +1338,34 @@ * consumes the original frame. */ -int -br_flood(struct sk_buff *skb, int port) +int br_flood(struct sk_buff *skb, int port) { -int i; -struct sk_buff *nskb; -unsigned long flags; + int i; + struct sk_buff *nskb; + unsigned long flags; - for (i = One; i <= No_of_ports; i++) { + for (i = One; i <= No_of_ports; i++) + { if (i == port) continue; - if (port_info[i].state == Forwarding) { + if (port_info[i].state == Forwarding) + { nskb = skb_clone(skb, GFP_ATOMIC); /* mark that's we've been here... */ nskb->pkt_bridged = IS_BRIDGED; - /* - * if the frame is originating in this host, - * we may need to resolve the outgoing address - if (port != 0) - nskb->arp = 1; - */ + nskb->arp = skb->arp; + +/* printk("Flood to port %d\n",i);*/ nskb->h.raw = nskb->data + ETH_HLEN; - save_flags(flags); - cli(); - skb_queue_tail(port_info[i].dev->buffs, nskb); - restore_flags(flags); + dev_queue_xmit(nskb,nskb->dev,1); } } return(0); } -int -find_port(struct device *dev) +int find_port(struct device *dev) { -int i; + int i; for (i = One; i <= No_of_ports; i++) if ((port_info[i].dev == dev) && @@ -1409,8 +1374,7 @@ return(0); } -int -br_port_cost(struct device *dev) /* 4.10.2 */ +int br_port_cost(struct device *dev) /* 4.10.2 */ { if (strncmp(dev->name, "eth", 3) == 0) /* ethernet */ return(100); @@ -1425,11 +1389,10 @@ * this routine always consumes the skb */ -void -br_bpdu(struct sk_buff *skb) /* consumes skb */ +void br_bpdu(struct sk_buff *skb) /* consumes skb */ { -Tcn_bpdu *bpdu; -int port; + Tcn_bpdu *bpdu; + int port; port = find_port(skb->dev); if (port == 0) { /* unknown port */ @@ -1453,8 +1416,7 @@ br_drop(skb); } -int -br_ioctl(unsigned int cmd, void *arg) +int br_ioctl(unsigned int cmd, void *arg) { int err; struct br_cf bcf; @@ -1484,7 +1446,6 @@ if (br_stats.flags & BR_UP) return(-EALREADY); printk("br: enabling bridging function\n"); - register_netdevice_notifier(&br_dev_notifier); br_stats.flags |= BR_UP; /* enable bridge */ start_hello_timer(); break; @@ -1492,12 +1453,13 @@ if (!(br_stats.flags & BR_UP)) return(-EALREADY); printk("br: disabling bridging function\n"); - unregister_netdevice_notifier(&br_dev_notifier); br_stats.flags &= ~BR_UP; /* disable bridge */ stop_hello_timer(); +#if 0 for (i = One; i <= No_of_ports; i++) if (port_info[i].state != Disabled) disable_port(i); +#endif break; case BRCMD_PORT_ENABLE: if (port_info[bcf.arg1].dev == 0) @@ -1548,7 +1510,8 @@ int br_cmp(unsigned int *a, unsigned int *b) { int i; - for (i=0; i<2; i++) { + for (i=0; i<2; i++) + { if (a[i] == b[i]) continue; if (a[i] < b[i]) diff -u --recursive --new-file v1.3.90/linux/net/ipv4/ip_options.c linux/net/ipv4/ip_options.c --- v1.3.90/linux/net/ipv4/ip_options.c Fri Apr 12 15:52:12 1996 +++ linux/net/ipv4/ip_options.c Thu Apr 18 09:47:39 1996 @@ -277,7 +277,7 @@ if (optlen<2 || optlen>l) { pp_ptr = optptr; - break; + goto error; } switch (*optptr) { @@ -286,25 +286,25 @@ if (optlen < 3) { pp_ptr = optptr + 1; - break; + goto error; } if (optptr[2] < 4) { pp_ptr = optptr + 2; - break; + goto error; } /* NB: cf RFC-1812 5.2.4.1 */ if (opt->srr) { pp_ptr = optptr; - break; + goto error; } if (!skb) { if (optptr[2] != 4 || optlen < 7 || ((optlen-3) & 3)) { pp_ptr = optptr + 1; - break; + goto error; } memcpy(&opt->faddr, &optptr[3], 4); if (optlen > 7) @@ -317,24 +317,24 @@ if (opt->rr) { pp_ptr = optptr; - break; + goto error; } if (optlen < 3) { pp_ptr = optptr + 1; - break; + goto error; } if (optptr[2] < 4) { pp_ptr = optptr + 2; - break; + goto error; } if (optptr[2] <= optlen) { if (optptr[2]+3 > optlen) { pp_ptr = optptr + 2; - break; + goto error; } if (skb) { @@ -350,17 +350,17 @@ if (opt->ts) { pp_ptr = optptr; - break; + goto error; } if (optlen < 4) { pp_ptr = optptr + 1; - break; + goto error; } if (optptr[2] < 5) { pp_ptr = optptr + 2; - break; + goto error; } if (optptr[2] <= optlen) { @@ -369,7 +369,7 @@ if (ts->ptr+3 > ts->len) { pp_ptr = optptr + 2; - break; + goto error; } switch (ts->flags) { @@ -384,7 +384,7 @@ if (ts->ptr+7 > ts->len) { pp_ptr = optptr + 2; - break; + goto error; } opt->ts = optptr - iph; if (skb) @@ -400,7 +400,7 @@ if (ts->ptr+7 > ts->len) { pp_ptr = optptr + 2; - break; + goto error; } opt->ts = optptr - iph; { @@ -417,7 +417,7 @@ break; default: pp_ptr = optptr + 3; - break; + goto error; } if (timeptr) { @@ -435,7 +435,7 @@ if (ts->overflow == 15) { pp_ptr = optptr + 3; - break; + goto error; } opt->ts = optptr - iph; if (skb) @@ -451,7 +451,7 @@ if (!skb) { pp_ptr = optptr; - break; + goto error; } break; } @@ -463,6 +463,7 @@ if (!pp_ptr) return 0; +error: if (skb) { icmp_send(skb, ICMP_PARAMETERPROB, 0, pp_ptr-iph, skb->dev); diff -u --recursive --new-file v1.3.90/linux/net/ipv4/ip_output.c linux/net/ipv4/ip_output.c --- v1.3.90/linux/net/ipv4/ip_output.c Fri Apr 12 15:52:12 1996 +++ linux/net/ipv4/ip_output.c Thu Apr 18 14:35:34 1996 @@ -137,7 +137,7 @@ #endif skb->arp = 0; skb->raddr = daddr; - return -dev->hard_header_len; + return dev->hard_header_len; } mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len); if (mac < 0) diff -u --recursive --new-file v1.3.90/linux/net/ipv4/raw.c linux/net/ipv4/raw.c --- v1.3.90/linux/net/ipv4/raw.c Sun Mar 10 09:28:57 1996 +++ linux/net/ipv4/raw.c Thu Apr 18 13:17:03 1996 @@ -109,6 +109,33 @@ return; } +static inline void raw_rcv_skb(struct sock * sk, struct sk_buff * skb) +{ + /* Charge it to the socket. */ + + if (sock_queue_rcv_skb(sk,skb)<0) + { + ip_statistics.IpInDiscards++; + skb->sk=NULL; + kfree_skb(skb, FREE_READ); + return; + } + + ip_statistics.IpInDelivers++; +} + +/* + * This is the prot->rcv() function. It's called when we have + * backlogged packets from core/sock.c if we couldn't receive it + * when the packet arrived. + */ +static int raw_rcv_redo(struct sk_buff *skb, struct device *dev, struct options *opt, + __u32 daddr, unsigned short len, + __u32 saddr, int redo, struct inet_protocol * protocol) +{ + raw_rcv_skb(skb->sk, skb); + return 0; +} /* * This should be the easiest of all, all we do is @@ -137,17 +164,11 @@ skb->ip_hdr->tot_len=ntohs(skb->ip_hdr->tot_len-4*skb->ip_hdr->ihl); #endif - /* Charge it to the socket. */ - - if(sock_queue_rcv_skb(sk,skb)<0) - { - ip_statistics.IpInDiscards++; - skb->sk=NULL; - kfree_skb(skb, FREE_READ); - return(0); + if (sk->users) { + __skb_queue_tail(&sk->back_log, skb); + return 0; } - - ip_statistics.IpInDelivers++; + raw_rcv_skb(sk, skb); return 0; } @@ -357,7 +378,7 @@ NULL, NULL, NULL, - NULL, + raw_rcv_redo, datagram_select, #ifdef CONFIG_IP_MROUTE ipmr_ioctl, diff -u --recursive --new-file v1.3.90/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c --- v1.3.90/linux/net/ipv4/tcp_input.c Wed Apr 17 09:06:33 1996 +++ linux/net/ipv4/tcp_input.c Thu Apr 18 14:10:41 1996 @@ -92,14 +92,20 @@ */ m = jiffies - oskb->when; /* RTT */ - if(m<=0) - m=1; /* IS THIS RIGHT FOR <0 ??? */ - m -= (sk->rtt >> 3); /* m is now error in rtt est */ - sk->rtt += m; /* rtt = 7/8 rtt + 1/8 new */ - if (m < 0) - m = -m; /* m is now abs(error) */ - m -= (sk->mdev >> 2); /* similar update on mdev */ - sk->mdev += m; /* mdev = 3/4 mdev + 1/4 new */ + if (sk->rtt != 0) { + if(m<=0) + m=1; /* IS THIS RIGHT FOR <0 ??? */ + m -= (sk->rtt >> 3); /* m is now error in rtt est */ + sk->rtt += m; /* rtt = 7/8 rtt + 1/8 new */ + if (m < 0) + m = -m; /* m is now abs(error) */ + m -= (sk->mdev >> 2); /* similar update on mdev */ + sk->mdev += m; /* mdev = 3/4 mdev + 1/4 new */ + } else { + /* no previous measure. */ + sk->rtt = m<<3; /* take the measured time to be rtt */ + sk->mdev = m<<2; /* make sure rto = 3*rtt */ + } /* * Now update timeout. Note that this removes any backoff. @@ -714,7 +720,7 @@ * (2) it has the same window as the last ACK, * (3) we have outstanding data that has not been ACKed * (4) The packet was not carrying any data. - * I've tried to order these in occurance of most likely to fail + * I've tried to order these in occurrence of most likely to fail * to least likely to fail. * [These are the rules BSD stacks use to determine if an ACK is a * duplicate.] diff -u --recursive --new-file v1.3.90/linux/net/ipv4/udp.c linux/net/ipv4/udp.c --- v1.3.90/linux/net/ipv4/udp.c Fri Apr 12 15:52:12 1996 +++ linux/net/ipv4/udp.c Thu Apr 18 12:50:04 1996 @@ -135,8 +135,6 @@ restore_flags(flags); } -static int udp_deliver(struct sock *sk, struct udphdr *uh, struct sk_buff *skb, struct device *dev, long saddr, long daddr, int len); - #define min(a,b) ((a)<(b)?(a):(b)) @@ -583,6 +581,37 @@ destroy_sock(sk); } +static inline void udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) +{ + /* + * Charge it to the socket, dropping if the queue is full. + */ + + /* I assume this includes the IP options, as per RFC1122 (4.1.3.2). */ + /* If not, please let me know. -- MS */ + + if (sock_queue_rcv_skb(sk,skb)<0) { + udp_statistics.UdpInErrors++; + ip_statistics.IpInDiscards++; + ip_statistics.IpInDelivers--; + skb->sk = NULL; + kfree_skb(skb, FREE_WRITE); + return; + } + udp_statistics.UdpInDatagrams++; +} + + +static inline void udp_deliver(struct sock *sk, struct sk_buff *skb) +{ + skb->sk = sk; + + if (sk->users) { + __skb_queue_tail(&sk->back_log, skb); + return; + } + udp_queue_rcv_skb(sk, skb); +} /* * All we need to do is get the socket, and then do a checksum. @@ -595,8 +624,23 @@ struct sock *sk; struct udphdr *uh; unsigned short ulen; - int addr_type = IS_MYADDR; - + int addr_type; + + /* + * If we're doing a "redo" (the socket was busy last time + * around), we can just queue the packet now.. + */ + if (redo) { + udp_queue_rcv_skb(skb->sk, skb); + return 0; + } + + /* + * First time through the loop.. Do all the setup stuff + * (including finding out the socket we go to etc) + */ + + addr_type = IS_MYADDR; if(!dev || dev->pa_addr!=daddr) addr_type=ip_chk_addr(daddr); @@ -651,9 +695,18 @@ return(0); } + /* + * These are supposed to be switched. + */ + + skb->daddr = saddr; + skb->saddr = daddr; len=ulen; + skb->dev = dev; + skb_trim(skb,len); + #ifdef CONFIG_IP_MULTICAST if (addr_type!=IS_MYADDR) { @@ -675,7 +728,7 @@ else skb1=skb; if(skb1) - udp_deliver(sk, uh, skb1, dev,saddr,daddr,len); + udp_deliver(sk, skb1); sk=sknext; } while(sknext!=NULL); @@ -712,43 +765,9 @@ kfree_skb(skb, FREE_WRITE); return(0); } - return udp_deliver(sk,uh,skb,dev, saddr, daddr, len); -} - -static int udp_deliver(struct sock *sk, struct udphdr *uh, struct sk_buff *skb, struct device *dev, long saddr, long daddr, int len) -{ - skb->sk = sk; - skb->dev = dev; - skb_trim(skb,len); - - /* - * These are supposed to be switched. - */ - - skb->daddr = saddr; - skb->saddr = daddr; - - - /* - * Charge it to the socket, dropping if the queue is full. - */ - - /* I assume this includes the IP options, as per RFC1122 (4.1.3.2). */ - /* If not, please let me know. -- MS */ - - if (sock_queue_rcv_skb(sk,skb)<0) - { - udp_statistics.UdpInErrors++; - ip_statistics.IpInDiscards++; - ip_statistics.IpInDelivers--; - skb->sk = NULL; - kfree_skb(skb, FREE_WRITE); - return(0); - } - udp_statistics.UdpInDatagrams++; - return(0); + udp_deliver(sk, skb); + return 0; } - struct proto udp_prot = { udp_close, diff -u --recursive --new-file v1.3.90/linux/net/ipv6/README linux/net/ipv6/README --- v1.3.90/linux/net/ipv6/README Thu Jan 1 02:00:00 1970 +++ linux/net/ipv6/README Thu Apr 18 14:35:34 1996 @@ -0,0 +1,4 @@ +To join in the work on Linux IPv6 join the majordomo managed mailing list + "netdev@nuclecu.unam.mx" + +Alan diff -u --recursive --new-file v1.3.90/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c --- v1.3.90/linux/net/netrom/af_netrom.c Fri Apr 12 15:52:13 1996 +++ linux/net/netrom/af_netrom.c Thu Apr 18 14:35:34 1996 @@ -282,6 +282,82 @@ return -EINVAL; } +/* + * dl1bke 960311: set parameters for existing NET/ROM connections, + * includes a KILL command to abort any connection. + * VERY useful for debugging ;-) + */ +static int nr_ctl_ioctl(const unsigned int cmd, void *arg) +{ + struct nr_ctl_struct nr_ctl; + struct sock *sk; + unsigned long flags; + int err; + + if ((err = verify_area(VERIFY_READ, arg, sizeof(nr_ctl))) != 0) + return err; + + memcpy_fromfs(&nr_ctl, arg, sizeof(nr_ctl)); + + if ((sk = nr_find_socket(nr_ctl.index, nr_ctl.id)) == NULL) + return -ENOTCONN; + + switch (nr_ctl.cmd) { + case NETROM_KILL: + nr_clear_queues(sk); + nr_write_internal(sk, NR_DISCREQ); + sk->nr->state = NR_STATE_0; + sk->state = TCP_CLOSE; + sk->err = ENETRESET; + if (!sk->dead) + sk->state_change(sk); + sk->dead = 1; + nr_set_timer(sk); + break; + + case NETROM_T1: + if (nr_ctl.arg < 1) + return -EINVAL; + sk->nr->rtt = (nr_ctl.arg * PR_SLOWHZ) / 2; + sk->nr->t1 = nr_ctl.arg * PR_SLOWHZ; + save_flags(flags); cli(); + if (sk->nr->t1timer > sk->nr->t1) + sk->nr->t1timer = sk->nr->t1; + restore_flags(flags); + break; + + case NETROM_T2: + if (nr_ctl.arg < 1) + return -EINVAL; + save_flags(flags); cli(); + sk->nr->t2 = nr_ctl.arg * PR_SLOWHZ; + if (sk->nr->t2timer > sk->nr->t2) + sk->nr->t2timer = sk->nr->t2; + restore_flags(flags); + break; + + case NETROM_N2: + if (nr_ctl.arg < 1 || nr_ctl.arg > 10) + return -EINVAL; + sk->nr->n2count = 0; + sk->nr->n2 = nr_ctl.arg; + break; + + case NETROM_PACLEN: + if (nr_ctl.arg < 16 || nr_ctl.arg > 65535) + return -EINVAL; + if (nr_ctl.arg > 236) /* we probably want this */ + printk("nr_ctl_ioctl: Warning --- huge paclen %d\n", (int)nr_ctl.arg); + sk->nr->paclen = nr_ctl.arg; + break; + + default: + return -EINVAL; + } + + return 0; +} + static int nr_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) { @@ -326,6 +402,12 @@ case NETROM_HDRINCL: sk->nr->hdrincl = opt ? 1 : 0; return 0; + + case NETROM_PACLEN: + if (opt < 1 || opt > 65536) + return -EINVAL; + sk->nr->paclen = opt; + return 0; default: return -ENOPROTOOPT; @@ -364,6 +446,10 @@ val = sk->nr->hdrincl; break; + case NETROM_PACLEN: + val = sk->nr->paclen; + break; + default: return -ENOPROTOOPT; } @@ -461,6 +547,7 @@ nr->t1 = nr_default.timeout; nr->t2 = nr_default.ack_delay; nr->n2 = nr_default.tries; + nr->paclen = nr_default.paclen; nr->t1timer = 0; nr->t2timer = 0; @@ -542,6 +629,7 @@ nr->t1 = osk->nr->t1; nr->t2 = osk->nr->t2; nr->n2 = osk->nr->n2; + nr->paclen = osk->nr->paclen; nr->device = osk->nr->device; nr->bpqext = osk->nr->bpqext; @@ -1216,12 +1304,16 @@ return 0; } - default: + case SIOCNRCTLCON: + if (!suser()) return -EPERM; + return nr_ctl_ioctl(cmd, (void *)arg); + + default: return dev_ioctl(cmd, (void *)arg); } /*NOTREACHED*/ - return(0); + return 0; } static int nr_get_info(char *buffer, char **start, off_t offset, int length, int dummy) @@ -1235,7 +1327,7 @@ cli(); - len += sprintf(buffer, "user_addr dest_node src_node dev my your st vs vr va t1 t2 n2 rtt wnd Snd-Q Rcv-Q\n"); + len += sprintf(buffer, "user_addr dest_node src_node dev my your st vs vr va t1 t2 n2 rtt wnd paclen Snd-Q Rcv-Q\n"); for (s = nr_list; s != NULL; s = s->next) { if ((dev = s->nr->device) == NULL) @@ -1247,7 +1339,7 @@ ax2asc(&s->nr->user_addr)); len += sprintf(buffer + len, "%-9s ", ax2asc(&s->nr->dest_addr)); - len += sprintf(buffer + len, "%-9s %-3s %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %5d %5d\n", + len += sprintf(buffer + len, "%-9s %-3s %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %6d %5d %5d\n", ax2asc(&s->nr->source_addr), devname, s->nr->my_index, s->nr->my_id, s->nr->your_index, s->nr->your_id, @@ -1259,7 +1351,7 @@ s->nr->t2 / PR_SLOWHZ, s->nr->n2count, s->nr->n2, s->nr->rtt / PR_SLOWHZ, - s->window, + s->window, s->nr->paclen, s->wmem_alloc, s->rmem_alloc); pos = begin + len; @@ -1324,6 +1416,7 @@ nr_default.busy_delay = NR_DEFAULT_T4; nr_default.tries = NR_DEFAULT_N2; nr_default.window = NR_DEFAULT_WINDOW; + nr_default.paclen = NR_DEFAULT_PACLEN; proc_net_register(&(struct proc_dir_entry) { PROC_NET_NR, 2, "nr", diff -u --recursive --new-file v1.3.90/linux/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c --- v1.3.90/linux/net/netrom/nr_dev.c Mon Mar 25 08:58:26 1996 +++ linux/net/netrom/nr_dev.c Thu Apr 18 14:35:34 1996 @@ -15,6 +15,8 @@ * History * NET/ROM 001 Jonathan(G4KLX) Cloned from loopback.c * NET/ROM 002 Steve Whitehouse(GW7RRM) fixed the set_mac_address + * NET/ROM 003 Jonathan(G4KLX) Put nr_rebuild_header into line with + * ax25_rebuild_header */ #include @@ -109,12 +111,10 @@ { struct enet_statistics *stats = (struct enet_statistics *)dev->priv; unsigned char *bp = (unsigned char *)buff; - - skb_device_unlock(skb); + struct sk_buff *skbn; if (!arp_query(bp + 7, raddr, dev)) { - skb->free = 1; - kfree_skb(skb, FREE_WRITE); + dev_kfree_skb(skb, FREE_WRITE); return 1; } @@ -127,9 +127,20 @@ bp[6] |= LAPB_E; bp[6] |= SSSID_SPARE; - if (!nr_route_frame(skb, NULL)) { - skb->free = 1; - kfree_skb(skb, FREE_WRITE); + if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { + dev_kfree_skb(skb, FREE_WRITE); + return 1; + } + + skbn->sk = skb->sk; + + if (skbn->sk != NULL) + atomic_add(skbn->truesize, &skbn->sk->wmem_alloc); + + dev_kfree_skb(skb, FREE_WRITE); + + if (!nr_route_frame(skbn, NULL)) { + dev_kfree_skb(skbn, FREE_WRITE); stats->tx_errors++; } diff -u --recursive --new-file v1.3.90/linux/net/netrom/nr_out.c linux/net/netrom/nr_out.c --- v1.3.90/linux/net/netrom/nr_out.c Wed Feb 21 08:33:26 1996 +++ linux/net/netrom/nr_out.c Thu Apr 18 14:35:34 1996 @@ -52,7 +52,7 @@ unsigned char transport[NR_TRANSPORT_LEN]; int err, frontlen, len, mtu; - mtu = sk->nr->device->mtu; + mtu = sk->nr->paclen; if (skb->len - NR_TRANSPORT_LEN > mtu) { /* Save a copy of the Transport Header */ diff -u --recursive --new-file v1.3.90/linux/scripts/Menuconfig linux/scripts/Menuconfig --- v1.3.90/linux/scripts/Menuconfig Fri Apr 12 15:52:13 1996 +++ linux/scripts/Menuconfig Thu Apr 18 14:38:54 1996 @@ -82,7 +82,7 @@ n) flag=" " ;; esac - echo -ne "'$2' '($flag) $1' " >>MCmenu + echo -ne "'$2' '[$flag] $1' " >>MCmenu echo -e "function $2 () { l_bool '$2' \"\$1\" }\n" >>MCradiolists } @@ -245,10 +245,10 @@ if extract_help $1 >help.out then $DIALOG --backtitle "$backtitle" --title "$2"\ - --textbox help.out $LINES $COLS + --textbox help.out $ROWS $COLS else $DIALOG --backtitle "$backtitle" \ - --textbox help.out $LINES $COLS + --textbox help.out $ROWS $COLS fi rm help.out } @@ -258,7 +258,7 @@ # function show_readme () { $DIALOG --backtitle "$backtitle" \ - --textbox scripts/README.Menuconfig $LINES $COLS + --textbox scripts/README.Menuconfig $ROWS $COLS } # @@ -269,7 +269,7 @@ echo -ne "$DIALOG --title '$1'\ --backtitle '$backtitle' \ --menu '$menu_instructions' \ - $LINES $COLS $((LINES-10)) \ + $ROWS $COLS $((ROWS-10)) \ '$default' " >MCmenu >MCradiolists } @@ -306,6 +306,11 @@ then case "$2" in y|m) eval $1=y ;; + c) eval x=\$$1 + case $x in + y) eval $1=n ;; + n) eval $1=y ;; + esac ;; *) eval $1=n ;; esac else @@ -336,7 +341,19 @@ if [ -n "$2" ] then case "$2" in - y|m) eval $1=m ;; + y) echo -en "\007" + ${DIALOG} --backtitle "$backtitle" \ + --infobox "\ +This feature depends on another which has been configured as a module. \ +As a result, this feature will be built as a module." 4 70 + sleep 5 + eval $1=m ;; + m) eval $1=m ;; + c) eval x=\$$1 + case $x in + m) eval $1=n ;; + n) eval $1=m ;; + esac ;; *) eval $1=n ;; esac else @@ -350,9 +367,17 @@ function l_tristate () { if [ -n "$2" ] then + eval x=\$$1 + case "$2" in y) eval $1=y ;; m) eval $1=m ;; + c) eval x=\$$1 + case $x in + y) eval $1=n ;; + n) eval $1=m ;; + m) eval $1=y ;; + esac ;; *) eval $1=n ;; esac else @@ -628,18 +653,19 @@ read selection "*|*"alt_config"*) @@ -711,7 +737,7 @@ EOM $DIALOG --backtitle "$backtitle"\ --title "Load Alternate Configuration"\ - --textbox help.out $LINES $COLS + --textbox help.out $ROWS $COLS fi done @@ -771,7 +797,7 @@ EOM $DIALOG --backtitle "$backtitle"\ --title "Store Alternate Configuration"\ - --textbox help.out $LINES $COLS + --textbox help.out $ROWS $COLS fi done @@ -991,35 +1017,38 @@ rm -f .tmpconfig .tmpconfig.h } -x=`stty -a` -case $x in -*\ rows\ *\;*) - LINES=${x##*rows} LINES=${LINES%%;*} LINES=$((${LINES:-25}-4)) - COLS=${x##*columns} COLS=${COLS%%;*} COLS=$((${COLS:-80}-5)) - ;; -*) - LINES=21 - COLS=75 - ;; -esac - -if [ $LINES -lt 15 -o $COLS -lt 75 ] -then - echo -e "\n\007Your display is too small to run Menuconfig!\n" - echo "It is currently set to $LINES lines by $COLS columns." - echo "It must be at least 15 lines by 75 columns." - exit 0 -fi +set_geometry () { + # Some distributions export these with incorrect values + # which can really screw up some ncurses programs. + unset LINES COLUMNS + + ROWS=${1:-24} COLS=${2:-80} + + # Just in case the nasty rlogin bug returns. + # + [ $ROWS = 0 ] && ROWS=24 + [ $COLS = 0 ] && COLS=80 + + if [ $ROWS -lt 19 -o $COLS -lt 80 ] + then + echo -e "\n\007Your display is too small to run Menuconfig!" + echo "It must be at least 19 lines by 80 columns." + exit 0 + fi + + ROWS=$((ROWS-4)) COLS=$((COLS-5)) +} + +set_geometry `stty size 2>/dev/null` menu_instructions="\ Arrow keys navigate the menu. \ + selects submenus --->. \ Highlighted letters are hotkeys. \ -Pressing includes a feature, excludes it, makes it modular. \ -Press to exit or for Help. \ -(*) shows built in features. \ -(M) shows modules. \ -< > features are module capable." +Pressing includes, excludes, modularizes features. \ +Press to exit, for Help. \ +Legend: [*] built-in [ ] excluded module < > module capable" radiolist_instructions="\ Use the arrow keys to navigate this window or \ diff -u --recursive --new-file v1.3.90/linux/scripts/README.Menuconfig linux/scripts/README.Menuconfig --- v1.3.90/linux/scripts/README.Menuconfig Fri Apr 12 15:52:13 1996 +++ linux/scripts/README.Menuconfig Thu Apr 18 14:38:54 1996 @@ -11,27 +11,28 @@ kernel parameters which are not really features, but must be entered in as decimal or hexadecimal numbers or possibly text. -Menu items beginning with (*), (M) or ( ) represent features +Menu items beginning with [*], or [ ] represent features configured to be built in, modularized or removed respectively. Pointed brackets <> represent module capable features. more... To change any of these features, highlight it with the cursor keys and press to build it in, to make it a module or - to removed it. (See keyboard hints below) + to removed it. You may also press the to cycle +through the available options (ie. Y->N->M->Y). Items beginning with numbers or other text within parenthesis can be changed by highlighting the item and pressing . Then enter the new parameter into the dialog box that pops up. -Some keyboard hints: +Some additional keyboard hints: Menus ---------- o Use the Up/Down arrow keys (cursor keys) to highlight the item - you wish to change or submenu wish to select. Submenus are - designated by "--->". + you wish to change or submenu wish to select and press . + Submenus are designated by "--->". Shortcut: Press the option's highlighted letter (hotkey). Pressing a hotkey more than once will sequence @@ -136,8 +137,13 @@ Menuconfig will display larger menus on screens or xterms which are set to display more than the standard 25 row by 80 column geometry. -In order for this to work, the "stty -a" command must be able to -display the screen's current row and column geometry. +In order for this to work, the "stty size" command must be able to +display the screen's current row and column geometry. I STRONGLY +RECOMMEND that you make sure you do NOT have the shell variables +LINES and COLUMNS exported into your environment. Some distributions +export those variables via /etc/profile. Some ncurses programs can +become confused when those variables (LINES & COLUMNS) don't reflect +the true screen size. NOTICE: lxdialog requires the ncurses libraries to compile. If you diff -u --recursive --new-file v1.3.90/linux/scripts/lxdialog/dialog.h linux/scripts/lxdialog/dialog.h --- v1.3.90/linux/scripts/lxdialog/dialog.h Fri Apr 12 15:52:13 1996 +++ linux/scripts/lxdialog/dialog.h Thu Apr 18 14:38:54 1996 @@ -131,7 +131,7 @@ chtype border); void draw_shadow (WINDOW * win, int y, int x, int height, int width); -int first_alpha (const char *string); +int first_alpha (const char *string, const char *exempt); int dialog_yesno (const char *title, const char *prompt, int height, int width); int dialog_msgbox (const char *title, const char *prompt, int height, int width, int pause); @@ -145,8 +145,6 @@ extern unsigned char dialog_input_result[]; int dialog_inputbox (const char *title, const char *prompt, int height, int width, const char *init); -int dialog_gauge (const char *title, const char *prompt, int height, int width, - int percent); /* * This is the base for fictitious keys, which activate diff -u --recursive --new-file v1.3.90/linux/scripts/lxdialog/menubox.c linux/scripts/lxdialog/menubox.c --- v1.3.90/linux/scripts/lxdialog/menubox.c Wed Mar 27 08:19:29 1996 +++ linux/scripts/lxdialog/menubox.c Thu Apr 18 14:38:54 1996 @@ -34,7 +34,7 @@ strncpy(menu_item, item, menu_width); menu_item[menu_width] = 0; - j = first_alpha(menu_item); + j = first_alpha(menu_item, "YyNnMm"); /* Clear 'residue' of last item */ wattrset (win, menubox_attr); @@ -205,13 +205,13 @@ i = max_choice; else { for (i = choice+1; i < max_choice; i++) { - j = first_alpha(items[(scroll+i)*2+1]); + j = first_alpha(items[(scroll+i)*2+1], "YyNnMm"); if (key == tolower(items[(scroll+i)*2+1][j])) break; } if (i == max_choice) for (i = 0; i < max_choice; i++) { - j = first_alpha(items[(scroll+i)*2+1]); + j = first_alpha(items[(scroll+i)*2+1], "YyNnMm"); if (key == tolower(items[(scroll+i)*2+1][j])) break; } @@ -308,15 +308,20 @@ print_buttons(dialog, height, width, button); wrefresh (dialog); break; + case ' ': case 's': case 'y': case 'n': case 'm': delwin (dialog); fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); - if (key == 'y') return 3; - if (key == 'n') return 4; - if (key == 'm') return 5; + switch (key) { + case 's': return 3; + case 'y': return 3; + case 'n': return 4; + case 'm': return 5; + case ' ': return 6; + } return 0; case 'h': case '?': @@ -327,7 +332,7 @@ fprintf(stderr, "%s \"%s\"\n", items[(scroll + choice) * 2], items[(scroll + choice) * 2 + 1] + - first_alpha(items[(scroll + choice) * 2 + 1])); + first_alpha(items[(scroll + choice) * 2 + 1],"")); else fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); diff -u --recursive --new-file v1.3.90/linux/scripts/lxdialog/util.c linux/scripts/lxdialog/util.c --- v1.3.90/linux/scripts/lxdialog/util.c Wed Mar 27 08:19:29 1996 +++ linux/scripts/lxdialog/util.c Thu Apr 18 14:38:54 1996 @@ -36,33 +36,33 @@ { A_NORMAL, /* screen_attr */ A_NORMAL, /* shadow_attr */ - A_REVERSE, /* dialog_attr */ - A_REVERSE, /* title_attr */ - A_REVERSE, /* border_attr */ - A_BOLD, /* button_active_attr */ + A_NORMAL, /* dialog_attr */ + A_BOLD, /* title_attr */ + A_NORMAL, /* border_attr */ + A_REVERSE, /* button_active_attr */ A_DIM, /* button_inactive_attr */ - A_UNDERLINE, /* button_key_active_attr */ - A_UNDERLINE, /* button_key_inactive_attr */ - A_NORMAL, /* button_label_active_attr */ + A_REVERSE, /* button_key_active_attr */ + A_BOLD, /* button_key_inactive_attr */ + A_REVERSE, /* button_label_active_attr */ A_NORMAL, /* button_label_inactive_attr */ - A_REVERSE, /* inputbox_attr */ - A_REVERSE, /* inputbox_border_attr */ - A_REVERSE, /* searchbox_attr */ - A_REVERSE, /* searchbox_title_attr */ - A_REVERSE, /* searchbox_border_attr */ - A_REVERSE, /* position_indicator_attr */ - A_REVERSE, /* menubox_attr */ - A_REVERSE, /* menubox_border_attr */ - A_REVERSE, /* item_attr */ - A_NORMAL, /* item_selected_attr */ - A_REVERSE, /* tag_attr */ + A_NORMAL, /* inputbox_attr */ + A_NORMAL, /* inputbox_border_attr */ + A_NORMAL, /* searchbox_attr */ + A_BOLD, /* searchbox_title_attr */ + A_NORMAL, /* searchbox_border_attr */ + A_BOLD, /* position_indicator_attr */ + A_NORMAL, /* menubox_attr */ + A_NORMAL, /* menubox_border_attr */ + A_NORMAL, /* item_attr */ + A_REVERSE, /* item_selected_attr */ + A_BOLD, /* tag_attr */ A_REVERSE, /* tag_selected_attr */ - A_NORMAL, /* tag_key_attr */ - A_BOLD, /* tag_key_selected_attr */ - A_REVERSE, /* check_attr */ + A_BOLD, /* tag_key_attr */ + A_REVERSE, /* tag_key_selected_attr */ + A_BOLD, /* check_attr */ A_REVERSE, /* check_selected_attr */ - A_REVERSE, /* uarrow_attr */ - A_REVERSE /* darrow_attr */ + A_BOLD, /* uarrow_attr */ + A_BOLD /* darrow_attr */ }; @@ -340,7 +340,7 @@ * Return the position of the first alphabetic character in a string. */ int -first_alpha(const char *string) +first_alpha(const char *string, const char *exempt) { int i, in_paren=0, c; @@ -351,7 +351,7 @@ if (c == ')') --in_paren; if ((! in_paren) && isalpha(c) && - strchr("nNyYmM", c) == 0) + strchr(exempt, c) == 0) return i; }