]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.5 - and a vacation 2.2.5
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:18:31 +0000 (15:18 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:18:31 +0000 (15:18 -0500)
I made Linux-2.2.5 yesterday (as some people already have noticed: due to
popular demand I try to delay the announcement for some time in order to
let the thing percolate to mirror sites, in case anybody wondered).
The 2.2.5 release is meant to be a final cleanup release before I leave
for a two-week vacation. So please take these release notes to also mean
that it is probably a good idea to hold off emailing me stuff directly,
unless it is a major bug that you really think I should look at
immediately. I would suggest people discuss problems on the mailing list
and on the newsgroups, where other competent people are, rather than
expecting me to do much about it.

Also, note that there have been various indications that egcs potentially
miscompiles the kernel, or at least makes some problems worse. We don't
know whether that is due to one or more kernel bugs, compiler problems, or
just combinations of "features" in both. I would suggest that if you have
problems you at least verify whether the problems still exist with
gcc-2.7.2.

That said, I bet that both the kernel people and the egcs people would be
really happy the more people look into this - if somebody feels motivated
enough and sees problems with egcs, it would be extremely powerful to try
to pinpoint the particular file that seems to bring on the problems. I'm
afraid it needs a known failure mode and lots of legwork to find out what
triggers it, though.

 - compiles with accounting.
 - add support for Microgate SyncLink and Synchronous HDLC
 - stallion driver update
 - alpha EV6 and SMP fix for bootup with newer compilers
 - ptrace fix for sparc/i386
 - small sparc updates
 - floppy driver could oops at bootup under certain setups
 - random driver updates (bw-qcam, sound driver error codes, etc oneliners)
 - FIOASYNC ioctl fix
 - network locking fixes
 - SMP "struct user" and signal sending fixes

Have fun, because I will,

                        Linus

20 files changed:
Documentation/stallion.txt
arch/alpha/kernel/smp.c
arch/sparc64/kernel/smp.c
arch/sparc64/mm/init.c
arch/sparc64/mm/ultra.S
drivers/char/istallion.c
drivers/char/stallion.c
drivers/char/synclink.c
drivers/fc4/socal.c
drivers/video/fbcon.c
include/asm-i386/timex.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/smp.h
include/linux/if_arp.h
include/linux/sched.h
include/net/sock.h
net/core/sock.c
net/ipv4/ipconfig.c
net/ipv4/tcp_ipv4.c
net/ipv6/tcp_ipv6.c

index 5a1a30320a974c16f001a7920379197c721bb690..65f4bcb8a52fd6e589d86d089d0fd128e86d5c6f 100644 (file)
@@ -2,10 +2,10 @@
 Stallion Multiport Serial Driver Readme
 ---------------------------------------
 
-Copyright (C) 1994-1998,  Stallion Technologies (support@stallion.com).
+Copyright (C) 1994-1999,  Stallion Technologies (support@stallion.com).
 
-Version:   5.4.7
-Date:      23OCT98
+Version:   5.5.1
+Date:      28MAR99
 
 
 
@@ -15,28 +15,28 @@ There are two drivers that work with the different families of Stallion
 multiport serial boards. One is for the Stallion smart boards - that is
 EasyIO, EasyConnection 8/32 and EasyConnection 8/64-PCI, the other for
 the true Stallion intelligent multiport boards - EasyConnection 8/64
-(ISA and EISA), ONboard and Brumby.
+(ISA, EISA, MCA), EasyConnection/RA-PCI, ONboard and Brumby.
 
 If you are using any of the Stallion intelligent multiport boards (Brumby,
-ONboard, EasyConnection 8/64 (ISA or EISA)) with Linux you will need to
-get the driver utility package. This package is available at most of the
-Linux archive sites (and on CD-ROMs that contain these archives). The file
-will be called stallion-X.X.X.tar.gz where X.X.X will be the version
-number. In particular this package contains the board embedded executable
-images that are required for these boards. It also contains the downloader
-program. These boards cannot be used without this.
+ONboard, EasyConnection 8/64 (ISA, EISA, MCA), EasyConnection/RA-PCI) with
+Linux you will need to get the driver utility package. This package is
+available at most of the Linux archive sites (and on CD-ROMs that contain
+these archives). The file will be called stallion-X.X.X.tar.gz where X.X.X
+will be the version number. In particular this package contains the board
+embedded executable images that are required for these boards. It also
+contains the downloader program. These boards cannot be used without this.
 
 The Stallion Technologies ftp site, ftp.stallion.com, will always have
 the latest version of the driver utility package. Other sites that usually
 have the latest version are tsx-11.mit.edu, sunsite.unc.edu and their
 mirrors.
 
-ftp.stallion.com:/drivers/ata5/Linux/v544.tar.gz
-tsx-11.mit.edu:/pub/linux/packages/stallion/stallion-5.4.4.tar.gz
-sunsite.unc.edu:/pub/Linux/kernel/patches/serial/stallion-5.4.4.tar.gz
+ftp.stallion.com:/drivers/ata5/Linux/v550.tar.gz
+tsx-11.mit.edu:/pub/linux/packages/stallion/stallion-5.5.0.tar.gz
+sunsite.unc.edu:/pub/Linux/kernel/patches/serial/stallion-5.5.0.tar.gz
 
 As of the printing of this document the latest version of the driver
-utility package is 5.4.4. If a later version is now available then you
+utility package is 5.5.0. If a later version is now available then you
 should use the latest version.
 
 If you are using the EasyIO, EasyConnection 8/32 or EasyConnection 8/64-PCI
@@ -44,7 +44,7 @@ boards then you don't need this package. Although it does have a handy
 script to create the /dev device nodes for these boards, and a serial stats
 display program.
 
-If you require DIP switch settings, EISA/MCA configuration files, or any
+If you require DIP switch settings, EISA or MCA configuration files, or any
 other information related to Stallion boards then have a look at Stallion's
 web pages at http://www.stallion.com.
 
@@ -55,12 +55,101 @@ web pages at http://www.stallion.com.
 The drivers can be used as loadable modules or compiled into the kernel.
 You can choose which when doing a "config" on the kernel.
 
-All ISA, EISA and MCA boards that you want to use need to be entered into
-the driver(s) configuration structures. All PCI boards will be automatically
-detected when you load the driver - so they do not need to be entered into
-the driver(s) configuration structure. (Note that kernel PCI BIOS32 support
-is required to use PCI boards.)
+All ISA, EISA and MCA boards that you want to use need to be configured into
+the driver(s). All PCI boards will be automatically detected when you load
+the driver - so they do not need to be entered into the driver(s)
+configuration structure. Note that kernel PCI support is required to use PCI
+boards.
 
+There are two methods of configuring ISA, EISA and MCA boards into the drivers.
+If using the driver as a loadable module then the simplist method is to pass
+the driver configuration as module arguments. The other method is to modify
+the driver source to add configuration lines for each board in use.
+
+If you have pre-built Stallion driver modules then the module argument
+configuration method should be used. A lot of Linux distributions come with
+pre-built driver modules in /lib/modules/X.Y.Z/misc for the kernel in use.
+That makes things pretty simple to get going.
+
+
+2.1 MODULE DRIVER CONFIGURATION:
+
+The simplest configuration for modules is to use the module load arguments
+to configure any ISA, EISA or MCA boards. PCI boards are automatically
+detected, so do not need any additional configuration at all.
+
+If using EasyIO, EasyConnection 8/32 ISA or MCA, or EasyConnection 8/63-PCI
+boards then use the "stallion" driver module, Otherwise if you are using
+an EasyConnection 8/64 ISA, EISA or MCA, EasyConnection/RA-PCI, ONboard,
+Brumby or original Stallion board then use the "istallion" driver module.
+
+Typically to load up the smart board driver use:
+
+    insmod stallion.o
+
+This will load the EasyIO and EasyConnection 8/32 driver. It will output a
+message to say that it loaded and print the driver version number. It will
+also print out whether it found the configured boards or not. These messages
+may not appear on the console, but typically are always logged to
+/var/adm/messages or /var/log/syslog files - depending on how the klogd and
+syslogd daemons are setup on your system.
+
+To load the intelligent board driver use:
+
+    insmod istallion.o
+
+It will output similar messages to the smart board driver.
+
+If not using an auto-detectable board type (that is a PCI board) then you
+will also need to supply command line arguments to the "insmod" command
+when loading the driver. The general form of the configuration argument is
+
+    board?=<name>[,<ioaddr>[,<addr>][,<irq>]]
+
+where:
+
+    board?  -- specifies the arbitary board number of this board,
+               can be in the range 0 to 3.
+
+    name    -- textual name of this board. The board name is the comman
+               board name, or any "shortened" version of that. The board
+               type number may also be used here.
+
+    ioaddr  -- specifies the I/O address of this board. This argument is
+               optional, but should generally be specified.
+
+    addr    -- optional second address argument. Some board types require
+               a second I/O address, some require a memory address. The
+               exact meaning of this argument depends on the board type.
+
+    irq     -- optional IRQ line used by this board.
+
+Up to 4 board configuration arguments can be specified on the load line.
+Here is some examples:
+
+    insmod stallion.o board0=easyio,0x2a0,5
+
+This configures an EasyIO board as board 0 at I/O address 0x2a0 and IRQ 5.
+
+    insmod istallion.o board3=ec8/64,0x2c0,0xcc000
+
+This configures an EasyConnection 8/64 ISA as board 3 at I/O address 0x2c0 at
+memory address 0xcc000.
+
+    insmod stallion.o board1=ec8/32-at,0x2a0,0x280,10
+
+This configures an EasyConnection 8/32 ISA board at primary I/O address 0x2a0,
+secondary address 0x280 and IRQ 10.
+
+You will probably want to enter this module load and configuration information
+into your system startup scripts so that the drivers are loaded and configured
+on each system boot. Typically the start up script would be something line
+/etc/rc.d/rc.modules.
+
+
+2.2 STATIC DRIVER CONFIGURATION:
+
+For static driver configuration you need to modify the driver source code.
 Entering ISA, EISA and MCA boards into the driver(s) configuration structure
 involves editing the driver(s) source file. It's pretty easy if you follow
 the instructions below. Both drivers can support up to 4 boards. The smart
@@ -96,14 +185,16 @@ When the new kernel is booted, or the loadable module loaded then the
 driver will emit some kernel trace messages about whether the configured
 boards were detected or not. Depending on how your system logger is set
 up these may come out on the console, or just be logged to
-/var/adm/messages. You should check the messages to confirm that all is well.
+/var/adm/messages or /var/log/syslog. You should check the messages to
+confirm that all is well.
 
 
-2.1 SHARING INTERRUPTS
+2.3 SHARING INTERRUPTS
 
 It is possible to share interrupts between multiple EasyIO and
-EasyConnection 8/32 boards in an EISA system. To do this you will need to
-do a couple of things:
+EasyConnection 8/32 boards in an EISA system. To do this you must be using
+static driver configuration, modifying the driver source code to add driver
+configuration. Then a couple of extra things are required:
 
 1. When entering the board resources into the stallion.c file you need to
    mark the boards as using level triggered interrupts. Do this by replacing
@@ -130,7 +221,7 @@ or load the driver your EasyIO and EasyConnection 8/32 boards will be
 sharing interrupts.
 
 
-2.2 USING HIGH SHARED MEMORY
+2.4 USING HIGH SHARED MEMORY
 
 The EasyConnection 8/64-EI, ONboard and Stallion boards are capable of
 using shared memory addresses above the usual 640K - 1Mb range. The ONboard
@@ -145,16 +236,18 @@ Just enter the address as you normally would for a lower than 1Mb address
 
 
 
-2.3 TROUBLE SHOOTING
+2.5 TROUBLE SHOOTING
 
 If a board is not found by the driver but is actually in the system then the
-most likely problem is that the I/O address is wrong. Change it in the driver
-stallion.c or istallion.c configuration structure and rebuild the kernel or
-modules, or change it on the board. On EasyIO and EasyConnection 8/32 boards
-the IRQ is software programmable, so if there is a conflict you may need to
-change the IRQ used for a board in the stallion.c configuration structure.
-There are no interrupts to worry about for ONboard, Brumby or EasyConnection
-8/64 (ISA, EISA and MCA) boards. The memory region on EasyConnection 8/64 and
+most likely problem is that the I/O address is wrong. Change the module load
+argument for the loadable module form. Or change it in the driver stallion.c
+or istallion.c configuration structure and rebuild the kernel or modules, or
+change it on the board.
+
+On EasyIO and EasyConnection 8/32 boards the IRQ is software programmable, so
+if there is a conflict you may need to change the IRQ used for a board. There
+are no interrupts to worry about for ONboard, Brumby or EasyConnection 8/64
+(ISA, EISA and MCA) boards. The memory region on EasyConnection 8/64 and
 ONboard boards is software programmable, but not on the Brumby boards.
 
 
@@ -167,9 +260,13 @@ The intelligent boards also need to have their "firmware" code downloaded
 to them. This is done via a user level application supplied in the driver
 utility package called "stlload". Compile this program wherever you dropped
 the package files, by typing "make". In its simplest form you can then type
+
     ./stlload -i cdk.sys
+
 in this directory and that will download board 0 (assuming board 0 is an
-EasyConnection 8/64 board). To download to an ONboard, Brumby or Stallion do:
+EasyConnection 8/64 or EasyConnection/RA board). To download to an
+ONboard, Brumby or Stallion do:
+
     ./stlload -i 2681.sys
 
 Normally you would want all boards to be downloaded as part of the standard
@@ -182,6 +279,7 @@ file in the stlload down-loader is /usr/lib/stallion. Create that directory
 and put the cdk.sys and 2681.sys files in it. (It's a convenient place to put
 them anyway). As an example your /etc/rc.d/rc.S file might have the
 following lines added to it (if you had 3 boards):
+
     /usr/sbin/stlload -b 0 -i /usr/lib/stallion/cdk.sys
     /usr/sbin/stlload -b 1 -i /usr/lib/stallion/2681.sys
     /usr/sbin/stlload -b 2 -i /usr/lib/stallion/2681.sys
index 25615e43de0c21cfcfa4eac9b3666a8fba7b999b..b905a66b73cad14355c720d39b440a63c4c6579f 100644 (file)
@@ -499,6 +499,7 @@ secondary_cpu_start(int cpuid, struct task_struct *idle)
                        return;
                }
                mdelay(1);
+               barrier();
        }
        DBGS(("secondary_cpu_start: SUCCESS for CPU %d!!!\n", cpuid));
 }
@@ -541,6 +542,7 @@ delay1:
                if (!(hwrpb->txrdy & cpumask))
                        goto ready1;
                udelay(100);
+               barrier();
        }
        goto timeout;
 
@@ -549,6 +551,7 @@ delay2:
                if (!(hwrpb->txrdy & cpumask))
                        goto ready2;
                udelay(100);
+               barrier();
        }
        goto timeout;
 
index 54b100e331489ea6aede50432acc0876fbebfecf..f2c921ab3f8a1f506b0a1826f8252b8b69ed214b 100644 (file)
@@ -347,6 +347,17 @@ extern unsigned long xcall_flush_tlb_all;
 extern unsigned long xcall_tlbcachesync;
 extern unsigned long xcall_flush_cache_all;
 extern unsigned long xcall_report_regs;
+extern unsigned long xcall_receive_signal;
+
+void smp_receive_signal(int cpu)
+{
+       if(smp_processors_ready &&
+          (cpu_present_map & (1UL<<cpu)) != 0) {
+               u64 pstate, data0 = (((u64)&xcall_receive_signal) & 0xffffffff);
+               __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
+               xcall_deliver(data0, 0, 0, pstate, cpu);
+       }
+}
 
 void smp_report_regs(void)
 {
index d44dbbab4e024536d2dd8f39bfa0a6ac4464bbb7..fd1a56e56baac04b847402cd276cd096f569f3f0 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.124 1999/02/08 07:01:42 ecd Exp $
+/*  $Id: init.c,v 1.125 1999/03/28 08:39:33 davem Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -142,9 +142,9 @@ void show_mem(void)
        printk("%d reserved pages\n",reserved);
        printk("%d pages shared\n",shared);
        printk("%d pages swap cached\n",cached);
-       printk("%ld pages in page table cache\n",pgtable_cache_size);
+       printk("%d pages in page table cache\n",pgtable_cache_size);
 #ifndef __SMP__
-       printk("%ld entries in page dir cache\n",pgd_cache_size);
+       printk("%d entries in page dir cache\n",pgd_cache_size);
 #endif 
        show_buffers();
 #ifdef CONFIG_NET
index 4362a15b4bf2bb90391bab0e8c798b14e274dd19..3d3d1a2892c00eb5574acb99b61490009a5d9b63 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.31 1998/11/07 06:39:21 davem Exp $
+/* $Id: ultra.S,v 1.32 1999/03/28 08:39:34 davem Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -261,6 +261,21 @@ xcall_capture:
        b,pt            %xcc, rtrap
         clr            %l6
 
+       .globl          xcall_receive_signal
+xcall_receive_signal:
+       rdpr            %pstate, %g2
+       wrpr            %g2, PSTATE_IG | PSTATE_AG, %pstate
+       rdpr            %tstate, %g1
+       andcc           %g1, TSTATE_PRIV, %g0
+       /* If we did not trap from user space, just ignore. */
+       bne,pn          %xcc, 99f
+        sethi          %hi(109f), %g7
+       b,pt            %xcc, etrap
+109:    or             %g7, %lo(109b), %g7
+       b,pt            %xcc, rtrap
+        clr            %l6
+99:    retry
+
        /* These two are not performance critical... */
        .globl          xcall_flush_tlb_all
 xcall_flush_tlb_all:
index a1a6d93a1a3307cec24dc28f27db64dae99fb4f7..28542b450a0005c3f2b19eb3ab51988887d4e178 100644 (file)
@@ -3,7 +3,7 @@
 /*
  *     istallion.c  -- stallion intelligent multiport serial driver.
  *
- *     Copyright (C) 1996-1998  Stallion Technologies (support@stallion.oz.au).
+ *     Copyright (C) 1996-1999  Stallion Technologies (support@stallion.oz.au).
  *     Copyright (C) 1994-1996  Greg Ungerer (gerg@stallion.oz.au).
  *
  *     This code is loosely based on the Linux serial driver, written by
 /*****************************************************************************/
 
 #include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/wait.h>
+#include <linux/malloc.h>
 #include <linux/interrupt.h>
-#include <linux/termios.h>
-#include <linux/fcntl.h>
-#include <linux/tty_driver.h>
-#include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/cdk.h>
 #include <linux/comstats.h>
 #include <linux/istallion.h>
-#include <linux/string.h>
-#include <linux/malloc.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <asm/system.h>
+
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_PCI
+#include <linux/pci.h>
+#endif
+
 /*****************************************************************************/
 
 /*
@@ -79,6 +74,7 @@
 #define        BRD_ECHPCI      26
 #define        BRD_ECH64PCI    27
 #define        BRD_EASYIOPCI   28
+#define        BRD_ECPPCI      29
 
 #define        BRD_BRUMBY      BRD_BRUMBY4
 
@@ -131,7 +127,7 @@ typedef struct {
 } stlconf_t;
 
 static stlconf_t       stli_brdconf[] = {
-       { BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },
+       /*{ BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },*/
 };
 
 static int     stli_nrbrds = sizeof(stli_brdconf) / sizeof(stlconf_t);
@@ -170,7 +166,7 @@ static int  stli_nrbrds = sizeof(stli_brdconf) / sizeof(stlconf_t);
  */
 static char    *stli_drvtitle = "Stallion Intelligent Multiport Serial Driver";
 static char    *stli_drvname = "istallion";
-static char    *stli_drvversion = "5.4.7";
+static char    *stli_drvversion = "5.5.1";
 static char    *stli_serialname = "ttyE";
 static char    *stli_calloutname = "cue";
 
@@ -296,8 +292,110 @@ static char       *stli_brdnames[] = {
        "EC8/32-PCI",
        "EC8/64-PCI",
        "EasyIO-PCI",
+       "EC/RA-PCI",
 };
 
+/*****************************************************************************/
+
+#ifdef MODULE
+/*
+ *     Define some string labels for arguments passed from the module
+ *     load line. These allow for easy board definitions, and easy
+ *     modification of the io, memory and irq resoucres.
+ */
+
+static char    *board0[8];
+static char    *board1[8];
+static char    *board2[8];
+static char    *board3[8];
+
+static char    **stli_brdsp[] = {
+       (char **) &board0,
+       (char **) &board1,
+       (char **) &board2,
+       (char **) &board3
+};
+
+/*
+ *     Define a set of common board names, and types. This is used to
+ *     parse any module arguments.
+ */
+
+typedef struct stlibrdtype {
+       char    *name;
+       int     type;
+} stlibrdtype_t;
+
+static stlibrdtype_t   stli_brdstr[] = {
+       { "stallion", BRD_STALLION },
+       { "1", BRD_STALLION },
+       { "brumby", BRD_BRUMBY },
+       { "brumby4", BRD_BRUMBY },
+       { "brumby/4", BRD_BRUMBY },
+       { "brumby-4", BRD_BRUMBY },
+       { "brumby8", BRD_BRUMBY },
+       { "brumby/8", BRD_BRUMBY },
+       { "brumby-8", BRD_BRUMBY },
+       { "brumby16", BRD_BRUMBY },
+       { "brumby/16", BRD_BRUMBY },
+       { "brumby-16", BRD_BRUMBY },
+       { "2", BRD_BRUMBY },
+       { "onboard2", BRD_ONBOARD2 },
+       { "onboard-2", BRD_ONBOARD2 },
+       { "onboard/2", BRD_ONBOARD2 },
+       { "onboard-mc", BRD_ONBOARD2 },
+       { "onboard/mc", BRD_ONBOARD2 },
+       { "onboard-mca", BRD_ONBOARD2 },
+       { "onboard/mca", BRD_ONBOARD2 },
+       { "3", BRD_ONBOARD2 },
+       { "onboard", BRD_ONBOARD },
+       { "onboardat", BRD_ONBOARD },
+       { "4", BRD_ONBOARD },
+       { "onboarde", BRD_ONBOARDE },
+       { "onboard-e", BRD_ONBOARDE },
+       { "onboard/e", BRD_ONBOARDE },
+       { "onboard-ei", BRD_ONBOARDE },
+       { "onboard/ei", BRD_ONBOARDE },
+       { "7", BRD_ONBOARDE },
+       { "ecp", BRD_ECP },
+       { "ecpat", BRD_ECP },
+       { "ec8/64", BRD_ECP },
+       { "ec8/64-at", BRD_ECP },
+       { "ec8/64-isa", BRD_ECP },
+       { "23", BRD_ECP },
+       { "ecpe", BRD_ECPE },
+       { "ecpei", BRD_ECPE },
+       { "ec8/64-e", BRD_ECPE },
+       { "ec8/64-ei", BRD_ECPE },
+       { "24", BRD_ECPE },
+       { "ecpmc", BRD_ECPMC },
+       { "ec8/64-mc", BRD_ECPMC },
+       { "ec8/64-mca", BRD_ECPMC },
+       { "25", BRD_ECPMC },
+       { "ecppci", BRD_ECPPCI },
+       { "ec/ra", BRD_ECPPCI },
+       { "ec/ra-pc", BRD_ECPPCI },
+       { "ec/ra-pci", BRD_ECPPCI },
+       { "29", BRD_ECPPCI },
+};
+
+/*
+ *     Define the module agruments.
+ */
+MODULE_AUTHOR("Greg Ungerer");
+MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver");
+
+MODULE_PARM(board0, "1-3s");
+MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]");
+MODULE_PARM(board1, "1-3s");
+MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]");
+MODULE_PARM(board2, "1-3s");
+MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]");
+MODULE_PARM(board3, "1-3s");
+MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]");
+
+#endif
+
 /*
  *     Set up a default memory address table for EISA board probing.
  *     The default addresses are all bellow 1Mbyte, which has to be the
@@ -317,18 +415,34 @@ static unsigned long      stli_eisamemprobeaddrs[] = {
 static int     stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);
 int            stli_eisaprobe = STLI_EISAPROBE;
 
+/*
+ *     Define the Stallion PCI vendor and device IDs.
+ */
+#ifdef CONFIG_PCI
+#ifndef        PCI_VENDOR_ID_STALLION
+#define        PCI_VENDOR_ID_STALLION          0x124d
+#endif
+#ifndef PCI_DEVICE_ID_ECRA
+#define        PCI_DEVICE_ID_ECRA              0x0004
+#endif
+#endif
+
 /*****************************************************************************/
 
 /*
  *     Hardware configuration info for ECP boards. These defines apply
  *     to the directly accessible io ports of the ECP. There is a set of
- *     defines for each ECP board type, ISA, EISA and MCA.
+ *     defines for each ECP board type, ISA, EISA, MCA and PCI.
  */
 #define        ECP_IOSIZE      4
+
 #define        ECP_MEMSIZE     (128 * 1024)
+#define        ECP_PCIMEMSIZE  (256 * 1024)
+
 #define        ECP_ATPAGESIZE  (4 * 1024)
-#define        ECP_EIPAGESIZE  (64 * 1024)
 #define        ECP_MCPAGESIZE  (4 * 1024)
+#define        ECP_EIPAGESIZE  (64 * 1024)
+#define        ECP_PCIPAGESIZE (64 * 1024)
 
 #define        STL_EISAID      0x8c4e
 
@@ -376,6 +490,14 @@ int                stli_eisaprobe = STLI_EISAPROBE;
 #define        ECP_MCENABLE    0x80
 #define        ECP_MCDISABLE   0x00
 
+/*
+ *     Important defines for the PCI class of ECP board.
+ *     (It has a lot in common with the other ECP boards.)
+ */
+#define        ECP_PCIIREG     0
+#define        ECP_PCICONFR    1
+#define        ECP_PCISTOP     0x01
+
 /*
  *     Hardware configuration info for ONboard and Brumby boards. These
  *     defines apply to the directly accessible io ports of these boards.
@@ -516,7 +638,11 @@ static unsigned int        stli_baudrates[] = {
 /*
  *     Define some handy local macros...
  */
-#define        MIN(a,b)                (((a) <= (b)) ? (a) : (b))
+#undef MIN
+#define        MIN(a,b)        (((a) <= (b)) ? (a) : (b))
+
+#undef TOLOWER
+#define        TOLOWER(x)      ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
 
 /*****************************************************************************/
 
@@ -527,6 +653,10 @@ static unsigned int        stli_baudrates[] = {
 #ifdef MODULE
 int            init_module(void);
 void           cleanup_module(void);
+static void    stli_argbrds(void);
+static int     stli_parsebrd(stlconf_t *confp, char **argp);
+
+static unsigned long   stli_atol(char *str);
 #endif
 
 int            stli_init(void);
@@ -583,6 +713,7 @@ 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 stlibrd_t *stli_allocbrd(void);
 
 static void    stli_ecpinit(stlibrd_t *brdp);
 static void    stli_ecpenable(stlibrd_t *brdp);
@@ -599,6 +730,9 @@ static void stli_ecpmcenable(stlibrd_t *brdp);
 static void    stli_ecpmcdisable(stlibrd_t *brdp);
 static char    *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
 static void    stli_ecpmcreset(stlibrd_t *brdp);
+static void    stli_ecppciinit(stlibrd_t *brdp);
+static char    *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
+static void    stli_ecppcireset(stlibrd_t *brdp);
 
 static void    stli_onbinit(stlibrd_t *brdp);
 static void    stli_onbenable(stlibrd_t *brdp);
@@ -625,6 +759,12 @@ static inline int  stli_initonb(stlibrd_t *brdp);
 static inline int      stli_findeisabrds(void);
 static inline int      stli_eisamemprobe(stlibrd_t *brdp);
 static inline int      stli_initports(stlibrd_t *brdp);
+static inline int      stli_getbrdnr(void);
+
+#ifdef CONFIG_PCI
+static inline int      stli_findpcibrds(void);
+static inline int      stli_initpcibrd(int brdtype, struct pci_dev *devp);
+#endif
 
 /*****************************************************************************/
 
@@ -741,8 +881,7 @@ void cleanup_module()
                kfree_s(stli_txcookbuf, STLI_TXBUFSIZE);
 
        for (i = 0; (i < stli_nrbrds); i++) {
-               brdp = stli_brds[i];
-               if (brdp == (stlibrd_t *) NULL)
+               if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL)
                        continue;
                for (j = 0; (j < STL_MAXPORTS); j++) {
                        portp = brdp->ports[j];
@@ -763,6 +902,114 @@ void cleanup_module()
        restore_flags(flags);
 }
 
+/*****************************************************************************/
+
+/*
+ *     Check for any arguments passed in on the module load command line.
+ */
+
+static void stli_argbrds()
+{
+       stlconf_t       conf;
+       stlibrd_t       *brdp;
+       int             nrargs, i;
+
+#if DEBUG
+       printk("stli_argbrds()\n");
+#endif
+
+       nrargs = sizeof(stli_brdsp) / sizeof(char **);
+
+       for (i = stli_nrbrds; (i < nrargs); i++) {
+               memset(&conf, 0, sizeof(conf));
+               if (stli_parsebrd(&conf, stli_brdsp[i]) == 0)
+                       continue;
+               if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
+                       continue;
+               stli_nrbrds = i + 1;
+               brdp->brdnr = i;
+               brdp->brdtype = conf.brdtype;
+               brdp->iobase = conf.ioaddr1;
+               brdp->memaddr = conf.memaddr;
+               stli_brdinit(brdp);
+       }
+}
+
+/*****************************************************************************/
+
+/*
+ *     Convert an ascii string number into an unsigned long.
+ */
+
+static unsigned long stli_atol(char *str)
+{
+       unsigned long   val;
+       int             base, c;
+       char            *sp;
+
+       val = 0;
+       sp = str;
+       if ((*sp == '0') && (*(sp+1) == 'x')) {
+               base = 16;
+               sp += 2;
+       } else if (*sp == '0') {
+               base = 8;
+               sp++;
+       } else {
+               base = 10;
+       }
+
+       for (; (*sp != 0); sp++) {
+               c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
+               if ((c < 0) || (c >= base)) {
+                       printk("STALLION: invalid argument %s\n", str);
+                       val = 0;
+                       break;
+               }
+               val = (val * base) + c;
+       }
+       return(val);
+}
+
+/*****************************************************************************/
+
+/*
+ *     Parse the supplied argument string, into the board conf struct.
+ */
+
+static int stli_parsebrd(stlconf_t *confp, char **argp)
+{
+       char    *sp;
+       int     nrbrdnames, i;
+
+#if DEBUG
+       printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);
+#endif
+
+       if ((argp[0] == (char *) NULL) || (*argp[0] == 0))
+               return(0);
+
+       for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
+               *sp = TOLOWER(*sp);
+
+       nrbrdnames = sizeof(stli_brdstr) / sizeof(stlibrdtype_t);
+       for (i = 0; (i < nrbrdnames); i++) {
+               if (strcmp(stli_brdstr[i].name, argp[0]) == 0)
+                       break;
+       }
+       if (i >= nrbrdnames) {
+               printk("STALLION: unknown board name, %s?\n", argp[0]);
+               return(0);
+       }
+
+       confp->brdtype = stli_brdstr[i].type;
+       if ((argp[1] != (char *) NULL) && (*argp[1] != 0))
+               confp->ioaddr1 = stli_atol(argp[1]);
+       if ((argp[2] != (char *) NULL) && (*argp[2] != 0))
+               confp->memaddr = stli_atol(argp[2]);
+       return(1);
+}
+
 #endif
 
 /*****************************************************************************/
@@ -1433,7 +1680,6 @@ static int stli_write(struct tty_struct *tty, int from_user, const unsigned char
 
                down(&stli_tmpwritesem);
                copy_from_user(stli_tmpwritebuf, chbuf, count);
-               up(&stli_tmpwritesem);
                chbuf = &stli_tmpwritebuf[0];
        }
 
@@ -1485,8 +1731,10 @@ static int stli_write(struct tty_struct *tty, int from_user, const unsigned char
                portp->portidx;
        *bits |= portp->portbit;
        set_bit(ST_TXBUSY, &portp->state);
-
        EBRDDISABLE(brdp);
+
+       if (from_user)
+               up(&stli_tmpwritesem);
        restore_flags(flags);
 
        return(count);
@@ -3362,6 +3610,60 @@ static void stli_ecpmcreset(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
+/*
+ *     The following set of functions act on ECP PCI boards.
+ */
+
+static void stli_ecppciinit(stlibrd_t *brdp)
+{
+#if DEBUG
+       printk("stli_ecppciinit(brdp=%x)\n", (int) brdp);
+#endif
+
+       outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));
+       udelay(10);
+       outb(0, (brdp->iobase + ECP_PCICONFR));
+       udelay(500);
+}
+
+/*****************************************************************************/
+
+static char *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+{      
+       void            *ptr;
+       unsigned char   val;
+
+#if DEBUG
+       printk("stli_ecppcigetmemptr(brdp=%x,offset=%x,line=%d)\n",
+               (int) brdp, (int) offset, line);
+#endif
+
+       if (offset > brdp->memsize) {
+               printk("STALLION: shared memory pointer=%x out of range at "
+                       "line=%d(%d), board=%d\n", (int) offset, line,
+                       __LINE__, brdp->brdnr);
+               ptr = 0;
+               val = 0;
+       } else {
+               ptr = brdp->membase + (offset % ECP_PCIPAGESIZE);
+               val = (offset / ECP_PCIPAGESIZE) << 1;
+       }
+       outb(val, (brdp->iobase + ECP_PCICONFR));
+       return(ptr);
+}
+
+/*****************************************************************************/
+
+static void stli_ecppcireset(stlibrd_t *brdp)
+{      
+       outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));
+       udelay(10);
+       outb(0, (brdp->iobase + ECP_PCICONFR));
+       udelay(500);
+}
+
+/*****************************************************************************/
+
 /*
  *     The following routines act on ONboards.
  */
@@ -3678,7 +3980,7 @@ static inline int stli_initecp(stlibrd_t *brdp)
 
        brdp->iosize = ECP_IOSIZE;
        if (check_region(brdp->iobase, brdp->iosize))
-               printk("STALLION: Warning, unit %d I/O address %x conflicts "
+               printk("STALLION: Warning, board %d I/O address %x conflicts "
                        "with another device\n", brdp->brdnr, brdp->iobase);
 
 /*
@@ -3729,6 +4031,20 @@ static inline int stli_initecp(stlibrd_t *brdp)
                name = "serial(EC8/64-MCA)";
                break;
 
+       case BRD_ECPPCI:
+               brdp->membase = (void *) brdp->memaddr;
+               brdp->memsize = ECP_PCIMEMSIZE;
+               brdp->pagesize = ECP_PCIPAGESIZE;
+               brdp->init = stli_ecppciinit;
+               brdp->enable = NULL;
+               brdp->reenable = NULL;
+               brdp->disable = NULL;
+               brdp->getmemptr = stli_ecppcigetmemptr;
+               brdp->intr = stli_ecpintr;
+               brdp->reset = stli_ecppcireset;
+               name = "serial(EC/RA-PCI)";
+               break;
+
        default:
                return(-EINVAL);
        }
@@ -3817,7 +4133,7 @@ static inline int stli_initonb(stlibrd_t *brdp)
 
        brdp->iosize = ONB_IOSIZE;
        if (check_region(brdp->iobase, brdp->iosize))
-               printk("STALLION: Warning, unit %d I/O address %x conflicts "
+               printk("STALLION: Warning, board %d I/O address %x conflicts "
                        "with another device\n", brdp->brdnr, brdp->iobase);
 
 /*
@@ -4082,6 +4398,7 @@ __initfunc(static int stli_brdinit(stlibrd_t *brdp))
        case BRD_ECP:
        case BRD_ECPE:
        case BRD_ECPMC:
+       case BRD_ECPPCI:
                stli_initecp(brdp);
                break;
        case BRD_ONBOARD:
@@ -4104,20 +4421,20 @@ __initfunc(static int stli_brdinit(stlibrd_t *brdp))
                        stli_brdnames[brdp->brdtype]);
                return(ENODEV);
        default:
-               printk("STALLION: unit=%d is unknown board type=%d\n",
+               printk("STALLION: board=%d is unknown board type=%d\n",
                        brdp->brdnr, brdp->brdtype);
                return(ENODEV);
        }
 
        if ((brdp->state & BST_FOUND) == 0) {
-               printk("STALLION: %s board not found, unit=%d io=%x mem=%x\n",
+               printk("STALLION: %s board not found, board=%d io=%x mem=%x\n",
                        stli_brdnames[brdp->brdtype], brdp->brdnr,
                        brdp->iobase, (int) brdp->memaddr);
                return(ENODEV);
        }
 
        stli_initports(brdp);
-       printk("STALLION: %s found, unit=%d io=%x mem=%x "
+       printk("STALLION: %s found, board=%d io=%x mem=%x "
                "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype],
                brdp->brdnr, brdp->iobase, (int) brdp->memaddr,
                brdp->nrpanels, brdp->nrports);
@@ -4278,30 +4595,14 @@ static inline int stli_findeisabrds()
                if (i < STL_MAXBRDS)
                        continue;
 
-/*
- *             Check that we have room for this new board in our board
- *             info table.
- */
-               if (stli_nrbrds >= STL_MAXBRDS) {
-                       printk("STALLION: no room for more probed boards, "
-                               "maximum supported %d\n", STL_MAXBRDS);
-                       break;
-               }
-
 /*
  *             We have found a Stallion board and it is not configured already.
  *             Allocate a board structure and initialize it.
  */
-               brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
-               if (brdp == (stlibrd_t *) NULL) {
-                       printk("STALLION: failed to allocate memory "
-                               "(size=%d)\n", sizeof(stlibrd_t));
+               if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
+                       return(-ENOMEM);
+               if ((brdp->brdnr = stli_getbrdnr()) < 0)
                        return(-ENOMEM);
-               }
-               memset(brdp, 0, sizeof(stlibrd_t));
-
-               brdp->magic = STLI_BOARDMAGIC;
-               brdp->brdnr = stli_nrbrds++;
                eid = inb(iobase + 0xc82);
                if (eid == ECP_EISAID)
                        brdp->brdtype = BRD_ECPE;
@@ -4321,6 +4622,123 @@ static inline int stli_findeisabrds()
 
 /*****************************************************************************/
 
+/*
+ *     Find the next available board number that is free.
+ */
+
+static inline int stli_getbrdnr()
+{
+       int     i;
+
+       for (i = 0; (i < STL_MAXBRDS); i++) {
+               if (stli_brds[i] == (stlibrd_t *) NULL) {
+                       if (i >= stli_nrbrds)
+                               stli_nrbrds = i + 1;
+                       return(i);
+               }
+       }
+       return(-1);
+}
+
+/*****************************************************************************/
+
+#ifdef CONFIG_PCI
+
+/*
+ *     We have a Stallion board. Allocate a board structure and
+ *     initialize it. Read its IO and MEMORY resources from PCI
+ *     configuration space.
+ */
+
+static inline int stli_initpcibrd(int brdtype, struct pci_dev *devp)
+{
+       stlibrd_t       *brdp;
+
+#if DEBUG
+       printk("stli_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", brdtype,
+               dev->bus->number, dev->devfn);
+#endif
+
+       if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
+               return(-ENOMEM);
+       if ((brdp->brdnr = stli_getbrdnr()) < 0) {
+               printk("STALLION: too many boards found, "
+                       "maximum supported %d\n", STL_MAXBRDS);
+               return(0);
+       }
+       brdp->brdtype = brdtype;
+
+#if DEBUG
+       printk("%s(%d): BAR[]=%x,%x,%x,%x\n", __FILE__, __LINE__,
+               devp->base_address[0], devp->base_address[1],
+               devp->base_address[2], devp->base_address[3]);
+#endif
+
+/*
+ *     We have all resources from the board, so lets setup the actual
+ *     board structure now.
+ */
+       brdp->iobase = (devp->base_address[3] & PCI_BASE_ADDRESS_IO_MASK);
+       brdp->memaddr = (devp->base_address[2] & PCI_BASE_ADDRESS_MEM_MASK);
+       stli_brdinit(brdp);
+
+       return(0);
+}
+
+/*****************************************************************************/
+
+/*
+ *     Find all Stallion PCI boards that might be installed. Initialize each
+ *     one as it is found.
+ */
+
+static inline int stli_findpcibrds()
+{
+       struct pci_dev  *dev = NULL;
+       int             rc;
+
+#if DEBUG
+       printk("stli_findpcibrds()\n");
+#endif
+
+       if (! pci_present())
+               return(0);
+
+       while ((dev = pci_find_device(PCI_VENDOR_ID_STALLION,
+           PCI_DEVICE_ID_ECRA, dev))) {
+               if ((rc = stli_initpcibrd(BRD_ECPPCI, dev)))
+                       return(rc);
+       }
+
+       return(0);
+}
+
+#endif
+
+/*****************************************************************************/
+
+/*
+ *     Allocate a new board structure. Fill out the basic info in it.
+ */
+
+static stlibrd_t *stli_allocbrd()
+{
+       stlibrd_t       *brdp;
+
+       brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
+       if (brdp == (stlibrd_t *) NULL) {
+               printk("STALLION: failed to allocate memory (size=%d)\n",
+                       sizeof(stlibrd_t));
+               return((stlibrd_t *) NULL);
+       }
+
+       memset(brdp, 0, sizeof(stlibrd_t));
+       brdp->magic = STLI_BOARDMAGIC;
+       return(brdp);
+}
+
+/*****************************************************************************/
+
 /*
  *     Scan through all the boards in the configuration and see what we
  *     can find.
@@ -4344,19 +4762,16 @@ static inline int stli_initbrds()
 
 /*
  *     Firstly scan the list of static boards configured. Allocate
- *     resources and initialize the boards as found.
+ *     resources and initialize the boards as found. If this is a
+ *     module then let the module args override static configuration.
  */
        for (i = 0; (i < stli_nrbrds); i++) {
                confp = &stli_brdconf[i];
-               brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t));
-               if (brdp == (stlibrd_t *) NULL) {
-                       printk("STALLION: failed to allocate memory "
-                               "(size=%d)\n", sizeof(stlibrd_t));
+#ifdef MODULE
+               stli_parsebrd(confp, stli_brdsp[i]);
+#endif
+               if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL)
                        return(-ENOMEM);
-               }
-               memset(brdp, 0, sizeof(stlibrd_t));
-
-               brdp->magic = STLI_BOARDMAGIC;
                brdp->brdnr = i;
                brdp->brdtype = confp->brdtype;
                brdp->iobase = confp->ioaddr1;
@@ -4365,10 +4780,17 @@ static inline int stli_initbrds()
        }
 
 /*
- *     Now go probing for EISA boards if enabled.
+ *     Static configuration table done, so now use dynamic methods to
+ *     see if any more boards should be configured.
  */
+#ifdef MODULE
+       stli_argbrds();
+#endif
        if (stli_eisaprobe)
                stli_findeisabrds();
+#ifdef CONFIG_PCI
+       stli_findpcibrds();
+#endif
 
 /*
  *     All found boards are initialized. Now for a little optimization, if
index dd27a4e26a79783c21299ac7fe684492a4f3a2f0..5093d2237a7f9e6422988e706e8ffbc0a45ad9ee 100644 (file)
@@ -3,7 +3,7 @@
 /*
  *     stallion.c  -- stallion multiport serial driver.
  *
- *     Copyright (C) 1996-1998  Stallion Technologies (support@stallion.oz.au).
+ *     Copyright (C) 1996-1999  Stallion Technologies (support@stallion.oz.au).
  *     Copyright (C) 1994-1996  Greg Ungerer (gerg@stallion.oz.au).
  *
  *     This code is loosely based on the Linux serial driver, written by
 /*****************************************************************************/
 
 #include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
+#include <linux/malloc.h>
 #include <linux/interrupt.h>
-#include <linux/termios.h>
-#include <linux/fcntl.h>
-#include <linux/tty_driver.h>
-#include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/cd1400.h>
 #include <linux/sc26198.h>
 #include <linux/comstats.h>
 #include <linux/stallion.h>
-#include <linux/string.h>
-#include <linux/malloc.h>
 #include <linux/ioport.h>
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 
-#include <asm/system.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
@@ -78,7 +68,7 @@
  *     stl_brdconf[] array is a board. Each line contains io/irq/memory
  *     ranges for that board (as well as what type of board it is).
  *     Some examples:
- *             { BRD_EASYIO, 0x2a0, 0, 0, 10, 0 }
+ *             { BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },
  *     This line would configure an EasyIO board (4 or 8, no difference),
  *     at io address 2a0 and irq 10.
  *     Another example:
@@ -105,7 +95,7 @@ typedef struct {
 } stlconf_t;
 
 static stlconf_t       stl_brdconf[] = {
-       { BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },
+       /*{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },*/
 };
 
 static int     stl_nrbrds = sizeof(stl_brdconf) / sizeof(stlconf_t);
@@ -144,7 +134,7 @@ static int  stl_nrbrds = sizeof(stl_brdconf) / sizeof(stlconf_t);
  */
 static char    *stl_drvtitle = "Stallion Multiport Serial Driver";
 static char    *stl_drvname = "stallion";
-static char    *stl_drvversion = "5.4.7";
+static char    *stl_drvversion = "5.5.1";
 static char    *stl_serialname = "ttyE";
 static char    *stl_calloutname = "cue";
 
@@ -259,6 +249,85 @@ static char        *stl_brdnames[] = {
 
 /*****************************************************************************/
 
+#ifdef MODULE
+/*
+ *     Define some string labels for arguments passed from the module
+ *     load line. These allow for easy board definitions, and easy
+ *     modification of the io, memory and irq resoucres.
+ */
+
+static char    *board0[4];
+static char    *board1[4];
+static char    *board2[4];
+static char    *board3[4];
+
+static char    **stl_brdsp[] = {
+       (char **) &board0,
+       (char **) &board1,
+       (char **) &board2,
+       (char **) &board3
+};
+
+/*
+ *     Define a set of common board names, and types. This is used to
+ *     parse any module arguments.
+ */
+
+typedef struct stlbrdtype {
+       char    *name;
+       int     type;
+} stlbrdtype_t;
+
+static stlbrdtype_t    stl_brdstr[] = {
+       { "easyio", BRD_EASYIO },
+       { "eio", BRD_EASYIO },
+       { "20", BRD_EASYIO },
+       { "ec8/32", BRD_ECH },
+       { "ec8/32-at", BRD_ECH },
+       { "ec8/32-isa", BRD_ECH },
+       { "ech", BRD_ECH },
+       { "echat", BRD_ECH },
+       { "21", BRD_ECH },
+       { "ec8/32-mc", BRD_ECHMC },
+       { "ec8/32-mca", BRD_ECHMC },
+       { "echmc", BRD_ECHMC },
+       { "echmca", BRD_ECHMC },
+       { "22", BRD_ECHMC },
+       { "ec8/32-pc", BRD_ECHPCI },
+       { "ec8/32-pci", BRD_ECHPCI },
+       { "26", BRD_ECHPCI },
+       { "ec8/64-pc", BRD_ECH64PCI },
+       { "ec8/64-pci", BRD_ECH64PCI },
+       { "ech-pci", BRD_ECH64PCI },
+       { "echpci", BRD_ECH64PCI },
+       { "echpc", BRD_ECH64PCI },
+       { "27", BRD_ECH64PCI },
+       { "easyio-pc", BRD_EASYIOPCI },
+       { "easyio-pci", BRD_EASYIOPCI },
+       { "eio-pci", BRD_EASYIOPCI },
+       { "eiopci", BRD_EASYIOPCI },
+       { "28", BRD_EASYIOPCI },
+};
+
+/*
+ *     Define the module agruments.
+ */
+MODULE_AUTHOR("Greg Ungerer");
+MODULE_DESCRIPTION("Stallion Multiport Serial Driver");
+
+MODULE_PARM(board0, "1-4s");
+MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]");
+MODULE_PARM(board1, "1-4s");
+MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,ioaddr2][,irq]]");
+MODULE_PARM(board2, "1-4s");
+MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,ioaddr2][,irq]]");
+MODULE_PARM(board3, "1-4s");
+MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,ioaddr2][,irq]]");
+
+#endif
+
+/*****************************************************************************/
+
 /*
  *     Hardware ID bits for the EasyIO and ECH boards. These defines apply
  *     to the directly accessible io ports of these boards (not the uarts -
@@ -399,9 +468,11 @@ static unsigned int        stl_baudrates[] = {
 /*
  *     Define some handy local macros...
  */
-#ifndef        MIN
-#define        MIN(a,b)                (((a) <= (b)) ? (a) : (b))
-#endif
+#undef MIN
+#define        MIN(a,b)        (((a) <= (b)) ? (a) : (b))
+
+#undef TOLOWER
+#define        TOLOWER(x)      ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
 
 /*****************************************************************************/
 
@@ -412,6 +483,10 @@ static unsigned int        stl_baudrates[] = {
 #ifdef MODULE
 int            init_module(void);
 void           cleanup_module(void);
+static void    stl_argbrds(void);
+static int     stl_parsebrd(stlconf_t *confp, char **argp);
+
+static unsigned long stl_atol(char *str);
 #endif
 
 int            stl_init(void);
@@ -459,15 +534,17 @@ static void       stl_echpciintr(stlbrd_t *brdp);
 static void    stl_echpci64intr(stlbrd_t *brdp);
 static void    stl_offintr(void *private);
 static void    *stl_memalloc(int len);
+static stlbrd_t *stl_allocbrd(void);
 static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
 
 static inline int      stl_initbrds(void);
 static inline int      stl_initeio(stlbrd_t *brdp);
 static inline int      stl_initech(stlbrd_t *brdp);
+static inline int      stl_getbrdnr(void);
 
 #ifdef CONFIG_PCI
 static inline int      stl_findpcibrds(void);
-static inline int      stl_initpcibrd(int brdtype, struct pci_dev *dev);
+static inline int      stl_initpcibrd(int brdtype, struct pci_dev *devp);
 #endif
 
 /*
@@ -747,7 +824,8 @@ void cleanup_module()
                kfree_s(stl_tmpwritebuf, STL_TXBUFSIZE);
 
        for (i = 0; (i < stl_nrbrds); i++) {
-               brdp = stl_brds[i];
+               if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
+                       continue;
                for (j = 0; (j < STL_MAXPANELS); j++) {
                        panelp = brdp->panels[j];
                        if (panelp == (stlpanel_t *) NULL)
@@ -779,6 +857,124 @@ void cleanup_module()
        restore_flags(flags);
 }
 
+/*****************************************************************************/
+
+/*
+ *     Check for any arguments passed in on the module load command line.
+ */
+
+static void stl_argbrds()
+{
+       stlconf_t       conf;
+       stlbrd_t        *brdp;
+       int             nrargs, i;
+
+#if DEBUG
+       printk("stl_argbrds()\n");
+#endif
+
+       nrargs = sizeof(stl_brdsp) / sizeof(char **);
+
+       for (i = stl_nrbrds; (i < nrargs); i++) {
+               memset(&conf, 0, sizeof(conf));
+               if (stl_parsebrd(&conf, stl_brdsp[i]) == 0)
+                       continue;
+               if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
+                       continue;
+               stl_nrbrds = i + 1;
+               brdp->brdnr = i;
+               brdp->brdtype = conf.brdtype;
+               brdp->ioaddr1 = conf.ioaddr1;
+               brdp->ioaddr2 = conf.ioaddr2;
+               brdp->irq = conf.irq;
+               brdp->irqtype = conf.irqtype;
+               stl_brdinit(brdp);
+       }
+}
+
+/*****************************************************************************/
+
+/*
+ *     Convert an ascii string number into an unsigned long.
+ */
+
+static unsigned long stl_atol(char *str)
+{
+       unsigned long   val;
+       int             base, c;
+       char            *sp;
+
+       val = 0;
+       sp = str;
+       if ((*sp == '0') && (*(sp+1) == 'x')) {
+               base = 16;
+               sp += 2;
+       } else if (*sp == '0') {
+               base = 8;
+               sp++;
+       } else {
+               base = 10;
+       }
+
+       for (; (*sp != 0); sp++) {
+               c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
+               if ((c < 0) || (c >= base)) {
+                       printk("STALLION: invalid argument %s\n", str);
+                       val = 0;
+                       break;
+               }
+               val = (val * base) + c;
+       }
+       return(val);
+}
+
+/*****************************************************************************/
+
+/*
+ *     Parse the supplied argument string, into the board conf struct.
+ */
+
+static int stl_parsebrd(stlconf_t *confp, char **argp)
+{
+       char    *sp;
+       int     nrbrdnames, i;
+
+#if DEBUG
+       printk("stl_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);
+#endif
+
+       if ((argp[0] == (char *) NULL) || (*argp[0] == 0))
+               return(0);
+
+       for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
+               *sp = TOLOWER(*sp);
+
+       nrbrdnames = sizeof(stl_brdstr) / sizeof(stlbrdtype_t);
+       for (i = 0; (i < nrbrdnames); i++) {
+               if (strcmp(stl_brdstr[i].name, argp[0]) == 0)
+                       break;
+       }
+       if (i >= nrbrdnames) {
+               printk("STALLION: unknown board name, %s?\n", argp[0]);
+               return(0);
+       }
+
+       confp->brdtype = stl_brdstr[i].type;
+
+       i = 1;
+       if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
+               confp->ioaddr1 = stl_atol(argp[i]);
+       i++;
+       if (confp->brdtype == BRD_ECH) {
+               if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
+                       confp->ioaddr2 = stl_atol(argp[i]);
+               i++;
+       }
+       if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
+               confp->irq = stl_atol(argp[i]);
+       return(1);
+}
+
 #endif
 
 /*****************************************************************************/
@@ -794,6 +990,28 @@ static void *stl_memalloc(int len)
 
 /*****************************************************************************/
 
+/*
+ *     Allocate a new board structure. Fill out the basic info in it.
+ */
+
+static stlbrd_t *stl_allocbrd()
+{
+       stlbrd_t        *brdp;
+
+       brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t));
+       if (brdp == (stlbrd_t *) NULL) {
+               printk("STALLION: failed to allocate memory (size=%d)\n",
+                       sizeof(stlbrd_t));
+               return((stlbrd_t *) NULL);
+       }
+
+       memset(brdp, 0, sizeof(stlbrd_t));
+       brdp->magic = STL_BOARDMAGIC;
+       return(brdp);
+}
+
+/*****************************************************************************/
+
 static int stl_open(struct tty_struct *tty, struct file *filp)
 {
        stlport_t       *portp;
@@ -1121,7 +1339,6 @@ static int stl_write(struct tty_struct *tty, int from_user, const unsigned char
                
                down(&stl_tmpwritesem);
                copy_from_user(stl_tmpwritebuf, chbuf, count);
-               up(&stl_tmpwritesem);
                chbuf = &stl_tmpwritebuf[0];
        }
 
@@ -1154,6 +1371,9 @@ static int stl_write(struct tty_struct *tty, int from_user, const unsigned char
        clear_bit(ASYI_TXLOW, &portp->istate);
        stl_startrxtx(portp, -1, 1);
 
+       if (from_user)
+               up(&stl_tmpwritesem);
+
        return(count);
 }
 
@@ -2185,12 +2405,12 @@ static inline int stl_initeio(stlbrd_t *brdp)
        }
 
        if (check_region(brdp->ioaddr1, brdp->iosize1)) {
-               printk("STALLION: Warning, unit %d I/O address %x conflicts "
+               printk("STALLION: Warning, board %d I/O address %x conflicts "
                        "with another device\n", brdp->brdnr, brdp->ioaddr1);
        }
        if (brdp->iosize2 > 0) {
                if (check_region(brdp->ioaddr2, brdp->iosize2)) {
-                       printk("STALLION: Warning, unit %d I/O address %x "
+                       printk("STALLION: Warning, board %d I/O address %x "
                                "conflicts with another device\n",
                                brdp->brdnr, brdp->ioaddr2);
                }
@@ -2376,7 +2596,7 @@ static int inline stl_initech(stlbrd_t *brdp)
                conflict = check_region(brdp->ioaddr2, brdp->iosize2) ?
                        brdp->ioaddr2 : 0;
        if (conflict) {
-               printk("STALLION: Warning, unit %d I/O address %x conflicts "
+               printk("STALLION: Warning, board %d I/O address %x conflicts "
                        "with another device\n", brdp->brdnr, conflict);
        }
 
@@ -2499,14 +2719,14 @@ __initfunc(static int stl_brdinit(stlbrd_t *brdp))
                stl_initech(brdp);
                break;
        default:
-               printk("STALLION: unit=%d is unknown board type=%d\n",
+               printk("STALLION: board=%d is unknown board type=%d\n",
                        brdp->brdnr, brdp->brdtype);
                return(ENODEV);
        }
 
        stl_brds[brdp->brdnr] = brdp;
        if ((brdp->state & BRD_FOUND) == 0) {
-               printk("STALLION: %s board not found, unit=%d io=%x irq=%d\n",
+               printk("STALLION: %s board not found, board=%d io=%x irq=%d\n",
                        stl_brdnames[brdp->brdtype], brdp->brdnr,
                        brdp->ioaddr1, brdp->irq);
                return(ENODEV);
@@ -2516,7 +2736,7 @@ __initfunc(static int stl_brdinit(stlbrd_t *brdp))
                if (brdp->panels[i] != (stlpanel_t *) NULL)
                        stl_initports(brdp, brdp->panels[i]);
 
-       printk("STALLION: %s found, unit=%d io=%x irq=%d "
+       printk("STALLION: %s found, board=%d io=%x irq=%d "
                "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype],
                brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels,
                brdp->nrports);
@@ -2525,6 +2745,26 @@ __initfunc(static int stl_brdinit(stlbrd_t *brdp))
 
 /*****************************************************************************/
 
+/*
+ *     Find the next available board number that is free.
+ */
+
+static inline int stl_getbrdnr()
+{
+       int     i;
+
+       for (i = 0; (i < STL_MAXBRDS); i++) {
+               if (stl_brds[i] == (stlbrd_t *) NULL) {
+                       if (i >= stl_nrbrds)
+                               stl_nrbrds = i + 1;
+                       return(i);
+               }
+       }
+       return(-1);
+}
+
+/*****************************************************************************/
+
 #ifdef CONFIG_PCI
 
 /*
@@ -2533,42 +2773,32 @@ __initfunc(static int stl_brdinit(stlbrd_t *brdp))
  *     configuration space.
  */
 
-static inline int stl_initpcibrd(int brdtype, struct pci_dev *dev)
+static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp)
 {
-       unsigned int    bar[4];
        stlbrd_t        *brdp;
-       int             i;
-       unsigned char   irq;
 
 #if DEBUG
-       printk("stl_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n",
-               brdtype, dev->bus->number, dev->devfn);
+       printk("stl_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", brdtype,
+               dev->bus->number, dev->devfn);
 #endif
 
-       brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t));
-       if (brdp == (stlbrd_t *) NULL) {
-               printk("STALLION: failed to allocate memory (size=%d)\n",
-                       sizeof(stlbrd_t));
+       if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
                return(-ENOMEM);
+       if ((brdp->brdnr = stl_getbrdnr()) < 0) {
+               printk("STALLION: too many boards found, "
+                       "maximum supported %d\n", STL_MAXBRDS);
+               return(0);
        }
-
-       memset(brdp, 0, sizeof(stlbrd_t));
-       brdp->magic = STL_BOARDMAGIC;
-       brdp->brdnr = stl_nrbrds++;
        brdp->brdtype = brdtype;
 
 /*
- *     Read in all the BAR registers from this board. Different Stallion
- *     boards use these in different ways, so we just read in the whole
- *     lot and then figure out what is what later.
+ *     Different Stallion boards use the BAR registers in different ways,
+ *     so set up io addresses based on board type.
  */
-       for (i = 0; (i < 4); i++)
-               bar[i] = dev->base_address[i];
-       irq = dev->irq;
-
 #if DEBUG
        printk("%s(%d): BAR[]=%x,%x,%x,%x IRQ=%x\n", __FILE__, __LINE__,
-               bar[0], bar[1], bar[2], bar[3], irq);
+               devp->base_address[0], devp->base_address[1],
+               devp->base_address[2], devp->base_address[3], devp->irq);
 #endif
 
 /*
@@ -2577,29 +2807,34 @@ static inline int stl_initpcibrd(int brdtype, struct pci_dev *dev)
  */
        switch (brdtype) {
        case BRD_ECHPCI:
-               brdp->ioaddr2 = (bar[0] & PCI_BASE_ADDRESS_IO_MASK);
-               brdp->ioaddr1 = (bar[1] & PCI_BASE_ADDRESS_IO_MASK);
+               brdp->ioaddr2 = (devp->base_address[0] &
+                       PCI_BASE_ADDRESS_IO_MASK);
+               brdp->ioaddr1 = (devp->base_address[1] &
+                       PCI_BASE_ADDRESS_IO_MASK);
                break;
        case BRD_ECH64PCI:
-               brdp->ioaddr2 = (bar[2] & PCI_BASE_ADDRESS_IO_MASK);
-               brdp->ioaddr1 = (bar[1] & PCI_BASE_ADDRESS_IO_MASK);
+               brdp->ioaddr2 = (devp->base_address[2] &
+                       PCI_BASE_ADDRESS_IO_MASK);
+               brdp->ioaddr1 = (devp->base_address[1] &
+                       PCI_BASE_ADDRESS_IO_MASK);
                break;
        case BRD_EASYIOPCI:
-               brdp->ioaddr1 = (bar[2] & PCI_BASE_ADDRESS_IO_MASK);
-               brdp->ioaddr2 = (bar[1] & PCI_BASE_ADDRESS_IO_MASK);
+               brdp->ioaddr1 = (devp->base_address[2] &
+                       PCI_BASE_ADDRESS_IO_MASK);
+               brdp->ioaddr2 = (devp->base_address[1] &
+                       PCI_BASE_ADDRESS_IO_MASK);
                break;
        default:
                printk("STALLION: unknown PCI board type=%d\n", brdtype);
                break;
        }
 
-       brdp->irq = irq;
+       brdp->irq = devp->irq;
        stl_brdinit(brdp);
 
        return(0);
 }
 
-
 /*****************************************************************************/
 
 /*
@@ -2621,17 +2856,8 @@ static inline int stl_findpcibrds()
                return(0);
 
        for (i = 0; (i < stl_nrpcibrds); i++)
-               while ((dev = pci_find_device(stl_pcibrds[i].vendid, stl_pcibrds[i].devid, dev))) {
-
-/*
- *                     Check that we can handle more boards...
- */
-                       if (stl_nrbrds >= STL_MAXBRDS) {
-                               printk("STALLION: too many boards found, "
-                                       "maximum supported %d\n", STL_MAXBRDS);
-                               i = stl_nrpcibrds;
-                               break;
-                       }
+               while ((dev = pci_find_device(stl_pcibrds[i].vendid,
+                   stl_pcibrds[i].devid, dev))) {
 
 /*
  *                     Found a device on the PCI bus that has our vendor and
@@ -2680,15 +2906,11 @@ static inline int stl_initbrds()
  */
        for (i = 0; (i < stl_nrbrds); i++) {
                confp = &stl_brdconf[i];
-               brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t));
-               if (brdp == (stlbrd_t *) NULL) {
-                       printk("STALLION: failed to allocate memory "
-                               "(size=%d)\n", sizeof(stlbrd_t));
+#ifdef MODULE
+               stl_parsebrd(confp, stl_brdsp[i]);
+#endif
+               if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
                        return(-ENOMEM);
-               }
-               memset(brdp, 0, sizeof(stlbrd_t));
-
-               brdp->magic = STL_BOARDMAGIC;
                brdp->brdnr = i;
                brdp->brdtype = confp->brdtype;
                brdp->ioaddr1 = confp->ioaddr1;
@@ -2698,11 +2920,14 @@ static inline int stl_initbrds()
                stl_brdinit(brdp);
        }
 
-#ifdef CONFIG_PCI
 /*
- *     If the PCI BIOS support is compiled in then let's go looking for
- *     ECH-PCI boards.
+ *     Find any dynamically supported boards. That is via module load
+ *     line options or auto-detected on the PCI bus.
  */
+#ifdef MODULE
+       stl_argbrds();
+#endif
+#ifdef CONFIG_PCI
        stl_findpcibrds();
 #endif
 
index fd7fb46885551f99575f0b3ffa668d225942bdee..0881c88218c2040cd6734403e83ebb43e828f3f7 100644 (file)
@@ -3626,7 +3626,7 @@ static inline int line_info(char *buf, struct mgsl_struct *info)
        }
        spin_unlock_irqrestore(&info->irq_spinlock,flags);
        
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
+#if 0 && LINUX_VERSION_CODE >= VERSION(2,1,0)
        ret += sprintf(buf+ret, "irq_spinlock=%08X\n",
                        info->irq_spinlock.lock );
 #endif
index e3a1c28e19fbcf1ff323f9c503ef8a6ccb98c37e..bf76123a6b9dfbbe683c062061fb731d0a9ede3f 100644 (file)
@@ -73,6 +73,7 @@ static void socal_memcpy(void *d, void *s, int size)
        }
 }
 
+#ifdef HAVE_SOCAL_UCODE
 static void socal_bzero(void *d, int size)
 {
        u32 *dp = (u32 *)d;
@@ -81,6 +82,7 @@ static void socal_bzero(void *d, int size)
                size -= sizeof(u32);
        }
 }
+#endif
 
 static inline void socal_disable(struct socal *s)
 {
index 64abb5a0126b03f34f53a0bb72701ffb6826de9a..6e79fa5fcdef9be631b65dc010844a1516d9702a 100644 (file)
@@ -1587,7 +1587,7 @@ static int fbcon_do_set_font(int unit, struct console_font_op *op, u8 *data, int
         if (CON_IS_VISIBLE(conp) && softback_buf) {
            int l = fbcon_softback_size / conp->vc_size_row;
            if (l > 5)
-               softback_end += l * conp->vc_size_row;
+               softback_end = softback_buf + l * conp->vc_size_row;
            else {
                /* Smaller scrollback makes no sense, and 0 would screw
                   the operation totally */
index bca879f733efa4abc578a7593045c655e0e42e12..f50fe1c461314109151bb008a089c16da8c231e6 100644 (file)
@@ -39,7 +39,7 @@ static inline cycles_t get_cycles (void)
 #else
        unsigned long eax, edx;
 
-       __asm__("rdtsc":"=a" (eax), "=d" (edx));
+       __asm__ __volatile__("rdtsc":"=a" (eax), "=d" (edx));
        return eax;
 #endif
 }
index 958a924da74fe95206699353d5f84c5bdd56aa5a..b4782e72f6172e916b8a9ef9ce628becb73afe55 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.102 1999/01/22 16:19:29 jj Exp $
+/* $Id: pgtable.h,v 1.103 1999/03/28 08:40:04 davem Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -333,8 +333,8 @@ static __inline__ pte_t pte_mkdirty(pte_t _pte)
 extern struct pgtable_cache_struct {
        unsigned long *pgd_cache;
        unsigned long *pte_cache;
-       unsigned long pgcache_size;
-       unsigned long pgdcache_size;
+       unsigned int pgcache_size;
+       unsigned int pgdcache_size;
 } pgt_quicklists;
 #endif
 #define pgd_quicklist          (pgt_quicklists.pgd_cache)
index 21eb76a22a298852878be9ee395c54a497099c4e..c5e99dab3d94c2ddc89e079dfc76d22c9de537b2 100644 (file)
@@ -98,8 +98,17 @@ extern __inline__ int hard_smp_processor_id(void)
 /* This needn't do anything as we do not sleep the cpu
  * inside of the idler task, so an interrupt is not needed
  * to get a clean fast response.
+ *
+ * Addendum: We do want it to do something for the signal
+ *           delivery case, we detect that by just seeing
+ *           if we are trying to send this to an idler or not.
  */
-extern __inline__ void smp_send_reschedule(int cpu) { }
+extern __inline__ void smp_send_reschedule(int cpu)
+{
+       extern void smp_receive_signal(int);
+       if(cpu_data[cpu].idle_volume == 0)
+               smp_receive_signal(cpu);
+}
 
 /* This is a nop as well because we capture all other cpus
  * anyways when making the PROM active.
index 24e001e9781ae530d593e7af1f4d0b0b14baa78e..39007c8bf55caa62a3113090bc06172c4985b8d4 100644 (file)
@@ -70,7 +70,7 @@
 #define ARPHRD_FCPP    784             /* Point to point fibrechanel   */
 #define ARPHRD_FCAL    785             /* Fibrechannel arbitrated loop */
 #define ARPHRD_FCPL    786             /* Fibrechannel public loop     */
-#define ARPHRD_FCFABRIC        786             /* Fibrechannel fabric          */
+#define ARPHRD_FCFABRIC        787             /* Fibrechannel fabric          */
        /* 787->799 reserved for fibrechannel media types */
 
 
index 1e6c27a622ef7583e38b24ef6f9cb41426581e3b..a5bbd135504fca65cca768e54f80713f931bbbe9 100644 (file)
@@ -113,6 +113,7 @@ struct sched_param {
  */
 extern rwlock_t tasklist_lock;
 extern spinlock_t scheduler_lock;
+extern spinlock_t runqueue_lock;
 
 extern void sched_init(void);
 extern void show_state(void);
index 31261fd69b18ec88ad7325f50c644a7635f8e96e..6c7f51202f8eeddaf4dd1166bee7ec44fb5ba7f3 100644 (file)
@@ -845,6 +845,9 @@ extern __inline__ void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
 
 extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
+#ifdef CONFIG_FILTER
+       struct sk_filter *filter;
+#endif
        /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
           number of warnings when compiling with -W --ANK
         */
@@ -852,7 +855,7 @@ extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
                 return -ENOMEM;
 
 #ifdef CONFIG_FILTER
-       if (sk->filter && sk_filter(skb, sk->filter))
+       if ((filter = sk->filter) != NULL && sk_filter(skb, filter))
                return -EPERM;  /* Toss packet */
 #endif /* CONFIG_FILTER */
 
index 2266a9641db406165f8b808deb48ec1055f5136f..90e2ad495ca6a22ee146134fc6e827097bb58e6d 100644 (file)
@@ -7,7 +7,7 @@
  *             handler for protocols to use and generic option handler.
  *
  *
- * Version:    $Id: sock.c,v 1.78 1999/03/25 10:03:55 davem Exp $
+ * Version:    $Id: sock.c,v 1.79 1999/03/28 10:18:25 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -150,6 +150,9 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                    char *optval, int optlen)
 {
        struct sock *sk=sock->sk;
+#ifdef CONFIG_FILTER
+       struct sk_filter *filter;
+#endif
        int val;
        int valbool;
        int err;
@@ -341,16 +344,11 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                        break;
 
                case SO_DETACH_FILTER:
-                        if(sk->filter) {
-                               struct sk_filter *filter;
-
-                               filter = sk->filter;
-
+                       filter = sk->filter;
+                        if(filter) {
                                sk->filter = NULL;
                                synchronize_bh();
-                               
-                               if (filter)
-                                       sk_filter_release(sk, filter);
+                               sk_filter_release(sk, filter);
                                return 0;
                        }
                        return -ENOENT;
@@ -500,22 +498,16 @@ struct sock *sk_alloc(int family, int priority, int zero_it)
 
 void sk_free(struct sock *sk)
 {
-       if (sk->destruct)
-               sk->destruct(sk);
-
 #ifdef CONFIG_FILTER
-       if (sk->filter) {
-               sk_filter_release(sk, sk->filter);
-               sk->filter = NULL;
-       }
+       struct sk_filter *filter;
 #endif
-
-       if (atomic_read(&sk->omem_alloc))
-               printk(KERN_DEBUG "sk_free: optmem leakage (%d bytes) detected.\n", atomic_read(&sk->omem_alloc));
+       if (sk->destruct)
+               sk->destruct(sk);
 
 #ifdef CONFIG_FILTER
-       if (sk->filter) {
-               sk_filter_release(sk, sk->filter);
+       filter = sk->filter;
+       if (filter) {
+               sk_filter_release(sk, filter);
                sk->filter = NULL;
        }
 #endif
index 94e64eec65e87190cac14936c25ff05f06ce72a7..abe93ec2776e669aca8d028d9fd69bd45465506e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  $Id: ipconfig.c,v 1.19 1999/01/15 06:54:00 davem Exp $
+ *  $Id: ipconfig.c,v 1.20 1999/03/28 10:18:28 davem Exp $
  *
  *  Automatic Configuration of IP -- use BOOTP or RARP or user-supplied
  *  information to configure own IP address and routes.
@@ -825,9 +825,9 @@ int __init ip_auto_config(void)
         */
        if (ic_myaddr == INADDR_NONE ||
 #ifdef CONFIG_ROOT_NFS
-            root_server_addr == INADDR_NONE ||
+           (root_server_addr == INADDR_NONE && ic_servaddr == INADDR_NONE) ||
 #endif
-           (ic_first_dev && ic_first_dev->next)) {
+           ic_first_dev->next) {
 #ifdef CONFIG_IP_PNP_DYNAMIC
                if (ic_dynamic() < 0) {
                        printk(KERN_ERR "IP-Config: Auto-configuration of network failed.\n");
index 3afdb55a552145e74deea0d895e663c6a743668b..cc94ced0f36f62bdb9e679516b96afdc6c1fac54 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_ipv4.c,v 1.170 1999/03/21 05:22:47 davem Exp $
+ * Version:    $Id: tcp_ipv4.c,v 1.171 1999/03/28 10:18:26 davem Exp $
  *
  *             IPv4 specific functions
  *
@@ -1305,6 +1305,9 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
 
        if(newsk != NULL) {
                struct tcp_opt *newtp;
+#ifdef CONFIG_FILTER
+               struct sk_filter *filter;
+#endif
 
                memcpy(newsk, sk, sizeof(*newsk));
                newsk->sklist_next = NULL;
@@ -1326,8 +1329,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
                skb_queue_head_init(&newsk->back_log);
                skb_queue_head_init(&newsk->error_queue);
 #ifdef CONFIG_FILTER
-               if (newsk->filter)
-                       sk_filter_charge(newsk, newsk->filter);
+               if ((filter = newsk->filter) != NULL)
+                       sk_filter_charge(newsk, filter);
 #endif
 
                /* Now setup tcp_opt */
@@ -1559,9 +1562,9 @@ static inline struct sock *tcp_v4_hnd_req(struct sock *sk,struct sk_buff *skb)
 
 int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 {
-
 #ifdef CONFIG_FILTER
-       if (sk->filter && sk_filter(skb, sk->filter))
+       struct sk_filter *filter = sk->filter;
+       if (filter && sk_filter(skb, filter))
                goto discard;
 #endif /* CONFIG_FILTER */
 
index f27c6148a3bc248c9d62fb1c011d75eba59e0ef0..d42542145316d6ed9ac06d69c3da24cc933089c2 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $Id: tcp_ipv6.c,v 1.100 1999/03/21 05:22:59 davem Exp $
+ *     $Id: tcp_ipv6.c,v 1.101 1999/03/28 10:18:30 davem Exp $
  *
  *     Based on: 
  *     linux/net/ipv4/tcp.c
@@ -1181,6 +1181,9 @@ static inline struct sock *tcp_v6_hnd_req(struct sock *sk, struct sk_buff *skb)
 
 static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 {
+#ifdef CONFIG_FILTER
+       struct sk_filter *filter;
+#endif
        int users = 0;
 
        /* Imagine: socket is IPv6. IPv4 packet arrives,
@@ -1195,7 +1198,8 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
                return tcp_v4_do_rcv(sk, skb);
 
 #ifdef CONFIG_FILTER
-       if (sk->filter && sk_filter(skb, sk->filter))
+       filter = sk->filter;
+       if (filter && sk_filter(skb, filter))
                goto discard;
 #endif /* CONFIG_FILTER */