Commit 85ed1260 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.51

parent 22accfc2
......@@ -893,6 +893,15 @@ S: 24 Avon Place
S: Arlington, Massachusetts 02174
S: USA
N: Craig Small
E: csmall@triode.apana.org.au
E: vk2xlz@gonzo.vk2xlz.ampr.org (packet radio)
S: 10 Stockalls Place
S: Minto, NSW, 2566
S: Australia
D: Gracilis PackeTwin device driver
D: RSPF daemon
N: Chris Smith
E: csmith@convex.com
D: HPFS filesystem
......
......@@ -439,7 +439,8 @@ CONFIG_NET_IPIP
encapsulating protocol. This particular tunneling driver implements
encapsulation of IP within IP, which sounds kind of pointless, but
can be useful if you want to make your (or some other) machine
appear on a different network than it physically is. Enabling this
appear on a different network than it physically is, or to use the
mobile IP facilities (which effectively are doing that). Enabling this
option will produce two modules ( = code which can be inserted in
and removed from the running kernel whenever you want), one
encapsulator and one decapsulator. This is still alpha code, which
......@@ -488,7 +489,8 @@ PC/TCP compatibility mode
CONFIG_INET_PCTCP
If you have been having difficulties telneting to your Linux machine
from a DOS system that uses (broken) PC/TCP networking software, try
enabling this option. Everyone else says N.
enabling this option. Everyone else says N. As of later 1.3.x kernels
nobody should need this option. Please report if it solves problems.
Reverse ARP
CONFIG_INET_RARP
......@@ -509,7 +511,7 @@ CONFIG_INET_SNARL
by Ethernet segments only, as this option optimizes network access
for this special case. If there are other connections, e.g. SLIP
links, between machines of your IP network, say N. If in doubt, say
Y.
N. The PATH mtu discovery facility will cover most cases anyway.
Disable Path MTU Discovery (normally enabled)
CONFIG_NO_PATH_MTU_DISCOVERY
......@@ -523,10 +525,10 @@ Disable NAGLE algorithm (normally enabled)
CONFIG_TCP_NAGLE_OFF
The NAGLE algorithm works by requiring an acknowledgment before
sending small IP frames (= packets). This keeps tiny telnet and
rlogin packets from congesting Wide Area Networks. You may wish to
disable it if you run your X-server from across the network, or if
multiple byte key sequences are delayed. Most people strongly
recommend to say N here, though, thereby leaving NAGLE enabled.
rlogin packets from congesting Wide Area Networks. Most people strongly
recommend to say N here, though, thereby leaving NAGLE enabled. Those
programs that benefit by disabling the facility should do it on a per
connection basis themselves anyway.
IP: Drop source routed frames
CONFIG_IP_NOSR
......@@ -571,15 +573,15 @@ CONFIG_IPX
the programs lynx, netscape or Mosaic). This driver would enlarge
your kernel by about 5 kB. Unless you have Novell computers on your
local network, say N.
BTW: Although it still doesn't work with this release of the kernel you
can also find ncpfs (a free Novell client) on linux01.gwdg.de.
Appletalk DDP
CONFIG_ATALK
Appletalk is the way Apple computers speak to each other on an
Ethernet (Apple calls it EtherTalk) network. If your linux box is
connected to such a network and you want to join the conversation,
say Y. You would have to give "appletalk" as the address family
argument to ifconfig ("man ifconfig") in order to do this. You will
also probably want to use the netatalk package so that your Linux
say Y. You will need to use the netatalk package so that your Linux
box can act as a print and file server for macs as well as access
appletalk printers. Check out
http://www.cs.dartmouth.edu/~flowerpt/projects/linux-netatalk/ on
......@@ -638,7 +640,7 @@ CONFIG_NETLINK
This driver allows for two-way communication between certain parts
of the kernel or modules and user processes; the user processes are
able to read from and write to character special files in the /dev
directory having major mode 18. So far, the kernel uses it to
directory having major mode 36. So far, the kernel uses it to
publish some network related information if you enable "Routing
messages", below. Say Y if you want to experiment with it; this is
ALPHA code, which means that it need not be completely stable; it
......@@ -647,10 +649,9 @@ CONFIG_NETLINK
Routing messages
CONFIG_RTNETLINK
If you enable this and create a character special file /dev/route
with major number 18 and minor number 0 using mknod ("man mknod"),
with major number 36 and minor number 0 using mknod ("man mknod"),
you can read some network related routing information from that
file. Everything you write to that file will be discarded. Say Y,
because otherwise the network link driver is pointless.
file. Everything you write to that file will be discarded.
SCSI support?
CONFIG_SCSI
......@@ -1091,15 +1092,13 @@ CONFIG_EQUALIZER
Sun LANCE Ethernet support
CONFIG_SUN_LANCE
This is support for a certain type of Ethernet cards on Sun
workstations. The driver does not yet exist, so you might as well
say N.
This is support for lance ethernet cards on Sun workstations such as
the Sparcstation IPC (any Sparc with an 'le0' under SunOS basically).
Sun Intel Ethernet support
CONFIG_SUN_INTEL
This is support for a certain type of Ethernet cards on Sun
workstations. The driver does not yet exist, so you might as well
say N.
This is support for the intel ethernet cards on some Sun workstations
(all those with an ie0 interface under SunOS).
Do you want to be offered ALPHA test drivers
CONFIG_NET_ALPHA
......@@ -1242,7 +1241,9 @@ CONFIG_EL3
Documentation/networking/net-modules.txt. If you plan to use more
than one network card under linux, read the
Multiple-Ethernet-mini-HOWTO, available from
sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini.
sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. If your card is not working
you may need to use the DOS setup disk to disable Plug & Play mode, and
to select the default media type.
Other ISA cards
CONFIG_NET_ISA
......@@ -1399,6 +1400,16 @@ CONFIG_PI
you should have said Y to "AX.25 support" above, because AX.25 is
the protocol used for digital traffic over radio links.
Gracilis PackeTwin support
CONFIG_PT
This card is similar to the PI card (mentioned above). It is used mainly
by amateur radio operators for packet radio. You should of already said Y
to "AX.25 support" as this card uses that protocol.
Other than the code and the PT user documentation, there is no other
information on this card.
NOTE: The card is capable of DMA and full duplex but neither of these have
been coded in the driver as yet.
WaveLAN support
CONFIG_WAVELAN
These are cards for wireless ethernet-like networking. Supported are
......@@ -1793,7 +1804,7 @@ CONFIG_MINIX_FS
still used for root/boot and other floppies or ram disks since it is
leaner. You don't want to use it on your harddisk because of certain
built-in restrictions. This option will enlarge your kernel by about
25 kB. Everyone should say Y so that they are able to read this
25 kB. Everyone should say Y or M so that they are able to read this
common floppy format. If you want to compile this as a module
however ( = code which can be inserted in and removed from the
running kernel whenever you want), say M here and read
......@@ -2049,7 +2060,7 @@ CONFIG_PRINTER
connecting the parallel ports of two local machines) or a ethernet
network pocket adaptor attaching to the parallel port and a parallel
printer as well, you should compile both drivers as modules because
the drivers don't like each other.
the drivers both want the same resources.
Logitech busmouse support
CONFIG_BUSMOUSE
......@@ -2103,7 +2114,9 @@ CONFIG_MS_BUSMOUSE
and read Documentation/modules.txt. If you are unsure, say N and
read the HOWTO nevertheless: it will tell you what you have. Chances
are that you have a regular serial MouseSystem or Microsoft mouse
plugging in a COM port which is supported automatically.
plugging in a COM port which is supported automatically. Also be aware
several vendors talk about 'Microsoft busmouse' and actually mean PS/2
busmouse - so count the pins on the connector.
ATIXL busmouse support
CONFIG_ATIXL_BUSMOUSE
......
SMP support for Linux with up to 32 processors using the Intel MP
SMP support for Linux with up to 16 processors using the Intel MP
specification.
WARNING:
This is experimental. Back up your disks first.
This is experimental. Back up your disks first. Experience is that
it is basically stable in its current (inefficient form).
To fix:
o Fix sys_idle to exit/enter kernel state and do hlt's.
o Fix scheduler decisions to reschedule. Per cpu reschedule ?
o Scheduler ignores stick to CPU advantage. Critical for P6! [Done - FK]
o Clean up message pass.
o Test for B stepping processors.
o Clean up processor specific/independant split.
o Document it all. [PARTLY DONE]
o Find the exception/crash bug.
o Halt other CPU's on reset/panic doesn't always work.
o Dont waste page at 4K - dont need it now.(watch the GDT code).
o Dump bootup pages once booted somehow.
......@@ -25,4 +23,3 @@ o Distribute irq's (locking present just needs the 82489 to be asked
nicely).
o 486 startup code.
o How to handle mixed FPU/non FPU processors.
o Support 4Mb page mode again [TESTING]
Watchdog Timer Interfaces For The Linux Operating System
Alan Cox <alan@lxorguk.ukuu.org.uk>
Custom Linux Driver And Program Development
The following watchdog drivers are currently implemented:
IMS WDT501-P
INS WDT501-P (no fan tachometer)
IMS WDT500-P
Software Only
All four interfaces provide /dev/watchdog, which when open must be written
to within a minute or the machine will reboot. Each write delays the reboot
time another minute. In the case of the software watchdog the ability to
reboot will depend on the state of the machines and interrupts. The hardware
boards physically pull the machine down off their own onboard timers and
will reboot from almost anything.
A second temperature monitoring interface is available on the WDT501P cards
and provides /dev/temperature. This is the machine internal temperature in
degrees farenheit. Each read returns a single byte giving the temperature.
The third interface logs kernel messages on additional alert events.
At the moment only the software watchdog is available in the standard
kernel.
Features
--------
WDT501P WDT500P Software
Reboot Timer X X X
External Reboot X X o
Temperature X o o
Fan Speed X o o
Power Under X o o
Power Over X o o
Overheat X o o
The external event interfaces on the WDT boards are not currently supported.
Example Watchdog Driver
-----------------------
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
int fd=open("/dev/watchdog",O_WRONLY);
if(fd==-1)
{
perror("watchdog");
exit(1);
}
while(1)
{
write(fd,"\0",1);
sleep(10);
}
}
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 50
SUBLEVEL = 51
ARCH = i386
......
......@@ -8,6 +8,9 @@
* This file handles the architecture-dependent parts of process handling..
*/
#define __KERNEL_SYSCALLS__
#include <stdarg.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
......@@ -21,6 +24,7 @@
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/config.h>
#include <linux/unistd.h>
#include <asm/segment.h>
#include <asm/pgtable.h>
......@@ -50,6 +54,8 @@ void enable_hlt(void)
hlt_counter--;
}
#ifndef __SMP__
static void hard_idle(void)
{
while (!need_resched) {
......@@ -68,7 +74,8 @@ static void hard_idle(void)
__asm__("hlt");
#endif
}
if (need_resched) break;
if (need_resched)
break;
schedule();
}
#ifdef CONFIG_APM
......@@ -77,61 +84,73 @@ static void hard_idle(void)
}
/*
* The idle loop on a i386..
* The idle loop on a uniprocessor i386..
*/
asmlinkage int sys_idle(void)
{
#ifndef __SMP__
unsigned long start_idle = 0;
#endif
if (current->pid != 0)
{
/* printk("Wrong process idled\n"); SMP bug check */
return -EPERM;
}
#ifdef __SMP__
/*
* SMP locking sanity checker
*/
if(smp_processor_id()!=active_kernel_processor)
panic("CPU is %d, kernel CPU is %d in sys_idle!\n",
smp_processor_id(), active_kernel_processor);
if(syscall_count!=1)
printk("sys_idle: syscall count is not 1 (%ld)\n", syscall_count);
if(kernel_counter!=1)
/* endless idle loop with no priority at all */
current->counter = -100;
for (;;)
{
printk("CPU %d, sys_idle, kernel_counter is %ld\n", smp_processor_id(), kernel_counter);
if(!kernel_counter)
panic("kernel locking botch");
}
/*
* Until we have C unlocking done
* We are locked at this point. So we can safely call
* the APM bios knowing only one CPU at a time will do
* so.
*/
current->counter = -100;
schedule();
return 0;
#endif
/* endless idle loop with no priority at all */
current->counter = -100;
for (;;) {
#ifdef __SMP__
if (cpu_data[smp_processor_id()].hlt_works_ok && !hlt_counter && !need_resched)
__asm__("hlt");
#else
if (!start_idle) start_idle = jiffies;
if (jiffies - start_idle > HARD_IDLE_TIMEOUT) {
if (!start_idle)
start_idle = jiffies;
if (jiffies - start_idle > HARD_IDLE_TIMEOUT)
{
hard_idle();
} else {
}
else
{
if (hlt_works_ok && !hlt_counter && !need_resched)
__asm__("hlt");
}
if (need_resched) start_idle = 0;
#endif
if (need_resched)
start_idle = 0;
schedule();
}
}
#else
/*
* In the SMP world we hlt outside of kernel syscall rather than within
* so as to get the right locking semantics.
*/
asmlinkage int sys_idle(void)
{
if(current->pid != 0)
return -EPERM;
current->counter= -100;
schedule();
return 0;
}
/*
* This is being executed in task 0 'user space'.
*/
int cpu_idle(void *unused)
{
while(1)
{
if(cpu_data[smp_processor_id()].hlt_works_ok && !hlt_counter && !need_resched)
__asm("hlt");
idle();
}
}
#endif
/*
* This routine reboots the machine by asking the keyboard
* controller to pulse the reset-line low. We try that for a while,
......@@ -186,6 +205,7 @@ void show_regs(struct pt_regs * regs)
/*
* Free current thread data structures etc..
*/
void exit_thread(void)
{
/* forget lazy i387 state */
......
......@@ -245,8 +245,6 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
eip = (unsigned long) sa->sa_handler;
if (sa->sa_flags & SA_ONESHOT)
sa->sa_handler = NULL;
/* force a supervisor-mode page-in of the signal handler to reduce races */
__asm__("testb $0,%%fs:%0": :"m" (*(char *) eip));
regs->cs = USER_CS; regs->ss = USER_DS;
regs->ds = USER_DS; regs->es = USER_DS;
regs->gs = USER_DS; regs->fs = USER_DS;
......
......@@ -29,6 +29,7 @@
#include <linux/smp.h>
#include <asm/pgtable.h>
#include <asm/bitops.h>
#include <asm/pgtable.h>
#include <asm/smp.h>
extern void *vremap(unsigned long offset, unsigned long size); /* Linus hasnt put this in the headers yet */
......@@ -611,7 +612,7 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
* During boot up send no messages
*/
if(!smp_activated)
if(!smp_activated || !smp_commenced)
return;
......
......@@ -573,7 +573,6 @@ void device_setup(void)
setup_dev(p);
nr += p->nr_real;
}
#ifdef CONFIG_BLK_DEV_RAM
rd_load();
#endif
......
......@@ -36,3 +36,12 @@ if [ "$CONFIG_APM" = "y" ]; then
bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
fi
bool 'Watchdog Timer Support' CONFIG_WATCHDOG
if [ "$CONFIG_WATCHDOG" = "y" ]; then
# bool ' WDT501P Watchdog timer' CONFIG_WDT_501P
# if [ "$CONFIG_WDT_501P" = "y" ]; then
# bool ' Fan Tachomeeter' CONFIG_WDT_501P_TACHO
# fi
# bool ' WDT500P Watchdog timer' CONFIG_WDT_500P
bool ' Software Watchdog' CONFIG_SOFT_WATCHDOG
fi
......@@ -92,6 +92,11 @@ else
endif
endif
ifdef CONFIG_SOFT_WATCHDOG
L_OBJS += softdog.o
M = y
endif
ifdef CONFIG_QIC02_TAPE
L_OBJS += tpqic02.o
endif
......
......@@ -385,7 +385,7 @@ int chr_dev_init(void)
#endif
#if defined (CONFIG_BUSMOUSE) || defined (CONFIG_82C710_MOUSE) || \
defined (CONFIG_PSMOUSE) || defined (CONFIG_MS_BUSMOUSE) || \
defined (CONFIG_ATIXL_BUSMOUSE)
defined (CONFIG_ATIXL_BUSMOUSE) || defined(CONFIG_SOFT_WATCHDOG)
mouse_init();
#endif
#ifdef CONFIG_SOUND
......
......@@ -119,6 +119,9 @@ int mouse_init(void)
#ifdef CONFIG_ATIXL_BUSMOUSE
atixl_busmouse_init();
#endif
#ifdef CONFIG_SOFT_WATCHDOG
watchdog_init();
#endif
#endif /* !MODULE */
if (register_chrdev(MOUSE_MAJOR,"mouse",&mouse_fops)) {
printk("unable to get major %d for mouse devices\n",
......
/*
* SoftDog 0.02: A Software Watchdog Device
*
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* Email us for quotes on Linux software and driver development.
*
* -----------------------
*
* 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.
*
* -----------------------
*
* Software only watchdog driver. Unlike its big brother the WDT501P
* driver this won't always recover a failed machine.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/mouse.h>
#define WATCHDOG_MINOR 130
#define TIMER_MARGIN (60*HZ) /* Allow 1 minute */
/*
* Our timer
*/
struct timer_list watchdog_ticktock;
static int timer_alive = 0;
/*
* If the timer expires..
*/
static void watchdog_fire(long data)
{
extern void hard_reset_now(void);
hard_reset_now();
printk("WATCHDOG: Reboot didn't ?????\n");
}
/*
* Allow only one person to hold it open
*/
static int softdog_open(struct inode *inode, struct file *file)
{
if(timer_alive)
return -EBUSY;
/*
* Activate timer
*/
watchdog_ticktock.expires=jiffies+TIMER_MARGIN;
add_timer(&watchdog_ticktock);
return 0;
}
static void softdog_release(struct inode *inode, struct file *file)
{
/*
* Shut off the timer.
*/
del_timer(&watchdog_ticktock);
timer_alive=0;
}
static int softdog_write(struct inode *inode, struct file *file, const char *data, int len)
{
/*
* Refresh the timer.
*/
del_timer(&watchdog_ticktock);
watchdog_ticktock.expires=jiffies+TIMER_MARGIN;
add_timer(&watchdog_ticktock);
return 1;
}
/*
* The mouse stuff ought to be renamed misc_register etc before 1.4...
*/
void watchdog_init(void)
{
static struct file_operations softdog_fops=
{
NULL, /* Seek */
NULL, /* Read */
softdog_write, /* Write */
NULL, /* Readdir */
NULL, /* Select */
NULL, /* Ioctl */
NULL, /* MMap */
softdog_open,
softdog_release,
NULL,
NULL /* Fasync */
};
static struct mouse softdog_mouse={
WATCHDOG_MINOR,
"softdog",
&softdog_fops
};
mouse_register(&softdog_mouse);
init_timer(&watchdog_ticktock);
watchdog_ticktock.function=watchdog_fire;
printk("Software Watchdog Timer: 0.02\n");
}
......@@ -104,6 +104,8 @@ static const char *version =
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#define BLOCKOUT_2
/* A zero-terminated list of I/O addresses to be probed.
The 3c501 can be at many locations, but here are the popular ones. */
static unsigned int netcard_portlist[] =
......@@ -128,7 +130,7 @@ static void set_multicast_list(struct device *dev);
#define EL1_IO_EXTENT 16
#ifndef EL_DEBUG
#define EL_DEBUG 2 /* use 0 for production, 1 for devel., >2 for debug */
#define EL_DEBUG 0 /* use 0 for production, 1 for devel., >2 for debug */
#endif /* Anything above 5 is wordy death! */
static int el_debug = EL_DEBUG;
......@@ -378,6 +380,9 @@ static int el_start_xmit(struct sk_buff *skb, struct device *dev)
int ioaddr = dev->base_addr;
unsigned long flags;
if(dev->interrupt) /* May be unloading, don't stamp on */
return 1; /* the packet buffer this time */
if (dev->tbusy)
{
if (jiffies - dev->trans_start < 20)
......@@ -437,9 +442,12 @@ static int el_start_xmit(struct sk_buff *skb, struct device *dev)
* mean no more interrupts can be pending on the card.
*/
outb(AX_SYS, AX_CMD);
inb(RX_STATUS);
inb(TX_STATUS);
#ifdef BLOCKOUT_1
disable_irq(dev->irq);
#endif
outb_p(AX_SYS, AX_CMD);
inb_p(RX_STATUS);
inb_p(TX_STATUS);
lp->loading=1;
......@@ -453,13 +461,19 @@ static int el_start_xmit(struct sk_buff *skb, struct device *dev)
outw(gp_start, GP_LOW); /* aim - packet will be loaded into buffer start */
outsb(DATAPORT,buf,skb->len); /* load buffer (usual thing each byte increments the pointer) */
outw(gp_start, GP_LOW); /* the board reuses the same register */
#ifndef BLOCKOUT_1
if(lp->loading==2) /* A receive upset our load, despite our best efforts */
{
if(el_debug>2)
printk("%s: burped during tx load.\n", dev->name);
goto load_it_again_sam; /* Sigh... */
}
#endif
outb(AX_XMIT, AX_CMD); /* fire ... Trigger xmit. */
lp->loading=0;
#ifdef BLOCKOUT_1
enable_irq(dev->irq);
#endif
dev->trans_start = jiffies;
}
......@@ -506,18 +520,37 @@ static void el_interrupt(int irq, struct pt_regs *regs)
if (dev->interrupt)
printk("%s: Reentering the interrupt driver!\n", dev->name);
dev->interrupt = 1;
#ifndef BLOCKOUT_1
if(lp->loading==1 && !dev->tbusy)
printk("%s: Inconsistent state loading while not in tx\n",
dev->name);
#endif
#ifdef BLOCKOUT_3
lp->loading=2; /* So we can spot loading interruptions */
#endif
if (dev->tbusy)
{
/*
* Board in transmit mode.
* Board in transmit mode. May be loading. If we are
* loading we shouldn't have got this.
*/
int txsr = inb(TX_STATUS);
#ifdef BLOCKOUT_2
if(lp->loading==1)
{
if(el_debug > 2)
{
printk("%s: Interrupt while loading [", dev->name);
printk(" txsr=%02x gp=%04x rp=%04x]\n", txsr, inw(GP_LOW),inw(RX_LOW));
}
lp->loading=2; /* Force a reload */
dev->interrupt = 0;
return;
}
#endif
if (el_debug > 6)
printk(" txsr=%02x gp=%04x rp=%04x", txsr, inw(GP_LOW),inw(RX_LOW));
......@@ -593,7 +626,7 @@ static void el_interrupt(int irq, struct pt_regs *regs)
*/
if (rxsr & RX_MISSED)
lp->stats.rx_missed_errors++;
if (rxsr & RX_RUNT)
else if (rxsr & RX_RUNT)
{ /* Handled to avoid board lock-up. */
lp->stats.rx_length_errors++;
if (el_debug > 5)
......
......@@ -51,6 +51,7 @@ if [ "$CONFIG_NET_ISA" = "y" ]; then
tristate 'NE2000/NE1000 support' CONFIG_NE2000
if [ "$CONFIG_AX25" = "y" ]; then
bool 'Ottawa PI and PI/2 support' CONFIG_PI
bool 'Gracilis PackeTwin support' CONFIG_PT
fi
bool 'SK_G16 support' CONFIG_SK_G16
fi
......
......@@ -345,6 +345,9 @@ L_OBJS += pi2.o
CONFIG_PI = CONFIG_PI
endif
ifeq ($(CONFIG_PT),y)
L_OBJS += pt.o
endif
# If anything built-in uses slhc, then build it into the kernel also.
# If not, but a module uses it, build as a module.
......
This is the README for the Gracilis Packetwin device driver, version 0.5
ALPHA for Linux 1.3.43.
These files will allow you to talk to the PackeTwin (now know as PT) and
connect through it just like a pair of TNC's. To do this you will also
require the AX.25 code in the kernel enabled.
There are four files in this archive; this readme, a patch file, a .c file
and finally a .h file. The two program files need to be put into the
drivers/net directory in the Linux source tree, for me this is the
directory /usr/src/linux/drivers/net. The patch file needs to be patched in
at the top of the Linux source tree (/usr/src/linux in my case).
You will most probably have to edit the pt.c file to suit your own setup,
this should just involve changing some of the defines at the top of the file.
Please note that if you run an external modem you must specify a speed of 0.
The program is currently setup to run a 4800 baud external modem on port A
and a Kantronics DE-9600 daughter board on port B so if you have this (or
something similar) then you're right.
To compile in the driver, put the files in the correct place and patch in
the diff. You will have to re-configure the kernel again before you
recompile it.
The driver is not real good at the moment for finding the card. You can
'help' it by changing the order of the potiential addresses in the structure
found in the pt_init() function so the address of where the card is is put
first.
After compiling, you have to get them going, they are pretty well like any
other net device and just need ifconfig to get them going.
As an example, here is my /etc/rc.net
--------------------------
#
# Configure the PackeTwin, port A.
/sbin/ifconfig pt0a 44.136.8.87 hw ax25 vk2xlz mtu 512
/sbin/ifconfig pt0a 44.136.8.87 broadcast 44.136.8.255 netmask 255.255.255.0
/sbin/route add -net 44.136.8.0 netmask 255.255.255.0 dev pt0a
/sbin/route add -net 44.0.0.0 netmask 255.0.0.0 gw 44.136.8.68 dev pt0a
/sbin/route add -net 138.25.16.0 netmask 255.255.240.0 dev pt0a
/sbin/route add -host 44.136.8.255 dev pt0a
#
# Configure the PackeTwin, port B.
/sbin/ifconfig pt0b 44.136.8.87 hw ax25 vk2xlz-1 mtu 512
/sbin/ifconfig pt0b 44.136.8.87 broadcast 44.255.255.255 netmask 255.0.0.0
/sbin/route add -host 44.136.8.216 dev pt0b
/sbin/route add -host 44.136.8.95 dev pt0b
/sbin/route add -host 44.255.255.255 dev pt0b
This version of the driver comes under the GNU GPL. If you have one on my
previous (non-GPL) versions of the driver, please update to this one.
I hope that this all works well for you. I would be pleased to hear how
many people use the driver and if it does its job.
- Craig vk2xlz
INET: csmall@acacia.itd.uts.edu.au craig.small@eol.ieaust.org.au
AMPR: vk2xlz@gonzo.vk2xlz.ampr.org
AX25: vk2xlz@vk2gdm.nsw.aus.oc
......@@ -960,7 +960,7 @@ static void set_multicast_list(struct device *dev)
struct i596_cmd *cmd;
if (i596_debug > 1)
printk ("%s: set multicast list %d\n", dev->name, num_addrs);
printk ("%s: set multicast list %d\n", dev->name, dev->mc_count);
if (dev->mc_count > 0)
{
......@@ -974,10 +974,10 @@ static void set_multicast_list(struct device *dev)
}
cmd->command = CmdMulticastList;
*((unsigned short *) (cmd + 1)) = dev->mc_count * 6;
cp=((char *)(cmd + 1))+2
cp=((char *)(cmd + 1))+2;
for(dmi=dev->mc_list;dmi!=NULL;dmi=dmi->next)
{
memcpy(cp, addr,6);
memcpy(cp, dmi,6);
cp+=6;
}
print_eth (((char *)(cmd + 1)) + 2);
......
This diff is collapsed.
/*
* pt.h: Linux device driver for the Gracilis PackeTwin
* Copyright (C) 1995 Craig Small VK2XLZ (vk2xlz@vk2xlz.ampr.org.)
*
* Please read the notice appearing at the top of the file pt.c
*/
#define DMA_BUFF_SIZE 2200
/* Network statistics, with the same names as 'struct enet_statistics'. */
#define netstats enet_statistics
#define ON 1
#define OFF 0
/* Register offset info, specific to the PT
* E.g., to read the data port on channel A, use
* inportb(pichan[dev].base + CHANA + DATA)
*/
#define CHANB 0 /* Base of channel B regs */
#define CHANA 2 /* Base of channel A regs */
/* 8530 ports on each channel */
#define CTL 0
#define DATA 1
#define DMAEN 0x8 /* Offset off DMA Enable register */
/* Timer chip offsets */
#define TMR0 0x4 /* Offset of timer 0 register */
#define TMR1 0x5 /* Offset of timer 1 register */
#define TMR2 0x6 /* Offset of timer 2 register */
#define TMRCMD 0x7 /* Offset of timer command register */
#define INT_REG 0x8
#define TMR1CLR 0x9
#define TMR2CLR 0xa
/* Interrupt register equates */
#define PT_SCC_MSK 0x1
#define PT_TMR1_MSK 0x2
#define PT_TMR2_MSK 0x4
/* Serial/interrupt register equates */
#define PT_DTRA_ON 0x1
#define PT_DTRB_ON 0x2
#define PT_EXTCLKA 0x4
#define PT_EXTCLKB 0x8
#define PT_LOOPA_ON 0x10
#define PT_LOOPB_ON 0x20
#define PT_EI 0x80
/* Timer chip equates */
#define SC0 0x00 /* Select counter 0 */
#define SC1 0x40 /* Select counter 1 */
#define SC2 0x80 /* Select counter 2 */
#define CLATCH 0x00 /* Counter latching operation */
#define MSB 0x20 /* Read/load MSB only */
#define LSB 0x10 /* Read/load LSB only */
#define LSB_MSB 0x30 /* Read/load LSB, then MSB */
#define MODE0 0x00 /* Interrupt on terminal count */
#define MODE1 0x02 /* Programmable one shot */
#define MODE2 0x04 /* Rate generator */
#define MODE3 0x06 /* Square wave rate generator */
#define MODE4 0x08 /* Software triggered strobe */
#define MODE5 0x0a /* Hardware triggered strobe */
#define BCD 0x01 /* BCD counter */
/* DMA controller registers */
#define DMA_STAT 8 /* DMA controller status register */
#define DMA_CMD 8 /* DMA controller command register */
#define DMA_MASK 10 /* DMA controller mask register */
#define DMA_MODE 11 /* DMA controller mode register */
#define DMA_RESETFF 12 /* DMA controller first/last flip flop */
/* DMA data */
#define DMA_DISABLE (0x04) /* Disable channel n */
#define DMA_ENABLE (0x00) /* Enable channel n */
/* Single transfers, incr. address, auto init, writes, ch. n */
#define DMA_RX_MODE (0x54)
/* Single transfers, incr. address, no auto init, reads, ch. n */
#define DMA_TX_MODE (0x48)
/* Write registers */
#define DMA_CFG 0x08
#define SERIAL_CFG 0x09
#define INT_CFG 0x09 /* shares with serial config */
#define DMA_CLR_FF 0x0a
#define SINGLE 3686400
#define DOUBLE 7372800
#define XTAL ((long) 6144000L)
#define SIOCGPIPARAM 0x5000 /* get PI parameters */
#define SIOCSPIPARAM 0x5001 /* set */
#define SIOCGPIBAUD 0x5002 /* get only baud rate */
#define SIOCSPIBAUD 0x5003
#define SIOCGPIDMA 0x5004 /* get only DMA */
#define SIOCSPIDMA 0x5005
#define SIOCGPIIRQ 0x5006 /* get only IRQ */
#define SIOCSPIIRQ 0x5007
struct pt_req {
int cmd;
int speed;
int clockmode;
int txdelay;
unsigned char persist;
int slotime;
int squeldelay;
int dmachan;
int irq;
};
/* SCC Interrupt vectors, if we have set 'status low' */
#define CHBTxIV 0x00
#define CHBEXTIV 0x02
#define CHBRxIV 0x04
#define CHBSRCIV 0x06
#define CHATxIV 0x08
#define CHAEXTIV 0x0a
#define CHARxIV 0x0c
#define CHASRCIV 0x0e
#ifdef __KERNEL__
/* Information that needs to be kept for each channel. */
struct pt_local {
struct netstats stats; /* %%%dp*/
long open_time; /* Useless example local info. */
unsigned long xtal;
struct mbuf *rcvbuf;/* Buffer for current rx packet */
struct mbuf *rxdmabuf1; /* DMA rx buffer */
struct mbuf *rxdmabuf2; /* DMA rx buffer */
int bufsiz; /* Size of rcvbuf */
char *rcp; /* Pointer into rcvbuf */
struct sk_buff_head sndq; /* Packets awaiting transmission */
int sndcnt; /* Number of packets on sndq */
struct sk_buff *sndbuf;/* Current buffer being transmitted */
char *txdmabuf; /* Transmit DMA buffer */
char *txptr; /* Used by B port tx */
int txcnt;
char tstate; /* Transmitter state */
#define IDLE 0 /* Transmitter off, no data pending */
#define ACTIVE 1 /* Transmitter on, sending data */
#define UNDERRUN 2 /* Transmitter on, flushing CRC */
#define FLAGOUT 3 /* CRC sent - attempt to start next frame */
#define DEFER 4 /* Receive Active - DEFER Transmit */
#define ST_TXDELAY 5 /* Sending leading flags */
#define CRCOUT 6
char rstate; /* Set when !DCD goes to 0 (TRUE) */
/* Normal state is ACTIVE if Receive enabled */
#define RXERROR 2 /* Error -- Aborting current Frame */
#define RXABORT 3 /* ABORT sequence detected */
#define TOOBIG 4 /* too large a frame to store */
int dev; /* Device number */
int base; /* Base of I/O registers */
int cardbase; /* Base address of card */
int stata; /* address of Channel A status regs */
int statb; /* address of Channel B status regs */
int speed; /* Line speed, bps */
int clockmode; /* tapr 9600 modem clocking option */
int txdelay; /* Transmit Delay 10 ms/cnt */
unsigned char persist; /* Persistence (0-255) as a % */
int slotime; /* Delay to wait on persistence hit */
int squeldelay; /* Delay after XMTR OFF for squelch tail */
struct iface *iface; /* Associated interface */
int dmachan; /* DMA channel for this port */
char saved_RR0; /* The saved version of RR) that we compare with */
int nrzi; /* Do we use NRZI (or NRZ) */
};
#endif
......@@ -4,6 +4,7 @@
mainmenu_option next_comment
comment 'Filesystems'
bool 'Quota support' CONFIG_QUOTA
tristate 'Standard (minix) fs support' CONFIG_MINIX_FS
tristate 'Extended fs support' CONFIG_EXT_FS
tristate 'Second extended fs support' CONFIG_EXT2_FS
......@@ -22,4 +23,6 @@ fi
tristate 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS
tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS
tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS
tristate 'SMB filesystem (to mount WfW shares etc..) support' CONFIG_SMB_FS
if [ "$CONFIG_INET" = "y" ]; then
tristate 'SMB filesystem (to mount WfW shares etc..) support' CONFIG_SMB_FS
fi
......@@ -13,11 +13,17 @@ O_TARGET := fs.o
O_OBJS = open.o read_write.o inode.o devices.o file_table.o buffer.o \
super.o block_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
ioctl.o readdir.o select.o fifo.o locks.o filesystems.o \
dcache.o dquot.o $(BINFMTS)
dcache.o $(BINFMTS)
MOD_LIST_NAME := FS_MODULES
ALL_SUB_DIRS = minix ext ext2 msdos proc isofs nfs xiafs umsdos hpfs sysv smbfs
ifeq ($(CONFIG_QUOTA),y)
O_OBJS += dquot.o
else
O_OBJS += noquot.o
endif
ifeq ($(CONFIG_MINIX_FS),y)
SUB_DIRS += minix
else
......
......@@ -950,7 +950,7 @@ static void get_more_buffer_heads(void)
if (unused_list)
return;
if (!(bh = (struct buffer_head*) get_free_page(GFP_BUFFER)))
if (!(bh = (struct buffer_head*) get_free_page(GFP_KERNEL)))
return;
for (nr_buffer_heads+=i=PAGE_SIZE/sizeof*bh ; i>0; i--) {
......@@ -1014,140 +1014,60 @@ static struct buffer_head * create_buffers(unsigned long page, unsigned long siz
static void read_buffers(struct buffer_head * bh[], int nrbuf)
{
int i;
int bhnum = 0;
struct buffer_head * bhr[MAX_BUF_PER_PAGE];
for (i = 0 ; i < nrbuf ; i++) {
if (bh[i] && !buffer_uptodate(bh[i]))
bhr[bhnum++] = bh[i];
}
if (bhnum)
ll_rw_block(READ, bhnum, bhr);
for (i = nrbuf ; --i >= 0 ; ) {
if (bh[i]) {
wait_on_buffer(bh[i]);
}
}
ll_rw_block(READ, nrbuf, bh);
bh += nrbuf;
do {
nrbuf--;
bh--;
wait_on_buffer(*bh);
} while (nrbuf > 0);
}
static int try_to_load_aligned(unsigned long address,
kdev_t dev, int b[], int size)
int bread_page(unsigned long address, kdev_t dev, int b[], int size)
{
struct buffer_head * bh, * tmp, * arr[MAX_BUF_PER_PAGE];
unsigned long offset;
int isize = BUFSIZE_INDEX(size);
int * p;
int block;
struct buffer_head *bh, *next, *arr[MAX_BUF_PER_PAGE];
int block, nr;
bh = create_buffers(address, size);
if (!bh)
return 0;
/* do any of the buffers already exist? punt if so.. */
p = b;
for (offset = 0 ; offset < PAGE_SIZE ; offset += size) {
block = *(p++);
if (!block)
goto not_aligned;
if (find_buffer(dev, block, size))
goto not_aligned;
return -ENOMEM;
nr = 0;
next = bh;
do {
struct buffer_head * tmp;
block = *(b++);
if (!block) {
memset(next->b_data, 0, size);
continue;
}
tmp = bh;
p = b;
block = 0;
while (1) {
arr[block++] = bh;
bh->b_count = 1;
bh->b_flushtime = 0;
clear_bit(BH_Dirty, &bh->b_state);
clear_bit(BH_Uptodate, &bh->b_state);
clear_bit(BH_Req, &bh->b_state);
bh->b_dev = dev;
bh->b_blocknr = *(p++);
bh->b_list = BUF_CLEAN;
nr_buffers++;
nr_buffers_size[isize]++;
insert_into_queues(bh);
if (bh->b_this_page)
bh = bh->b_this_page;
else
break;
tmp = get_hash_table(dev, block, size);
if (tmp) {
memcpy(next->b_data, tmp->b_data, size);
brelse(tmp);
continue;
}
buffermem += PAGE_SIZE;
bh->b_this_page = tmp;
mem_map[MAP_NR(address)].count++;
buffer_pages[MAP_NR(address)] = bh;
read_buffers(arr,block);
while (block-- > 0)
brelse(arr[block]);
arr[nr++] = next;
next->b_dev = dev;
next->b_blocknr = block;
next->b_count = 1;
next->b_flushtime = 0;
clear_bit(BH_Dirty, &next->b_state);
clear_bit(BH_Uptodate, &next->b_state);
clear_bit(BH_Req, &next->b_state);
next->b_list = BUF_CLEAN;
} while ((next = next->b_this_page) != NULL);
if (nr)
read_buffers(arr,nr);
++current->maj_flt;
return 1;
not_aligned:
while ((tmp = bh) != NULL) {
while ((next = bh) != NULL) {
bh = bh->b_this_page;
put_unused_buffer_head(tmp);
put_unused_buffer_head(next);
}
return 0;
}
/*
* Try-to-share-buffers tries to minimize memory use by trying to keep
* both code pages and the buffer area in the same page. This is done by
* trying to load them into memory the way we want them.
*
* This doesn't guarantee that the memory is shared, but should under most
* circumstances work very well indeed (ie >90% sharing of code pages on
* demand-loadable executables).
*/
static inline int try_to_share_buffers(unsigned long address,
kdev_t dev, int *b, int size)
{
struct buffer_head * bh;
int block;
block = b[0];
if (!block)
return 0;
bh = get_hash_table(dev, block, size);
if (!bh)
return try_to_load_aligned(address, dev, b, size);
brelse(bh);
return 0;
}
/*
* bread_page reads four buffers into memory at the desired address. It's
* a function of its own, as there is some speed to be got by reading them
* all at the same time, not waiting for one to be read, and then another
* etc. This also allows us to optimize memory usage by sharing code pages
* and filesystem buffers..
*/
void bread_page(unsigned long address, kdev_t dev, int b[], int size)
{
struct buffer_head * bh[MAX_BUF_PER_PAGE];
unsigned long where;
int i, j;
if (try_to_share_buffers(address, dev, b, size))
return;
++current->maj_flt;
for (i=0, j=0; j<PAGE_SIZE ; i++, j+= size) {
bh[i] = NULL;
if (b[i])
bh[i] = getblk(dev, b[i], size);
}
read_buffers(bh,i);
where = address;
for (i=0, j=0; j<PAGE_SIZE ; i++, j += size, where += size) {
if (bh[i]) {
if (buffer_uptodate(bh[i]))
memcpy((void *) where, bh[i]->b_data, size);
brelse(bh[i]);
} else
memset((void *) where, 0, size);
}
}
#if 0
/*
* bwrite_page writes a page out to the buffer cache and/or the physical device.
......@@ -1869,7 +1789,7 @@ int bdflush(void * unused) {
in a few more things so "top" and /proc/2/{exe,root,cwd}
display semi-sane things. Not real crucial though... */
sprintf(current->comm, "bdflush - kernel");
sprintf(current->comm, "kernel bdflush");
for (;;) {
#ifdef DEBUG
......
......@@ -4,6 +4,7 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/config.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/mm.h>
......@@ -120,6 +121,8 @@ struct file * get_empty_filp(void)
return NULL;
}
#ifdef CONFIG_QUOTA
void add_dquot_ref(dev_t dev, short type)
{
struct file *filp;
......@@ -149,3 +152,5 @@ void reset_dquot_ptrs(dev_t dev, short type)
}
}
}
#endif
......@@ -430,28 +430,38 @@ void iput(struct inode * inode)
return;
}
static inline unsigned long value(struct inode * inode)
{
if (inode->i_lock)
return 1000;
if (inode->i_dirt)
return 1000;
return inode->i_nrpages;
}
struct inode * get_empty_inode(void)
{
static int ino = 0;
struct inode * inode, * best;
unsigned long badness = ~0UL;
int i;
if (nr_inodes < NR_INODE && nr_free_inodes < (nr_inodes >> 2))
if (nr_inodes < NR_INODE && nr_free_inodes < (nr_inodes >> 1))
grow_inodes();
repeat:
inode = first_inode;
best = NULL;
for (i = 0; i<nr_inodes; inode = inode->i_next, i++) {
if (!inode->i_count) {
if (!best)
best = inode;
if (!inode->i_dirt && !inode->i_lock) {
unsigned long i = value(inode);
if (i < badness) {
best = inode;
if ((badness = i) == 0)
break;
}
}
}
if (!best || best->i_dirt || best->i_lock)
if (badness > 20)
if (nr_inodes < NR_INODE) {
grow_inodes();
goto repeat;
......
......@@ -37,7 +37,12 @@
current->state = TASK_INTERRUPTIBLE; \
schedule(); \
}
#define dprintk if (0) printk
#ifdef DEBUG_NFS
#define dprintk(x) printk(x)
#else
#define dprintk(x)
#endif
static inline void
rpc_insque(struct rpc_sock *rsock, struct rpc_wait *slot)
......@@ -52,9 +57,9 @@ rpc_insque(struct rpc_sock *rsock, struct rpc_wait *slot)
rsock->tail = slot;
slot->prev = tmp;
slot->next = NULL;
dprintk("RPC: inserted %08lx into queue.\n", (long)slot);
dprintk("RPC: head = %08lx, tail = %08lx.\n",
(long) rsock->head, (long) rsock->tail);
dprintk(("RPC: inserted %08lx into queue.\n", (long)slot));
dprintk(("RPC: head = %08lx, tail = %08lx.\n",
(long) rsock->head, (long) rsock->tail));
}
static inline void
......@@ -71,9 +76,9 @@ rpc_remque(struct rpc_sock *rsock, struct rpc_wait *slot)
next->prev = prev;
else
rsock->tail = prev;
dprintk("RPC: removed %08lx from queue.\n", (long)slot);
dprintk("RPC: head = %08lx, tail = %08lx.\n",
(long) rsock->head, (long) rsock->tail);
dprintk(("RPC: removed %08lx from queue.\n", (long)slot));
dprintk(("RPC: head = %08lx, tail = %08lx.\n",
(long) rsock->head, (long) rsock->tail));
}
static inline int
......@@ -83,12 +88,12 @@ rpc_sendmsg(struct rpc_sock *rsock, struct msghdr *msg, int len)
unsigned long oldfs;
int result;
dprintk("RPC: sending %d bytes (buf %p)\n", len, msg->msg_iov[0].iov_base);
dprintk(("RPC: sending %d bytes (buf %p)\n", len, msg->msg_iov[0].iov_base));
oldfs = get_fs();
set_fs(get_ds());
result = sock->ops->sendmsg(sock, msg, len, 0, 0);
set_fs(oldfs);
dprintk("RPC: result = %d\n", result);
dprintk(("RPC: result = %d\n", result));
return result;
}
......@@ -104,7 +109,7 @@ rpc_select(struct rpc_sock *rsock)
struct file *file = rsock->file;
select_table wait_table;
dprintk("RPC: selecting on socket...\n");
dprintk(("RPC: selecting on socket...\n"));
wait_table.nr = 0;
wait_table.entry = &entry;
current->state = TASK_INTERRUPTIBLE;
......@@ -120,7 +125,7 @@ rpc_select(struct rpc_sock *rsock)
} else if (wait_table.nr)
remove_wait_queue(entry.wait_address, &entry.wait);
current->state = TASK_RUNNING;
dprintk("RPC: ...Okay, there appears to be some data.\n");
dprintk(("RPC: ...Okay, there appears to be some data.\n"));
return 0;
}
......@@ -133,16 +138,16 @@ rpc_recvmsg(struct rpc_sock *rsock, struct msghdr *msg, int len,int flags)
unsigned long oldfs;
int result;
dprintk("RPC: receiving %d bytes max (buf %p)\n", len, msg->msg_iov[0].iov_base);
dprintk(("RPC: receiving %d bytes max (buf %p)\n", len, msg->msg_iov[0].iov_base));
oldfs = get_fs();
set_fs(get_ds());
result = sock->ops->recvmsg(sock, msg, len, 1, flags, &alen);
set_fs(oldfs);
dprintk("RPC: result = %d\n", result);
dprintk(("RPC: result = %d\n", result));
#if 0
if (alen != salen || memcmp(&sa, sap, alen)) {
dprintk("RPC: reply address mismatch... rejected.\n");
dprintk(("RPC: reply address mismatch... rejected.\n"));
result = -EAGAIN;
}
#endif
......@@ -173,11 +178,11 @@ rpc_call_one(struct rpc_sock *rsock, struct rpc_wait *slot,
iov.iov_base = (void *)sndbuf;
iov.iov_len = slen;
dprintk("RPC: placing one call, rsock = %08lx, slot = %08lx, "
dprintk(("RPC: placing one call, rsock = %08lx, slot = %08lx, "
"sap = %08lx, salen = %d, "
"sndbuf = %08lx, slen = %d, rcvbuf = %08lx, rlen = %d\n",
(long) rsock, (long) slot, (long) sap,
salen, (long) sndbuf, slen, (long) rcvbuf, rlen);
salen, (long) sndbuf, slen, (long) rcvbuf, rlen));
result = rpc_sendmsg(rsock, &msg, slen);
if (result < 0)
......@@ -201,7 +206,7 @@ rpc_call_one(struct rpc_sock *rsock, struct rpc_wait *slot,
/* wait for data to arrive */
result = rpc_select(rsock);
if (result < 0) {
dprintk("RPC: select error = %d\n", result);
dprintk(("RPC: select error = %d\n", result));
break;
}
......@@ -214,7 +219,7 @@ rpc_call_one(struct rpc_sock *rsock, struct rpc_wait *slot,
case EAGAIN: case ECONNREFUSED:
continue;
default:
dprintk("rpc_call: recv error = %d\n", result);
dprintk(("rpc_call: recv error = %d\n", result));
case ERESTARTSYS:
return result;
}
......@@ -234,7 +239,7 @@ rpc_call_one(struct rpc_sock *rsock, struct rpc_wait *slot,
if (!rovr || rovr->gotit) {
/* bad XID or duplicate reply, discard dgram */
dprintk("RPC: bad XID or duplicate reply.\n");
dprintk(("RPC: bad XID or duplicate reply.\n"));
iov.iov_base=(void *)&xid;
iov.iov_len=sizeof(xid);
rpc_recvmsg(rsock, &msg, sizeof(xid),0);
......@@ -282,7 +287,7 @@ rpc_call(struct rpc_sock *rsock, struct sockaddr *sap, int addrlen,
slot = NULL;
do {
dprintk("RPC call TP1\n");
dprintk(("RPC call TP1\n"));
current->timeout = jiffies + timeout;
if (slot == NULL) {
while ((slot = rsock->free) == NULL) {
......@@ -296,12 +301,12 @@ rpc_call(struct rpc_sock *rsock, struct sockaddr *sap, int addrlen,
goto timedout;
}
if (rsock->shutdown) {
printk("RPC: aborting call due to shutdown.\n");
dprintk(("RPC: aborting call due to shutdown.\n"));
current->timeout = 0;
return -EIO;
}
}
dprintk("RPC call TP2\n");
dprintk(("RPC call TP2\n"));
slot->gotit = 0;
slot->xid = *(u32 *)sndbuf;
slot->buf = rcvbuf;
......@@ -310,15 +315,15 @@ rpc_call(struct rpc_sock *rsock, struct sockaddr *sap, int addrlen,
rpc_insque(rsock, slot);
}
dprintk("RPC call TP3\n");
dprintk(("RPC call TP3\n"));
result = rpc_call_one(rsock, slot, sap, addrlen,
sndbuf, slen, rcvbuf, rlen);
if (result != -ETIMEDOUT)
break;
timedout:
dprintk("RPC call TP4\n");
dprintk("RPC: rpc_call_one returned timeout.\n");
dprintk(("RPC call TP4\n"));
dprintk(("RPC: rpc_call_one returned timeout.\n"));
if (strategy->exponential)
timeout <<= 1;
else
......@@ -329,10 +334,10 @@ rpc_call(struct rpc_sock *rsock, struct sockaddr *sap, int addrlen,
break;
} while (1);
dprintk("RPC call TP5\n");
dprintk(("RPC call TP5\n"));
current->timeout = 0;
if (slot != NULL) {
dprintk("RPC call TP6\n");
dprintk(("RPC call TP6\n"));
rpc_remque(rsock, slot);
slot->next = rsock->free;
rsock->free = slot;
......@@ -356,7 +361,7 @@ rpc_makesock(struct file *file)
struct rpc_wait *slot;
int i;
dprintk("RPC: make RPC socket...\n");
dprintk(("RPC: make RPC socket...\n"));
if ((rsock = kmalloc(sizeof(struct rpc_sock), GFP_KERNEL)) == NULL)
return NULL;
memset(rsock, 0, sizeof(*rsock)); /* Nnnngh! */
......@@ -377,7 +382,7 @@ rpc_makesock(struct file *file)
rsock->shutdown = 0;
*/
dprintk("RPC: made socket %08lx", (long) rsock);
dprintk(("RPC: made socket %08lx", (long) rsock));
return rsock;
}
......
......@@ -92,7 +92,7 @@ nfs_rpc_call(struct nfs_server *server, int *start, int *end, int size)
}
if ((timeout.init_timeout <<= 1) >= maxtimeo)
timeout.init_timeout = maxtimeo;
} else if (result < 0) {
} else if (result < 0 && result != ERESTARTSYS) {
printk("NFS: notice message: result = %d.\n", result);
}
} while (result == -ETIMEDOUT && !(server->flags & NFS_MOUNT_SOFT));
......
/*
* A Non implementation of disk quotas. Chainsawed from dquot.c by
* Alan Cox <alan@lxorguk.ukuu.org.uk>. This saves us memory without
* having zillions of #ifdefs (Or if it had been done right one
*
* QUOTA_OP(inode,func)
*
* macro.)
*/
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/tty.h>
#include <linux/malloc.h>
#include <linux/mount.h>
#include <asm/segment.h>
#ifndef min
#define min(a,b) ((a) < (b)) ? (a) : (b)
#endif
int sync_dquots(kdev_t dev, short type)
{
return(0);
}
/*
* Trash the cache for a certain type on a device.
*/
void invalidate_dquots(kdev_t dev, short type)
{
}
/*
* Initialize pointer in a inode to the right dquots.
*/
void dquot_initialize(struct inode *inode, short type)
{
}
void dquot_drop(struct inode *inode)
{
}
void dquot_init(void)
{
}
/*
* Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
*/
int quota_off(kdev_t dev, short type)
{
return(0);
}
int quota_on(kdev_t dev, short type, char *path)
{
return(-ENOPKG);
}
/*
* Ok this is the systemcall interface, this communicates with
* the userlevel programs. Currently this only supports diskquota
* calls. Maybe we need to add the process quotas etc in the future.
* But we probably better use rlimits for that.
*/
asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
{
return(-ENOPKG);
}
......@@ -469,7 +469,7 @@ static int get_stat(int pid, char * buffer)
else
state = "RSDZTW"[tsk->state];
vsize = eip = esp = 0;
if (tsk->mm) {
if (tsk->mm && tsk->mm != &init_mm) {
struct vm_area_struct *vma = tsk->mm->mmap;
while (vma) {
vsize += vma->vm_end - vma->vm_start;
......@@ -628,7 +628,7 @@ static int get_statm(int pid, char * buffer)
if (!p || (tsk = *p) == NULL)
return 0;
if (tsk->mm) {
if (tsk->mm && tsk->mm != &init_mm) {
struct vm_area_struct * vma = tsk->mm->mmap;
while (vma) {
......@@ -692,7 +692,7 @@ static int read_maps (int pid, struct file * file, char * buf, int count)
if (!p || !*p)
return -EINVAL;
if (!(*p)->mm || count == 0)
if (!(*p)->mm || (*p)->mm == &init_mm || count == 0)
return 0;
/* decode f_pos */
......
......@@ -27,11 +27,15 @@ extern __inline__ unsigned short int __constant_ntohs(unsigned short int);
extern __inline__ unsigned long int
__ntohl(unsigned long int x)
{
#if defined(CONFIG_M486) && defined(__KERNEL__)
__asm__("bswap %0" : "=r" (x) : "0" (x));
#else
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
"rorl $16,%0\n\t" /* swap words */
"xchgb %b0,%h0" /* swap higher bytes */
:"=q" (x)
: "0" (x));
#endif
return x;
}
......
......@@ -5,6 +5,7 @@
#ifndef ASSEMBLY
#include <asm/i82489.h>
#include <asm/bitops.h>
#include <linux/tasks.h>
#include <linux/ptrace.h>
......@@ -178,6 +179,8 @@ extern unsigned char *apic_reg;
extern unsigned char *kernel_stacks[NR_CPUS];
extern unsigned char boot_cpu_id;
extern unsigned long cpu_present_map;
extern volatile unsigned long smp_invalidate_needed;
extern volatile unsigned long smp_spins;
extern void smp_invalidate(void);
extern volatile unsigned long kernel_flag, kernel_counter;
extern volatile unsigned char active_kernel_processor;
......@@ -241,5 +244,6 @@ extern __inline int smp_processor_id(void)
#define PROC_CHANGE_PENALTY 20 /* Schedule penalty */
#endif
#endif
......@@ -7,7 +7,7 @@
*
* Copyright (C) 1995 by Ralf Baechle
*
* Some usefull macros for MIPS assembler code
* Some useful macros for MIPS assembler code
*
* Some of the routines below contain useless nops that will be optimized
* away by gas in -O mode. These nops are however required to fill delay
......
......@@ -574,7 +574,7 @@ extern inline void bforget(struct buffer_head *buf)
}
extern void set_blocksize(kdev_t dev, int size);
extern struct buffer_head * bread(kdev_t dev, int block, int size);
extern void bread_page(unsigned long addr,kdev_t dev,int b[],int size);
extern int bread_page(unsigned long addr,kdev_t dev,int b[],int size);
extern void bwrite_page(unsigned long addr,kdev_t dev,int b[],int size);
extern struct buffer_head * breada(kdev_t dev,int block, int size,
unsigned int pos, unsigned int filesize);
......
/*
* NET_ALIAS network device aliasing definitions.
*
*
* Version: @(#)net_alias.h 0.43 12/20/95
*
* Author: Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar>
*
*
* 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.
*
*/
#ifndef _NET_ALIAS_H
#define _NET_ALIAS_H
#include <linux/types.h>
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/inet.h>
#include <linux/in.h> /* for default IP behavior */
/*
* max. alias slot number allowed
......@@ -32,7 +45,7 @@ struct net_alias
unsigned slot; /* slot number */
void *data; /* private data */
struct device *main_dev; /* pointer to main device */
struct net_alias_type *nat; /* alias type bound */
struct net_alias_type *nat; /* alias type object bound */
struct net_alias *next; /* next alias (hashed linked list) */
};
......@@ -61,15 +74,17 @@ struct net_alias_type
int n_attach; /* number of aliases attached */
char name[16]; /* af_name */
__u32 (*get_addr32) /* get __u32 addr 'representation'*/
(struct sockaddr*);
int (*addr_chk) /* address checking func: */
(struct device *, struct sockaddr *);
(struct net_alias_type *this, struct sockaddr*);
int (*dev_addr_chk) /* address checking func: */
(struct net_alias_type *this, struct device *, struct sockaddr *);
struct device * (*dev_select) /* closest alias selector*/
(struct net_alias_type *this, struct device *, struct sockaddr *sa);
int (*alias_init_1) /* called after alias creation: */
(struct net_alias *alias, struct sockaddr *sa);
(struct net_alias_type *this,struct net_alias *alias, struct sockaddr *sa);
int (*alias_done_1) /* called before alias deletion */
(struct net_alias *alias);
(struct net_alias_type *this, struct net_alias *alias);
int (*alias_print_1)
(char *buf, int len, struct net_alias *alias);
(struct net_alias_type *this, struct net_alias *alias, char *buf, int len);
struct net_alias_type *next; /* link */
};
......@@ -81,7 +96,7 @@ struct net_alias_type
static __inline__ int
net_alias_is(struct device *dev)
{
return (dev->my_alias != 0);
return (dev->my_alias != NULL);
}
......@@ -92,14 +107,14 @@ net_alias_is(struct device *dev)
static __inline__ int
net_alias_has(struct device *dev)
{
return (dev->alias_info != 0);
return (dev->alias_info != NULL);
}
extern void net_alias_init(void);
extern struct device * net_alias_dev_get(char *dev_name, int aliasing_ok, int *err, struct sockaddr *sa, void *data);
extern int net_alias_rehash(struct net_alias *alias, struct sockaddr *sa);
extern int net_alias_dev_rehash(struct device *dev, struct sockaddr *sa);
extern int net_alias_getinfo(char *buf, char **, off_t , int , int );
extern int net_alias_types_getinfo(char *buf, char **, off_t , int , int );
......@@ -107,8 +122,11 @@ extern int net_alias_types_getinfo(char *buf, char **, off_t , int , int );
extern int register_net_alias_type(struct net_alias_type *nat, int type);
extern int unregister_net_alias_type(struct net_alias_type *nat);
extern struct device * net_alias_chk(struct device *dev, struct sockaddr *sa, int flags_1, int flags_0);
extern struct device * net_alias_chk32(struct device *dev, int family, __u32 addr32, int flags_1, int flags_0);
extern struct device * net_alias_dev_chk(struct device *main_dev, struct sockaddr *sa, int flags_on, int flags_off);
extern struct device * net_alias_dev_chk32(struct device *main_dev, int family, __u32 addr32, int flags_on, int flags_off);
extern struct device * net_alias_dev_rcv_sel(struct device *main_dev, struct sockaddr *sa_src, struct sockaddr *sa_dst);
extern struct device * net_alias_dev_rcv_sel32(struct device *main_dev, int family, __u32 src, __u32 dst);
/*
......@@ -151,26 +169,4 @@ net_alias_nextdev_set(struct device *dev, struct device *nextdev)
return nextdev;
}
/*
* addr_chk wrapper: check given generic address with (UP) aliases
*/
static __inline__ struct device *
net_alias_addr_chk(struct device *dev, struct sockaddr *sa)
{
return net_alias_chk(dev, sa, IFF_UP, 0);
}
/*
* addr_chk32 wrapper: check given u32 address with (UP) aliases
*/
static __inline__ struct device *
net_alias_addr_chk32(struct device *dev, int family, __u32 addr32)
{
return net_alias_chk32(dev, family, addr32, IFF_UP, 0);
}
#endif /* _NET_ALIAS_H */
#ifndef _IP_ALIAS_H
#define _IP_ALIAS_H
/*
* IP alias specific prototypes
* IP_ALIAS (AF_INET) aliasing definitions.
*
*
* Version: @(#)ip_alias.h 0.43 12/20/95
*
* Author: Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
*/
#include <linux/net_alias.h>
#ifndef _IP_ALIAS_H
#define _IP_ALIAS_H
extern int ip_alias_init(void);
extern int ip_alias_done(void);
......
......@@ -174,7 +174,10 @@ struct sock
*/
volatile unsigned short backoff;
volatile int err;
volatile int err, err_soft; /* Soft holds errors that don't
cause failure but are the cause
of a persistent failure not just
'timed out' */
unsigned char protocol;
volatile unsigned char state;
volatile unsigned char ack_backlog;
......
......@@ -488,9 +488,29 @@ static void parse_options(char *line)
envp_init[envs+1] = NULL;
}
extern void setup_arch(char **, unsigned long *, unsigned long *);
#ifdef __SMP__
#ifndef __SMP__
/*
* Uniprocessor idle thread
*/
int cpu_idle(void *unused)
{
for(;;)
idle();
}
#else
/*
* Multiprocessor idle thread is in arch/...
*/
extern int cpu_idle(void * unused);
/*
* Activate a secondary processor.
*/
......@@ -500,15 +520,10 @@ asmlinkage void start_secondary(void)
trap_init();
init_IRQ();
smp_callin();
for(;;)
idle();
cpu_idle(NULL);
}
int smp_idle(void * unused)
{
for (;;)
idle();
}
/*
* Called by CPU#0 to activate the rest.
......@@ -525,7 +540,7 @@ static void smp_init(void)
for(i=1;i<smp_num_cpus;i++)
{
kernel_thread(smp_idle, NULL, CLONE_PID);
kernel_thread(cpu_idle, NULL, CLONE_PID);
/*
* Assume linear processor numbering
*/
......@@ -633,8 +648,7 @@ asmlinkage void start_kernel(void)
*
* Right now task[0] just does a infinite idle loop.
*/
for(;;)
idle();
cpu_idle(NULL);
}
static int printf(const char *fmt, ...)
......
......@@ -38,6 +38,8 @@
#include <linux/ext2_fs.h>
#include <linux/random.h>
extern unsigned char aux_device_present, kbd_read_mask;
#ifdef __alpha__
# include <asm/io.h>
# include <asm/hwrpb.h>
......@@ -62,6 +64,9 @@ extern void __remqu (void);
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/firewall.h>
#include <linux/trdevice.h>
#ifdef CONFIG_AX25
#include <net/ax25.h>
#endif
......@@ -133,6 +138,11 @@ extern int (*rarp_ioctl_hook)(int,void*);
extern void (* iABI_hook)(struct pt_regs * regs);
#ifdef CONFIG_BINFMT_ELF
#include <linux/elfcore.h>
extern int dump_fpu(elf_fpregset_t *);
#endif
struct symbol_table symbol_table = {
#include <linux/symtab_begin.h>
#ifdef MODVERSIONS
......@@ -558,6 +568,22 @@ struct symbol_table symbol_table = {
X(proc_net_inode_operations),
X(proc_net),
#endif
/* all busmice */
X(add_mouse_randomness),
X(fasync_helper),
/* psaux mouse */
X(aux_device_present),
X(kbd_read_mask),
#ifdef CONFIG_TR
X(tr_setup),
X(tr_type_trans),
#endif
#ifdef CONFIG_BINFMT_ELF
X(dump_fpu),
#endif
/********************************************************
* Do not add anything below this line,
* as the stacked modules depend on this!
......
......@@ -78,7 +78,7 @@ int shrink_mmap(int priority, unsigned long limit)
limit = MAP_NR(limit);
if (clock >= limit)
clock = 0;
priority = limit >> (2*priority);
priority = limit >> priority;
page = mem_map + clock;
while (priority-- > 0) {
if (page->inode && page->count == 1) {
......
......@@ -46,7 +46,7 @@ swap_control_t swap_control = {
20, 3, 1, 3, /* Page aging */
10, 2, 2, 0, /* Buffer aging */
32, 4, /* Aging cluster */
8192, 4096, /* Pageout and bufferout weights */
8192, 8192, /* Pageout and bufferout weights */
-200, /* Buffer grace */
1, 1, /* Buffs/pages to free */
RCL_ROUND_ROBIN /* Balancing policy */
......
......@@ -156,7 +156,7 @@ o Minor bug fixes [TESTED]
o Missing patches for device change in TCP [TESTED]
o Device locking [TESTED]
o Infinite slip devices [IN - BUG]
o Infinite slip devices [TESTED]
o New AF_UNIX sockets [TESTED]
o Sendmsg/recvmsg (for some stuff only) [TESTED]
o Device unload loopholes fixed [TESTED]
......@@ -209,7 +209,7 @@ o Rewrote ICMP completely [TESTED]
o Moved most IP addresses to __u32 [TESTED]
o Cleaned up ICMP reporting [TESTED]
o Tidied remove_sock [TESTED]
o Added memory allocation type to ip_build_xmit [IN]
o Added memory allocation type to ip_build_xmit [TESTED]
o Cleaned up af_inet to use inet_error [TESTED]
o Named firewall returns [TESTED]
o Added firewall output checks to ip_build_xmit [TESTED]
......@@ -218,7 +218,7 @@ o Multicast router downs VIF's when their
o Reformatted ipv4/protocol.c, dropped frag field [TESTED]
o Fixed MSS for TCP [TESTED]
o Dropped sock_awaitconn [TESTED]
o Added ip_forward to ksyms for IPIP etc [IN]
o Added ip_forward to ksyms for IPIP etc [TESTED]
o Appletalk TIOCINQ/TIOCOUTQ bug fix [TESTED]
o Rewrote the IFF_UP/IFF_DOWN handling code [TESTED]
......@@ -239,7 +239,7 @@ o Kernel/user communication module (not used yet) [TESTED]
-------->>>>> 1.3.31 <<<<<<-------
o IFF_ALLMULTI support for 3c501,3c509,8390 and
tulip(SMC etherpower) boards [IN]
tulip(SMC etherpower) boards [TESTED]
-------->>>>> 1.3.33 <<<<<<--------
......@@ -268,38 +268,52 @@ o ip udp/raw nonblock bug fixed [TESTED]
o ICMP lockup fix [TESTED]
o Fundamental operations now only sendmsg/recvmsg [TESTED]
o bind() for SOCK_PACKET [IN]
o set_mac_addr fixed up [IN]
o BSD SIOCSIFADDR, AF_UNSPEC behaviour [IN]
o set_mac_addr fixed up [TESTED]
o BSD SIOCSIFADDR, AF_UNSPEC behaviour [TESTED]
o Updated this list [OK]
o Massive ARP/cache/routing rewrite [ANK] [IN]
o AX.25 connect return fixed in using sock_error [IN]
o AX.25 connect return fixed in using sock_error [TESTED]
o Proper netlink device major(36) [TESTED]
o First parts of the SKIP support [IN, not useful]
o TCP ICMP (SOSS should work again) [IN]
o TCP ICMP (SOSS should work again) [TESTED]
o IPFW support for TOS changing (Al Longyear) [IN]
o DECNET PPP test code [Steve] [IN]
o NFS root [Miguel/Gero] [IN]
o Path MTU discovery [ANK] [IN]
o NFS root [Miguel/Gero] [TESTED]
o Path MTU discovery [ANK] [TESTED]
-------->>>>> 1.3.44 <<<<<<--------
o NFS root/ FPU clash fixed [IN]
o ARP lock bug fixed [IN]
o SO_BSDCOMPAT option(libbsd/ibcs2 ought to set) [IN]
o Changed to new set_multicast_list() [IN]
o ARP ioctl() call fixes [Bernd] [IN]
o NFS root/ FPU clash fixed [TESTED]
o ARP lock bug fixed [TESTED]
o SO_BSDCOMPAT option(libbsd/ibcs2 ought to set) [SEMIDONE]
o Changed to new set_multicast_list() [TESTED]
o ARP ioctl() call fixes [Bernd] [TESTED]
o Fixes to the name set functions (maybe fixes
netrom) [Steve] [IN]
o Packet protocol labelling (not IPX yet) [IN]
o Faster buffer copy/clone [Linus] [IN]
netrom) [Steve] [TESTED]
o Packet protocol labelling (not IPX yet) [TESTED]
o Faster buffer copy/clone [Linus] [TESTED]
-------->>>>> 1.3.46 <<<<<<--------
o AX.25/NetROM fixes/changes [John Naylor] [IN]
o AX.25/NetROM fixes/changes [John Naylor] [TESTED]
o Further attempts to fix the IPX memory bug [IN]
o ARP fixes (Assorted) [IN]
o Driver fixes for multicast lists [IN]
-------->>>>> 1.3.48 <<<<<<--------
o IPalias [TESTED]
-------->>>>> 1.3.50 <<<<<<--------
o TCP soft error support [IN]
o Further 3c501 tweaking [TESTED]
o Still trying to make IPX work right [IN]
o Trap faulty boxes sending IGMP using 0.0.0.0 [IN]
o Only allow SMBFS selection with IP configured [IN]
o Packetwin driver [Craig] [IN]
o Net alias changes [Juan] [IN]
---------- Things I thought Linus had for a while and not merged ----------------
......@@ -310,7 +324,6 @@ o Decnet pre pre pre pre pre Alpha 0.0.
o Chase Donald for new drivers, get people to sort out what net
drivers should cease to be 'Alpha'.
o IPX PPP support
o IPalias
---------- Things pending for me to merge --------------
......@@ -323,7 +336,7 @@ o SPARC patches [Dave] [partly in]
o Forwarding queue control (+ fairness algorithms ??)
o IP forward flow control.
o IPX memory leak ?????
o IPX memory leak ????? [Done with luck]
o Clean up RAW AX.25 sockets.
o Finish IPIP bug fixes [Done hopefully]
o Multicast routing [STARTED BITS]
......@@ -332,9 +345,23 @@ o IPX for Lwared
o SKIP [Available in user mode]
o AX.25/NetROM locking changes
o insw_and_csum
o IPAlias
o AF_UNIX fd passing
-------------------------- Bugs to fix ------------------------------
o signal interrupting a unix domain connect can occasionally hang the
machine ??
o IPX has a memory accounting bug. [HOPE DONE]
o TCP socket cache gets things wrong very very occasionally under high
load. [TRYING THINGS]
o AX.25/NetROM needs more locking.
o IP mroute code Oopses still. [WAITING DIFF]
o Lance driver in a few rare systems is causing crashes in copy/checksum.
o NFS logs an error (-512) when interrupted.
o NFS flow control is needed with the new multirequest NFS support.
o Need to be able to turn off the intelligent arp refreshing as its not so
hot over AX.25 and upsets some people with very dumb ISDN bridges.
0.2
---
o Fast checksum/copy on outgoing TCP
......
The following parameters should be tunable but aren't, until we get sysctl
or similar schemes. For now you'll have to dig around. Various CONFIG_xxx
items that should be configurable using sysctl omitted.
This is far from complete
Item Description
----------------------------------------------------------------------------
MAX_SOCKETS Tunable on boot, maximum sockets we will allocate
NUM_PROTO Maximum loadable address family, will need recompile
MAX_LINKS Maximum number of netlink minor devices. (1-32)
MAX_QBYTES Size of a netlink device queue (tunable)
RIF_TABLE_SIZE Token ring RIF cache size (tunable)
AARP_HASH_SIZE Size of appletalk hash table (tunable)
AX25_DEF_T1 AX.25 parameters. These are all tunable via
AX25_DEF_T2 SIOCAX25SETPARMS
AX25_DEF_T3 T1-T3,N2 have the meanings in the specification
AX25_DEF_N2
AX25_DEF_AXDEFMODE 8 = normal 128 is PE1CHL extended
AX25_DEF_IPDEFMODE 'D' - datagram 'V' - virtual connection
AX25_DEF_BACKOFF 'E'xponential 'L'inear
AX25_DEF_NETROM Allow netrom 1=Y
AX25_DF_TEXT Allow PID=Text 1=Y
AX25_DEF_WINDOW Window for normal mode
AX25_DEF_EWINDOW Window for PE1CHL mode
AX25_DEF_DIGI 1 for inband 2 for cross band 3 for both
AX25_DEF_CONMODE Allow connected modes 1=Yes
AX25_ROUTE_MAX AX.25 route cache size - no currently tunable
Unnamed (16) Number of protocol hash slots (tunable)
DEV_NUMBUFFS Number of priority levels (not easily tunable)
Unnamed (300) Maximum packet backlog queue (tunable)
MAX_IOVEC Maximum number of iovecs in a message (tunable)
MIN_WINDOW Offered minimum window (tunable)
MAX_WINDOW Offered maximum window (tunable)
MAX_HEADER Largest physical header (tunable)
MAX_ADDR_LEN Largest physical address (tunable)
SOCK_ARRAY_SIZE IP socket array hash size (tunable)
ARP_RES_TIME Time we try and resolve (tunable)
ARP_DEAD_RES_TIME Time the entry stays dead (tunable)
ARP_MAX_TRIES Maximum tries (tunable)
ARP_TIMEOUT Timeout on an ARP (tunable)
ARP_CHECK_INTERVAL Check interval to refresh an arp (tunable)
ARP_CONFIRM_INTERVAL Confirm poll time (tunable)
ARP_TABLE_SIZE Hash table size for ARP (tunable)
IP_MAX_MEMBERSHIPS Largest number of groups per socket (BSD style)
16 Hard coded constant for amount of room allowed for
cache align and faster forwarding (tunable)
IPFRAG_HIGH_THRESH Limit on fragments, we free fragments until we reach
IPFRAG_LOW_THRESH which provides some breathing space. (tunable)
IP_FRAG_TIME Time we hold a fragment for. (tunable)
PORT_MASQ_BEGIN First port reserved for masquerade (tunable)
PORT_MASQ_END Last port used for masquerade (tunable)
MASQUERADE_EXPIRE_TCP_FIN Time we keep a masquerade for after a FIN
MASUQERADE_EXPIRE_UDP Time we keep a UDP masquerade for (tunable)
MAXVIFS Maximum mrouted vifs (1-32)
MFC_LINES Lines in the multicast router cache (tunable)
SK_RMEM_MAX Max memory a socket owns for receive (tunable)
SK_WMEM_MAX Max memory a socket owns for send (tunable)
NetROM parameters are tunable via an ioctl passing a struct
4000 Size a Unix domain socket malloc falls back to
(tunable) should be 8K - a bit for 8K machines like
the ALPHA
......@@ -1121,7 +1121,7 @@ static int dev_ifsioc(void *arg, unsigned int getset)
#ifdef CONFIG_NET_ALIAS
if (net_alias_is(dev))
net_alias_rehash(dev->my_alias,&ifr.ifr_addr);
net_alias_dev_rehash(dev ,&ifr.ifr_addr);
#endif
dev->pa_addr = (*(struct sockaddr_in *)
&ifr.ifr_addr).sin_addr.s_addr;
......@@ -1387,6 +1387,9 @@ int net_dev_init(void)
#if defined(CONFIG_PI)
pi_init();
#endif
#if defined(CONFIG_PT)
pt_init();
#endif
#if defined(CONFIG_DEC_ELCP)
dec21040_init();
#endif
......
This diff is collapsed.
......@@ -66,6 +66,7 @@
* (compatibility fix)
* Alan Cox : Added optimistic memory grabbing for AF_UNIX throughput.
* Alan Cox : Allocator for a socket is settable.
* Alan Cox : SO_ERROR includes soft errors.
*
* To Fix:
*
......@@ -259,8 +260,9 @@ int sock_getsockopt(struct sock *sk, int level, int optname,
break;
case SO_ERROR:
val = sk->err;
sk->err = 0;
val = sock_error(sk);
if(val==0)
val=xchg(&sk->err_soft,0);
break;
case SO_OOBINLINE:
......
......@@ -1471,7 +1471,7 @@ void inet_proto_init(struct net_proto *pro)
int i;
printk("Swansea University Computer Society TCP/IP for NET3.032\n");
printk("Swansea University Computer Society TCP/IP for NET3.033\n");
/*
* Tell SOCKET that we are alive...
......
......@@ -895,15 +895,22 @@ int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
*/
/*
* try to switch to alias device whose address is tip, if any
* try to switch to alias device whose addr is tip or closest to sip.
*/
#ifdef CONFIG_NET_ALIAS
if (net_alias_has(dev))
if (tip != dev->pa_addr && net_alias_has(skb->dev))
{
struct device *adev;
adev = net_alias_chk32(dev,AF_INET,tip,IFF_UP,IFF_NOARP);
if (adev != NULL) dev = adev;
/*
* net_alias_dev_rcv_sel32 returns main dev if it fails to found other.
*/
dev = net_alias_dev_rcv_sel32(dev, AF_INET, sip, tip);
if (dev->type != ntohs(arp->ar_hrd) || dev->flags & IFF_NOARP)
{
kfree_skb(skb, FREE_READ);
return 0;
}
}
#endif
......
......@@ -2,9 +2,11 @@
* Linux NET3: Internet Gateway Management Protocol [IGMP]
*
* This code implements the IGMP protocol as defined in RFC1122. There has
* been a further revision of this protocol since, but since it is not
* cleanly specified in any IETF standards we implement the old one properly
* rather than play a game of guess the BSD unofficial extensions.
* been a further revision of this protocol since which is now supported.
*
* If you have trouble with this module be careful what gcc you have used,
* the older version didnt come out right using gcc 2.5.8, the newer one
* seems to fall out with gcc 2.6.2.
*
* Authors:
* Alan Cox <Alan.Cox@linux.org>
......@@ -42,6 +44,8 @@
* and do what the IGMP version 2 specified.
* Chih-Jen Chang : Added a timer to revert to IGMP V2 router
* Tsu-Sheng Tsao if the specified time expired.
* Alan Cox : Stop IGMP from 0.0.0.0 being accepted.
* Alan Cox : Use GFP_ATOMIC in the right places.
*/
......@@ -107,7 +111,10 @@ static struct ip_router_info *igmp_get_mrouter_info(struct device *dev)
/*
* Not found. Create a new entry. The default is IGMP V2 router
*/
i=(struct ip_router_info *)kmalloc(sizeof(*i), GFP_KERNEL);
i=(struct ip_router_info *)kmalloc(sizeof(*i), GFP_ATOMIC);
if(i==NULL)
return NULL;
i->dev = dev;
i->type = IGMP_NEW_ROUTER;
i->time = IGMP_AGE_THRESHOLD;
......@@ -153,7 +160,9 @@ static struct ip_router_info *igmp_set_mrouter_info(struct device *dev,int type,
/*
* Not found. Create a new entry.
*/
i=(struct ip_router_info *)kmalloc(sizeof(*i), GFP_KERNEL);
i=(struct ip_router_info *)kmalloc(sizeof(*i), GFP_ATOMIC);
if(i==NULL)
return NULL;
i->dev = dev;
i->type = type;
i->time = time;
......@@ -242,6 +251,8 @@ static void igmp_timer_expire(unsigned long data)
struct ip_router_info *r;
igmp_stop_timer(im);
r=igmp_get_mrouter_info(im->interface);
if(r==NULL)
return;
if(r->type==IGMP_NEW_ROUTER)
igmp_send_report(im->interface, im->multiaddr, IGMP_HOST_NEW_MEMBERSHIP_REPORT);
else
......@@ -277,7 +288,8 @@ static void igmp_heard_query(struct device *dev,unsigned char max_resp_time)
{
mrouter_type=IGMP_NEW_ROUTER;
igmp_set_mrouter_info(dev,mrouter_type,0);
if(igmp_set_mrouter_info(dev,mrouter_type,0)==NULL)
return;
/*
* - Start the timers in all of our membership records
* that the query applies to for the interface on
......@@ -310,7 +322,8 @@ static void igmp_heard_query(struct device *dev,unsigned char max_resp_time)
mrouter_type=IGMP_OLD_ROUTER;
max_resp_time=IGMP_MAX_HOST_REPORT_DELAY*IGMP_TIMER_SCALE;
igmp_set_mrouter_info(dev,mrouter_type,IGMP_AGE_THRESHOLD);
if(igmp_set_mrouter_info(dev,mrouter_type,IGMP_AGE_THRESHOLD)==NULL)
return;
/*
* Start the timers in all of our membership records for
......@@ -383,6 +396,8 @@ extern __inline__ void igmp_group_added(struct ip_mc_list *im)
igmp_init_timer(im);
ip_mc_filter_add(im->interface, im->multiaddr);
r=igmp_get_mrouter_info(im->interface);
if(r==NULL)
return;
if(r->type==IGMP_NEW_ROUTER)
igmp_send_report(im->interface, im->multiaddr, IGMP_HOST_NEW_MEMBERSHIP_REPORT);
else
......@@ -416,6 +431,18 @@ int igmp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
return 0;
}
/*
* I have a report that someone does this!
*/
if(saddr==0)
{
printk("Broken multicast host using 0.0.0.0 heard on %s\n",
dev->name);
kfree_skb(skb, FREE_READ);
return 0;
}
if(ih->type==IGMP_HOST_MEMBERSHIP_QUERY && daddr==IGMP_ALL_HOSTS)
igmp_heard_query(dev,ih->code);
if(ih->type==IGMP_HOST_MEMBERSHIP_REPORT && daddr==ih->group)
......
/*
* IP_ALIAS (AF_INET) aliasing module.
*
*
* Version: @(#)ip_alias.c 0.43 12/20/95
*
* Author: Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar>
*
* Fixes:
* JJC : ip_alias_dev_select method.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
*/
#include <linux/module.h>
#include <linux/types.h>
......@@ -5,6 +23,10 @@
#include <linux/netdevice.h>
#include <linux/if.h>
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/route.h>
#include <net/route.h>
#ifdef ALIAS_USER_LAND_DEBUG
#include "net_alias.h"
......@@ -19,7 +41,7 @@
* AF_INET alias init
*/
static int
ip_alias_init_1(struct net_alias *alias, struct sockaddr *sa)
ip_alias_init_1(struct net_alias_type *this, struct net_alias *alias, struct sockaddr *sa)
{
#ifdef ALIAS_USER_LAND_DEBUG
printk("alias_init(%s) called.\n", alias->name);
......@@ -32,7 +54,7 @@ ip_alias_init_1(struct net_alias *alias, struct sockaddr *sa)
* AF_INET alias done
*/
static int
ip_alias_done_1(struct net_alias *alias)
ip_alias_done_1(struct net_alias_type *this, struct net_alias *alias)
{
#ifdef ALIAS_USER_LAND_DEBUG
printk("alias_done(%s) called.\n", alias->name);
......@@ -42,11 +64,11 @@ ip_alias_done_1(struct net_alias *alias)
}
/*
* print address info
* print alias address info
*/
int
ip_alias_print_1(char *buf, int len, struct net_alias *alias)
ip_alias_print_1(struct net_alias_type *this, struct net_alias *alias, char *buf, int len)
{
char *p;
......@@ -55,6 +77,37 @@ ip_alias_print_1(char *buf, int len, struct net_alias *alias)
(p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
}
struct device *
ip_alias_dev_select(struct net_alias_type *this, struct device *main_dev, struct sockaddr *sa)
{
__u32 addr;
struct rtable *rt;
/*
* defensive...
*/
if (main_dev == NULL) return NULL;
/*
* get u32 address.
*/
addr = (sa)? (*(struct sockaddr_in *)sa).sin_addr.s_addr : 0;
if (addr == 0) return NULL;
/*
* find 'closest' device to address given. any other suggestions? ...
* net_alias module will check if returned device is main_dev's alias
*/
rt = ip_rt_route(addr, 0);
return (rt)? rt->rt_dev : NULL;
}
/*
* net_alias AF_INET type defn.
*/
......@@ -65,7 +118,8 @@ struct net_alias_type ip_alias_type =
0, /* n_attach */
"ip", /* name */
NULL, /* get_addr32() */
NULL, /* addr_chk() */
NULL, /* dev_addr_chk() */
ip_alias_dev_select, /* dev_select() */
ip_alias_init_1, /* alias_init_1() */
ip_alias_done_1, /* alias_done_1() */
ip_alias_print_1, /* alias_print_1() */
......
......@@ -272,6 +272,17 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
#endif
}
/*
* Try to select closest <src,dst> alias device, if any.
* net_alias_dev_rcv_sel32 returns main device if it
* fails to found other.
*/
#ifdef CONFIG_NET_ALIAS
if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev))
skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr);
#endif
/*
* See if the firewall wants to dispose of the packet.
*/
......@@ -316,18 +327,7 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
* function entry.
*/
/*
* also check device aliases address : will avoid
* a full lookup over device chain
*/
#ifdef CONFIG_NET_ALIAS
if ( iph->daddr == skb->dev->pa_addr ||
( net_alias_has(skb->dev) && net_alias_addr_chk32(skb->dev,AF_INET, iph->daddr )) ||
(brd = ip_chk_addr(iph->daddr)) != 0)
#else
if ( iph->daddr == skb->dev->pa_addr || (brd = ip_chk_addr(iph->daddr)) != 0)
#endif
{
if (opt && opt->srr)
{
......
......@@ -220,11 +220,11 @@ static int raw_sendto(struct sock *sk, const unsigned char *from,
if (sk->state != TCP_ESTABLISHED)
return(-EINVAL);
sin.sin_family = AF_INET;
sin.sin_port = sk->protocol;
sin.sin_port = sk->num;
sin.sin_addr.s_addr = sk->daddr;
}
if (sin.sin_port == 0)
sin.sin_port = sk->protocol;
sin.sin_port = sk->num;
if (sin.sin_addr.s_addr == INADDR_ANY)
sin.sin_addr.s_addr = ip_my_addr();
......
This diff is collapsed.
......@@ -404,19 +404,8 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c
* that skb1 and skb2 point to it (them) so that it (they) can be
* demuxed to sock1 and/or sock2. If we are unable to make enough
* copies, we do as much as is possible.
*
* Firstly stop charging the sender for the space. We will
* charge the recipient or discard. If we are called from ipx_rcv
* this is ok as no socket owns an input buffer.
*/
if(skb->sk && !copy)
{
skb->sk->wmem_alloc -= skb->truesize; /* Adjust */
skb->sk=NULL; /* Disown */
}
if (copy)
{
skb1 = skb_clone(skb, GFP_ATOMIC);
......@@ -499,7 +488,7 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node)
*/
if ((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK))
send_to_wire = 0;
send_to_wire = 0; /* No non looped */
/*
* See if this should be demuxed to sockets on this interface
......@@ -514,12 +503,24 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node)
* To our own node, loop and free the original.
*/
if (memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0)
{
/*
* Don't charge sender
*/
if(skb->sk)
skb->sk->wmem_alloc-=skb->truesize;
/*
* Will charge receiver
*/
return ipxitf_demux_socket(intrfc, skb, 0);
}
/*
* Broadcast, loop and possibly keep to send on.
*/
if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
{
if (!send_to_wire && skb->sk)
skb->sk->wmem_alloc-=skb->truesize;
ipxitf_demux_socket(intrfc, skb, send_to_wire);
if (!send_to_wire)
return 0;
......@@ -527,7 +528,9 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node)
}
/*
* if the originating net is not equal to our net; this is routed
* If the originating net is not equal to our net; this is routed
* We are still charging the sender. Which is right - the driver
* free will handle this fairly.
*/
if (ipx->ipx_source.net != intrfc->if_netnum)
......
......@@ -1341,7 +1341,7 @@ void sock_init(void)
{
int i;
printk("Swansea University Computer Society NET3.033 for Linux 1.3.38\n");
printk("Swansea University Computer Society NET3.033 for Linux 1.3.50\n");
/*
* Initialize all address (protocol) families.
......
......@@ -801,6 +801,7 @@ static int unix_sendmsg(struct socket *sock, struct msghdr *msg, int len, int no
/*
* Sleep until data has arrive. But check for races..
*/
static void unix_data_wait(unix_socket * sk)
{
cli();
......@@ -1035,7 +1036,7 @@ static struct proto_ops unix_proto_ops = {
void unix_proto_init(struct net_proto *pro)
{
printk("NET3: Unix domain sockets 0.10 BETA for Linux NET3.031.\n");
printk("NET3: Unix domain sockets 0.10 BETA for Linux NET3.033.\n");
sock_register(unix_proto_ops.family, &unix_proto_ops);
proc_net_register(&(struct proc_dir_entry) {
PROC_NET_UNIX, 4, "unix",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment