Commit 1b5d39c0 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.0.12

parent 530861e1
......@@ -129,6 +129,15 @@ N: Ross Biro
E: bir7@leland.Stanford.Edu
D: Original author of the Linux networking code
N: Philip Blundell
E: pjb27@cam.ac.uk
E: pb@nexus.co.uk
E: phil@tazenda.demon.co.uk
D: Device driver hacking (especially EtherExpress16/3C505 net cards)
D: Some Linux/ARM stuff
S: Trinity College
S: Cambridge, UK. CB2 1TQ
N: Thomas Bogendoerfer
E: tsbogend@bigbug.franken.de
D: Lance32 driver
......@@ -545,6 +554,13 @@ S: Muehlenweg 19
S: 34266 Niestetal
S: Germany
N: Richard Henderson
E: rth@tamu.edu
D: Alpha/ELF, gcc, binutils, and glibc
S: 304 E. North Ave.
S: Bryan, TX 77801-3431
S: USA
N: Sebastian Hetze
E: she@lunetix.de
D: German Linux Documentation,
......@@ -568,6 +584,14 @@ S: 46030 Manekin Plaza, Suite 160
S: Dulles, Virginia 20166
S: USA
N: Kenji Tsutomu Hollis
E: khollis@bitgate.com
W: http://www.nurk.org/
D: Berkshire PC Watchdog Driver
S: PO Box 15
S: Grants Pass, OR 97526
S: USA
N: Nick Holloway
E: Nick.Holloway@alfie.demon.co.uk
E: Nick.Holloway@parallax.co.uk
......
......@@ -26,11 +26,11 @@ http://slug.ctv.es/~alfredo/Cambios.html.
valtozasokrol, az alabbi cimen megtalaljak Nyitrai Tamas forditasat:
http://www.datanet.hu/generations/linux/newkernel.html.
For people who prefer Japanse (thanks to Mitsuhiro Kojima): Kono
bunshou no nihongo ban ha
For people who prefer Japanese (thanks to Mitsuhiro Kojima): Kono
bunshou no nihongo ban wa
http://jf.gee.kyoto-u.ac.jp/JF/v2.0/Changes-2.0.html ni arimasu.
Last updated: July 29, 1996.
Last updated: August 6, 1996.
Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
Current Releases
......@@ -135,6 +135,18 @@ there's an unofficial libc-4.7.6 release out to which you can upgrade
to fix this problem. Libc is available from
ftp://sunsite.unc.edu/pub/Linux/GCC/.
GCC Signal 11 error
===================
Many people have been reporting messages like the following,
especially when compiling a new kernel:
`gcc: Internal compiler error: program cc1 got fatal signal 11'.
This is NOT a kernel bug. Rather, these messages are generally
caused by hardware problems. See http://www.bitwizard.nl/sig11/ for
the sig11 FAQ.
Procps utilities
================
......@@ -259,7 +271,11 @@ the following as root:
ftp://sunsite.unc.edu/pub/Linux/GCC/termcap-2.0.8.tar.gz. If you
upgrade to this release read the `README' file contained into the
package to get some important information about the `tgetent' function
changes!
changes! Note that there is now a fixed version at
ftp://sunsite.unc.edu/pub/Linux/GCC/termcap-2.0.8.fix. If some of your
apps complain that termcap entries are too long and you don't need some
of the more esoteric terms in the standard 2.0.8 termcap, just download
termcap-2.0.8.fix and move it to /etc/termcap.
Also, the console driver is now responsible for keeping track of
correspondence between character codes and glyph bitmaps. If you
......@@ -271,7 +287,7 @@ Hdparm
Hdparm has been upgraded to take advantage of the latest features of
the kernel drivers. The latest non-beta version can be found at
ftp://sunsite.unc.edu/pub/Linux/kernel/patches/diskdrives/hdparm-3.0.tar.gz.
ftp://sunsite.unc.edu/pub/Linux/kernel/patches/diskdrives/hdparm-3.1.tar.gz.
IP Accounting
=============
......@@ -285,7 +301,7 @@ direction (either incoming or outgoing).
There also exists a possibility to match on device names and/or
device addresses, so that only packets coming in/going out via that
device (network interface) match with a rule. You'll need to get
ipfwadm from ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.2.tar.gz to
ipfwadm from ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.3.0.tar.gz to
use this.
IP Firewalls
......@@ -298,7 +314,7 @@ exists a possibility to match on device names and/or device addresses,
so that only packets coming in/going out via that device (network
interface) match with a rule. This is especially useful to prevent
spoofing. You'll need to get
ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.2.tar.gz to use this.
ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.3.0.tar.gz to use this.
IP Masquerading
===============
......@@ -307,7 +323,7 @@ IP Masquerading
always need to load separate modules (ip_masq_ftp.o and/or
ip_masq_irc.o) if you are going to use FTP or IRC in combination with
masquerading. You'll need to get
ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.2.tar.gz to use this.
ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.3.0.tar.gz to use this.
ISDN support
============
......@@ -473,9 +489,9 @@ Cyclades Serial Driver
======================
The Cyclades driver has been changed so that the minor numbers start
at 0 instead of 32 (ie: ttyC0 should be major 19, minor 0 in the 2.0.x
kernels while it used to be major 19, minor 32 in the older kernels).
You can use mknod to manually fix this or use a newer version of MAKEDEV.
at 0 instead of 32 (for example, ttyC0 should be major 19, minor 0 for
2.0.x kernels; in older kernels, it would have been major 19, minor
32). Use mknod or a sufficiently new version of MAKEDEV to fix this.
NCR 53c810 SCSI Driver
======================
......@@ -492,8 +508,9 @@ Perl
While we're on the subject, changes made for the 2.0.x series cause
the connect() Perl (both 4 and 5) call to time out while connecting to
remote systems. If you need the connect call for your program, use C
instead of Perl.
remote systems. The problem is not actually in the connect() call;
rather, the optional bind() call usually used with connect() causes the
problem. Remove the bind() call and your Perl scripts should connect.
Also, Perl scripts using the readdir call now misbehave if you're
using an old version of Perl, due to changes in libc. Upgrade to a
......@@ -508,7 +525,10 @@ when present at the end of a line, try setting an appropriate value
(many have reported success with "latin1", for example) for the
environmental variable LESSCHARSET. Another, and probably better,
solution is to edit the file /usr/lib/man.config and change all
`-Tlatin1' options to `-Tascii'.
`-Tlatin1' options to `-Tascii'. An alternate solution, for those of
you who can't reformat your man files in .../cat* directories is to
edit /usr/lib/man.config, setting the PAGER to `PAGER
(LESSCHARSET=latin1;export LESSCHARSET;/usr/bin/less -is'.
E2fsprogs
=========
......
......@@ -3483,7 +3483,7 @@ CONFIG_PCWATCHDOG
it resets your computer after a certain amount of time. This driver is
like the WDT501 driver but for different hardware. The PC watchdog cards
can be ordered from http://www.berkprod.com. Some example rc.local files
are available from ftp.bitgame.com.
are available from ftp.bitgate.com.
Enhanced Real Time Clock Support
CONFIG_RTC
......
......@@ -257,7 +257,7 @@ Summary of ide driver parameters for kernel "command line":
older/odd IDE drives.
"idebus=xx" : inform IDE driver of VESA/PCI bus speed in Mhz,
where "xx" is between 25 and 66 inclusive,
where "xx" is between 20 and 66 inclusive,
used when tuning chipset PIO modes.
For PCI bus, 25 is correct for a P75 system,
30 is correct for P90,P120,P180 systems,
......
Ioctl Numbers
12 Jun 1996
6 Aug 1996
Michael Chastain
<mec@duracef.shout.net>
......@@ -50,7 +50,8 @@ Following the convention is good because:
(5) When following the convention, the driver code can use generic
code to call verify_area to validate parameters.
This table is current to Linux pre2.0.9.
This table lists ioctls visible from user land for Linux/i386. It is
current to Linux 2.0.11.
Code Seq# Include File Comments
========================================================
......@@ -83,6 +84,7 @@ Code Seq# Include File Comments
'T' all linux/soundcard.h conflict!
'T' all asm-i386/ioctls.h conflict!
'V' all linux/vt.h
'W' 00-1F linux/pcwd.h
'Y' all linux/cyclades.h
'Z' all linux/scc.h version 2.2 of z8530drv
'a' all various, see http://lrcwww.epfl.ch/linux-atm/magic.html
......
......@@ -86,7 +86,7 @@ M gpg109@rsphy1.anu.edu.au
L: linux-net@vger.rutgers.edu
S: Maintained
ETHEREXPRESS NETWORK DRIVER
ETHEREXPRESS-16 NETWORK DRIVER
P: Philip Blundell
M: pjb27@cam.ac.uk
L: linux-net@vger.rutgers.edu
......
VERSION = 2
PATCHLEVEL = 0
SUBLEVEL = 11
SUBLEVEL = 12
ARCH = i386
......
......@@ -993,6 +993,7 @@ static inline void sio_fixup(void)
{ 0, 0, 2, 1, 0}, /* idsel 11 KN25_PCI_SLOT0 */
{ 1, 1, 0, 2, 1}, /* idsel 12 KN25_PCI_SLOT1 */
{ 2, 2, 1, 0, 2}, /* idsel 13 KN25_PCI_SLOT2 */
{ 0, 0, 0, 0, 0}, /* idsel 14 AS255 TULIP */
#endif
};
/*
......@@ -1005,7 +1006,21 @@ static inline void sio_fixup(void)
* This probably ought to be configurable via MILO. For
* example, sound boards seem to like using IRQ 9.
*/
#ifdef CONFIG_ALPHA_NONAME
/*
* For UDB, the only available PCI slot must not map to IRQ 9,
* since that's the builtin MSS sound chip. That PCI slot
* will map to PIRQ1 (for INTA at least), so we give it IRQ 15
* instead.
*
* Unfortunately we have to do this for NONAME as well, since
* they are co-indicated when the platform type "Noname" is
* selected... :-(
*/
const unsigned int route_tab = 0x0b0a0f09;
#else /* CONFIG_ALPHA_NONAME */
const unsigned int route_tab = 0x0b0a090f;
#endif /* CONFIG_ALPHA_NONAME */
unsigned int level_bits;
unsigned char pin, slot;
int pirq;
......@@ -1093,8 +1108,13 @@ static inline void sio_fixup(void)
* Now, make all PCI interrupts level sensitive. Notice:
* these registers must be accessed byte-wise. inw()/outw()
* don't work.
*
* Make sure to turn off any level bits set for IRQs 9,10,11,15,
* so that the only bits getting set are for devices actually found.
* Note that we do preserve the remainder of the bits, which we hope
* will be set correctly by ARC/SRM.
*/
level_bits |= (inb(0x4d0) | (inb(0x4d1) << 8));
level_bits |= ((inb(0x4d0) | (inb(0x4d1) << 8)) & 0x71ff);
outb((level_bits >> 0) & 0xff, 0x4d0);
outb((level_bits >> 8) & 0xff, 0x4d1);
enable_ide(0x26e);
......
......@@ -32,6 +32,10 @@ extern void timer_interrupt(struct pt_regs * regs);
# error Unable to handle more than 64 irq levels.
#endif
/* Reserved interrupts. These must NEVER be requested by any driver!
*/
#define IS_RESERVED_IRQ(irq) ((irq)==2) /* IRQ 2 used by hw cascade */
/*
* Shadow-copy of masked interrupts.
* The bits are used as follows:
......@@ -185,6 +189,8 @@ int request_irq(unsigned int irq,
if (irq >= NR_IRQS)
return -EINVAL;
if (IS_RESERVED_IRQ(irq))
return -EINVAL;
if (!handler)
return -EINVAL;
p = irq_action + irq;
......@@ -241,6 +247,10 @@ void free_irq(unsigned int irq, void *dev_id)
printk("Trying to free IRQ%d\n",irq);
return;
}
if (IS_RESERVED_IRQ(irq)) {
printk("Trying to free reserved IRQ %d\n", irq);
return;
}
for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
if (action->dev_id != dev_id)
continue;
......
......@@ -10,13 +10,13 @@
#
#
# Note : at this point, these files are compiled on all systems.
# Note : at this point, these files are compiled on all systems.
# In the future, some of these should be built conditionally.
#
L_TARGET := block.a
L_OBJS := ll_rw_blk.o genhd.o
L_OBJS := ll_rw_blk.o genhd.o
M_OBJS :=
MOD_LIST_NAME := BLOCK_MODULES
LX_OBJS :=
......
/*
* linux/drivers/block/cmd640.c Version 0.97 Aug 4, 1996
* linux/drivers/block/cmd640.c Version 0.99 Aug 6, 1996
*
* Copyright (C) 1995-1996 Linus Torvalds & authors (see below)
*/
......@@ -90,6 +90,8 @@
* Version 0.96 prevent use of io_32bit when prefetch is off
* Version 0.97 fix VLB secondary interface for sjd@slip.net
* other minor tune-ups: 0.96 was very good.
* Version 0.98 ignore PCI version when disabled by BIOS
* Version 0.99 display setup/active/recovery clocks with PIO mode
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
......@@ -119,6 +121,7 @@ int cmd640_vlb = 0;
#define VID 0x00
#define DID 0x02
#define PCMD 0x04
#define PCMD_ENA 0x01
#define PSTTS 0x06
#define REVID 0x08
#define PROGIF 0x09
......@@ -288,6 +291,10 @@ static int match_pci_cmd640_device (void)
if (get_cmd640_reg(i) != ven_dev[i])
return 0;
}
if ((get_cmd640_reg(PCMD) & PCMD_ENA) == 0) {
printk("ide: cmd640 on PCI disabled by BIOS\n");
return 0;
}
return 1; /* success */
}
......@@ -457,6 +464,24 @@ static void set_prefetch_mode (unsigned int index, int mode)
restore_flags(flags);
}
/*
* Dump out current drive clocks settings
*/
static void display_clocks (unsigned int index)
{
byte active_count, recovery_count;
active_count = active_counts[index];
if (active_count == 1)
++active_count;
recovery_count = recovery_counts[index];
if (active_count > 3 && recovery_count == 1)
++recovery_count;
if (cmd640_chip_version > 1)
recovery_count += 1; /* cmd640b uses (count + 1)*/
printk(", clocks=%d/%d/%d\n", setup_counts[index], active_count, recovery_count);
}
/*
* Pack active and recovery counts into single byte representation
* used by controller
......@@ -564,7 +589,7 @@ static void cmd640_set_mode (unsigned int index, byte pio_mode, unsigned int cyc
active_time = ide_pio_timings[pio_mode].active_time;
recovery_time = cycle_time - (setup_time + active_time);
clock_time = 1000 / bus_speed;
cycle_count = (cycle_time + clock_time - 1) / clock_time;
cycle_count = (cycle_time + clock_time - 1) / clock_time;
setup_count = (setup_time + clock_time - 1) / clock_time;
......@@ -635,12 +660,13 @@ static void cmd640_tune_drive (ide_drive_t *drive, byte mode_wanted)
(void) ide_get_best_pio_mode (drive, mode_wanted, 5, &d);
cmd640_set_mode (index, d.pio_mode, d.cycle_time);
printk ("%s: selected cmd640 PIO mode%d (%dns) %s/IORDY%s\n",
printk ("%s: selected cmd640 PIO mode%d (%dns) %s/IORDY%s",
drive->name,
d.pio_mode,
d.cycle_time,
d.use_iordy ? "w" : "wo",
d.overridden ? " (overriding vendor mode)" : "");
display_clocks(index);
}
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
......@@ -784,8 +810,9 @@ int ide_probe_for_cmd640x (void)
*/
retrieve_drive_counts (index);
check_prefetch (index);
printk("cmd640: drive%d timings/prefetch(%s) preserved\n",
printk("cmd640: drive%d timings/prefetch(%s) preserved",
index, drive->no_io_32bit ? "off" : "on");
display_clocks(index);
}
#else
/*
......
......@@ -1685,15 +1685,9 @@ void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
} while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2);
}
if (handler) {
if(intr_count >= 2)
{
/* expected interrupt */
floppy_tq.routine = (void *)(void *) handler;
queue_task_irq(&floppy_tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
}
else
handler();
/* expected interrupt */
floppy_tq.routine = (void *)(void *) handler;
queue_task_irq(&floppy_tq, &tq_timer);
} else
FDCS->reset = 1;
is_alive("normal interrupt end");
......@@ -1931,8 +1925,7 @@ static int wait_til_done(void (*handler)(void), int interruptible)
unsigned long flags;
floppy_tq.routine = (void *)(void *) handler;
queue_task(&floppy_tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
queue_task(&floppy_tq, &tq_timer);
INT_OFF;
while(command_status < 2 && NO_SIGNAL){
is_alive("wait_til_done");
......@@ -2740,8 +2733,7 @@ static void redo_fd_request(void)
if (TESTF(FD_NEED_TWADDLE))
twaddle();
floppy_tq.routine = (void *)(void *) floppy_start;
queue_task(&floppy_tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
queue_task(&floppy_tq, &tq_timer);
#ifdef DEBUGT
debugt("queue fd request");
#endif
......@@ -2762,8 +2754,7 @@ static struct tq_struct request_tq =
static void process_fd_request(void)
{
cont = &rw_cont;
queue_task(&request_tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
queue_task(&request_tq, &tq_timer);
}
static void do_fd_request(void)
......
......@@ -256,6 +256,7 @@
* fix missing restore_flags() in ide_ioctl
* prevent use of io_32bit on cmd640 with no prefetch
* Version 5.49 fix minor quirks in probing routines
* Version 5.50 allow values as small as 20 for idebus=
*
* Some additional driver compile-time options are in ide.h
*
......@@ -2807,7 +2808,7 @@ static int match_parm (char *s, const char *keywords[], int vals[], int max_vals
* older/odd IDE drives.
*
* "idebus=xx" : inform IDE driver of VESA/PCI bus speed in Mhz,
* where "xx" is between 25 and 66 inclusive,
* where "xx" is between 20 and 66 inclusive,
* used when tuning chipset PIO modes.
* For PCI bus, 25 is correct for a P75 system,
* 30 is correct for P90,P120,P180 systems,
......@@ -2912,10 +2913,10 @@ void ide_setup (char *s)
if (s[3] == 'b' && s[4] == 'u' && s[5] == 's') {
if (match_parm(&s[6], NULL, vals, 1) != 1)
goto bad_option;
if (vals[0] >= 25 && vals[0] <= 66)
if (vals[0] >= 20 && vals[0] <= 66)
idebus_parameter = vals[0];
else
printk(" -- BAD BUS SPEED! Expected value from 25 to 66");
printk(" -- BAD BUS SPEED! Expected value from 20 to 66");
goto done;
}
/*
......
......@@ -42,7 +42,7 @@
#endif
#ifdef CONFIG_BLK_DEV_CMD640
#if 1
#if 0 /* change to 1 when debugging cmd640 problems */
void cmd640_dump_regs (void);
#define CMD640_DUMP_REGS cmd640_dump_regs() /* for debugging cmd640 chipset */
#endif
......
......@@ -17,6 +17,11 @@
**********************
v2.55 (96/08/05)
- A couple more messages moved to D_EXTRA.
- SLOW_XMIT_COPY off by default.
- Some tiny changes.
v2.54 (96/07/05)
- Under some situations, Stage 5 autoprobe was a little bit too
picky about the TXACK flag.
......@@ -154,14 +159,19 @@
TO DO: (semi-prioritized)
- Smarter recovery from RECON-during-transmit conditions.
- Support "arpless" mode like NetBSD does, and as recommended
by the (obsoleted) RFC1051.
- Smarter recovery from RECON-during-transmit conditions. (ie.
retransmit immediately)
- Make arcnetE_send_packet use arcnet_prepare_tx for loading the
packet into ARCnet memory.
- Probe for multiple devices in one shot (trying to decide whether
to do it the "ugly" way or not).
- Add support for the new 1.3.x IP header cache features.
- Debug level should be changed with a system call, not a hack to
the "metric" flag.
- Some cards have shared memory with 4k mirrors instead of just 2k,
so we (uneventfully) find the "wrong" shmem when probing.
- Probe for multiple devices in one shot (trying to decide whether
to do it the "ugly" way or not).
- Add support for the new 1.3.x IP header cache, and other features.
- Debug level should be changed with a system call, not a hack to
the "metric" flag.
- What about cards with shared memory that can be "turned off?"
(or that have none at all, like the SMC PC500longboard)
- Autoconfigure PDI5xxPlus cards. (I now have a PDI508Plus to play
......@@ -192,7 +202,7 @@
*/
static const char *version =
"arcnet.c: v2.54 96/07/05 Avery Pennarun <apenwarr@foxnet.net>\n";
"arcnet.c: v2.55 96/08/05 Avery Pennarun <apenwarr@foxnet.net>\n";
......@@ -244,11 +254,11 @@ static const char *version =
* defines; ARCnet probably is not the only driver that can screw up an
* ftape DMA transfer.
*
* Turn this off if you don't have timing-sensitive DMA (ie. a tape drive)
* and would like the little bit of speed back. It's on by default because
* - trust me - it's very difficult to figure out that you need it!
* Turn this on if you have timing-sensitive DMA (ie. a tape drive) and
* would like to sacrifice a little bit of network speed to reduce tape
* write retries or some related problem.
*/
#define SLOW_XMIT_COPY
#undef SLOW_XMIT_COPY
/* The card sends the reconfiguration signal when it loses the connection to
* the rest of its network. It is a 'Hello, is anybody there?' cry. This
......@@ -2310,7 +2320,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
if (in->skb) /* already assembling one! */
{
BUGMSG(D_NORMAL,"aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
BUGMSG(D_EXTRA,"aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
in->sequence,arcsoft->split_flag,
arcsoft->sequence);
kfree_skb(in->skb,FREE_WRITE);
......@@ -2407,7 +2417,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
if (in->skb && in->sequence!=arcsoft->sequence)
{
BUGMSG(D_NORMAL,"wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
BUGMSG(D_EXTRA,"wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
saddr,in->sequence,arcsoft->sequence,
arcsoft->split_flag);
kfree_skb(in->skb,FREE_WRITE);
......@@ -2423,7 +2433,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
arcsoft->split_flag);
if (in->skb) /* already assembling one! */
{
BUGMSG(D_NORMAL,"aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n",
BUGMSG(D_EXTRA,"aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n",
in->sequence,arcsoft->split_flag,
arcsoft->sequence);
lp->stats.rx_errors++;
......@@ -2437,7 +2447,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
if (in->numpackets>16)
{
BUGMSG(D_NORMAL,"incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
BUGMSG(D_EXTRA,"incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
arcsoft->split_flag);
lp->stats.rx_errors++;
lp->stats.rx_length_errors++;
......@@ -2477,7 +2487,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
*/
if (!in->skb)
{
BUGMSG(D_NORMAL,"can't continue split without starting first! (splitflag=%d, seq=%d)\n",
BUGMSG(D_EXTRA,"can't continue split without starting first! (splitflag=%d, seq=%d)\n",
arcsoft->split_flag,arcsoft->sequence);
lp->stats.rx_errors++;
lp->stats.rx_missed_errors++;
......@@ -2490,7 +2500,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
/* harmless duplicate? ignore. */
if (packetnum<=in->lastpacket-1)
{
BUGMSG(D_NORMAL,"duplicate splitpacket ignored! (splitflag=%d)\n",
BUGMSG(D_EXTRA,"duplicate splitpacket ignored! (splitflag=%d)\n",
arcsoft->split_flag);
lp->stats.rx_errors++;
lp->stats.rx_frame_errors++;
......@@ -2498,7 +2508,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
}
/* "bad" duplicate, kill reassembly */
BUGMSG(D_NORMAL,"out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n",
BUGMSG(D_EXTRA,"out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n",
in->sequence,arcsoft->split_flag,
arcsoft->sequence);
kfree_skb(in->skb,FREE_WRITE);
......
This diff is collapsed.
......@@ -873,9 +873,9 @@ plip_rebuild_header(void *buff, struct device *dev, unsigned long dst,
return 0;
}
for (i=0; i < ETH_ALEN - sizeof(unsigned long); i++)
for (i=0; i < ETH_ALEN - sizeof(u32); i++)
eth->h_dest[i] = 0xfc;
memcpy(&(eth->h_dest[i]), &dst, sizeof(unsigned long));
*(u32 *)(eth->h_dest+i) = dst;
return 0;
}
......@@ -964,9 +964,9 @@ plip_open(struct device *dev)
nl->is_deferred = 0;
/* Fill in the MAC-level header. */
for (i=0; i < ETH_ALEN - sizeof(unsigned long); i++)
for (i=0; i < ETH_ALEN - sizeof(u32); i++)
dev->dev_addr[i] = 0xfc;
memcpy(&(dev->dev_addr[i]), &dev->pa_addr, sizeof(unsigned long));
*(u32 *)(dev->dev_addr+i) = dev->pa_addr;
dev->interrupt = 0;
dev->start = 1;
......
/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
* Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu
* Revised: Thu Apr 4 20:44:47 1996 by r.faith@ieee.org
* Revised: Thu Aug 8 14:58:51 1996 by r.faith@ieee.org
* Author: Rickard E. Faith, faith@cs.unc.edu
* Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith
*
* $Id: fdomain.c,v 5.41 1996/04/05 04:22:25 root Exp $
* $Id: fdomain.c,v 5.44 1996/08/08 18:58:53 root Exp $
* 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
......@@ -104,6 +104,7 @@
1.3.34 5.39 12 Oct 1995 V3.60 BIOS; /proc
1.3.72 5.39 8 Feb 1996 Adaptec AHA-2920 board
1.3.85 5.41 4 Apr 1996
2.0.12 5.44 8 Aug 1996 Use ID 7 for all PCI cards
......@@ -275,7 +276,7 @@ struct proc_dir_entry proc_scsi_fdomain = {
S_IFDIR | S_IRUGO | S_IXUGO, 2
};
#define VERSION "$Revision: 5.41 $"
#define VERSION "$Revision: 5.44 $"
/* START OF USER DEFINABLE OPTIONS */
......@@ -580,8 +581,8 @@ static int fdomain_is_valid_port( int port )
/* Try to toggle 32-bit mode. This only
works on an 18c30 chip. (User reports
say that this doesn't work at all, so
we'll use the other method.) */
say this works, so we should switch to
it in the near future.) */
outb( 0x80, port + IO_Control );
if ((inb( port + Configuration2 ) & 0x80) == 0x80) {
......@@ -1018,7 +1019,7 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
tpnt->this_id = (this_id & 0x07);
adapter_mask = (1 << tpnt->this_id);
} else {
if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
if (PCI_bus || (bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
tpnt->this_id = 7;
adapter_mask = 0x80;
} else {
......@@ -1246,7 +1247,7 @@ static int fdomain_select( int target )
#endif
#if ERRORS_ONLY
if (!target) {
if (chip == tmc18c30 && !flag) /* Skip first failure for 18C30 chips. */
if (!flag) /* Skip first failure for all chips. */
++flag;
else
printk( "fdomain: Selection failed\n" );
......@@ -1394,7 +1395,9 @@ void fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs )
printk( "Status = %x, ", current_SC->SCp.Status );
#endif
#if ERRORS_ONLY
if (current_SC->SCp.Status && current_SC->SCp.Status != 2) {
if (current_SC->SCp.Status
&& current_SC->SCp.Status != 2
&& current_SC->SCp.Status != 8) {
printk( "fdomain: target = %d, command = %x, status = %x\n",
current_SC->target,
current_SC->cmnd[0],
......@@ -1666,7 +1669,7 @@ void fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs )
qualifier = (unsigned char)(*((char *)current_SC->request_buffer
+ 13));
if (!(key == UNIT_ATTENTION && (code == 0x29 || !code))
if (key != UNIT_ATTENTION
&& !(key == NOT_READY
&& code == 0x04
&& (!qualifier || qualifier == 0x02 || qualifier == 0x01))
......
......@@ -261,6 +261,9 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
#ifdef CONFIG_SCSI_QLOGIC_FAS
QLOGICFAS,
#endif
#ifdef CONFIG_SCSI_QLOGIC_ISP
QLOGICISP,
#endif
#ifdef CONFIG_SCSI_PAS16
MV_PAS16,
#endif
......@@ -294,9 +297,6 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
#ifdef CONFIG_SCSI_AM53C974
AM53C974,
#endif
#ifdef CONFIG_SCSI_QLOGIC_ISP
QLOGICISP,
#endif
#ifdef CONFIG_SCSI_PPA
PPA,
#endif
......
......@@ -490,6 +490,9 @@ static void do_sd_request (void)
if( SDev->removable && !intr_count )
{
scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
/* scsi_ioctl may allow CURRENT to change, so start over. */
SDev->was_reset = 0;
continue;
}
SDev->was_reset = 0;
}
......
......@@ -485,11 +485,11 @@ void sr_photocd(struct inode *inode)
printk(KERN_WARNING"sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
break; /* if the first ioctl fails, we don't call the second one */
}
is_xa = (rec[0] == 0x20);
min = (unsigned long) rec[1]/16*10 + (unsigned long) rec[1]%16;
sec = (unsigned long) rec[2]/16*10 + (unsigned long) rec[2]%16;
frame = (unsigned long) rec[3]/16*10 + (unsigned long) rec[3]%16;
sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
is_xa = (rec[0] == 0x20) || sector;
if (sector) {
sector -= CD_BLOCK_OFFSET;
#ifdef DEBUG
......@@ -566,9 +566,6 @@ void sr_photocd(struct inode *inode)
break;
}
sector = rec[11] + (rec[10] << 8) + (rec[9] << 16) + (rec[8] << 24);
if (rec[6] <= 1) {
sector = 0; /* ignore sector offsets from first track */
}
is_xa = !!sector;
#ifdef DEBUG
if (sector)
......
......@@ -629,7 +629,7 @@ ess_audio_prepare_for_input (int dev, int bsize, int bcount)
if (devc->channels == 1)
{
if (devc->bits == AFMT_U8 == 0)
if (devc->bits == AFMT_U8)
{ /* 8 bit mono */
ess_write (devc, 0xb7, 0x51);
ess_write (devc, 0xb7, 0xd0);
......
......@@ -87,6 +87,7 @@ sb_midi_close (int dev)
sb_dsp_reset (devc);
devc->intr_active = 0;
devc->input_opened = 0;
devc->opened = 0;
restore_flags (flags);
}
......
......@@ -289,7 +289,7 @@ sound_mmap (inode_handle * inode, file_handle * file, vm_area_handle * vma)
size, dmap->bytes_in_use);
}
if (remap_page_range (vma_get_start (vma), virt_to_phys(dmap->raw_buf),
if (remap_page_range (vma_get_start (vma), (unsigned long)dmap->raw_buf,
vma_get_end (vma) - vma_get_start (vma),
vma_get_page_prot (vma)))
return -EAGAIN;
......
......@@ -765,7 +765,7 @@ do_load_elf_library(int fd){
/* First of all, some simple consistency checks */
if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
(elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
!elf_check_arch(elf_ex.e_machine) ||
(!inode->i_op || !inode->i_op->default_file_ops->mmap))
return -ENOEXEC;
......
......@@ -1101,7 +1101,7 @@ static inline void after_unlock_page (struct page * page)
if (clear_bit(PG_decr_after, &page->flags))
atomic_dec(&nr_async_pages);
if (clear_bit(PG_free_after, &page->flags))
free_page(page_address(page));
__free_page(page);
if (clear_bit(PG_swap_unlock_after, &page->flags))
swap_after_unlock_page(page->swap_unlock_entry);
}
......@@ -1322,11 +1322,10 @@ void unlock_buffer(struct buffer_head * bh)
*/
int generic_readpage(struct inode * inode, struct page * page)
{
unsigned long block, address;
unsigned long block;
int *p, nr[PAGE_SIZE/512];
int i;
address = page_address(page);
page->count++;
set_bit(PG_locked, &page->flags);
set_bit(PG_free_after, &page->flags);
......@@ -1342,7 +1341,7 @@ int generic_readpage(struct inode * inode, struct page * page)
} while (i > 0);
/* IO start */
brw_page(READ, address, inode->i_dev, nr, inode->i_sb->s_blocksize, 1);
brw_page(READ, page_address(page), inode->i_dev, nr, inode->i_sb->s_blocksize, 1);
return 0;
}
......
......@@ -25,6 +25,9 @@
*
* Bruno Haible : remove 4K limit for the maps file
* <haible@ma2s2.mathematik.uni-karlsruhe.de>
*
* Yves Arrouye : remove removal of trailing spaces in get_array.
* <Yves.Arrouye@marin.fdn.fr>
*/
#include <linux/types.h>
......@@ -370,7 +373,7 @@ static int get_array(struct task_struct ** p, unsigned long start, unsigned long
for (;;) {
addr = get_phys_addr(*p, start);
if (!addr)
goto ready;
return result;
do {
c = *(char *) addr;
if (!c)
......@@ -378,17 +381,13 @@ static int get_array(struct task_struct ** p, unsigned long start, unsigned long
if (size < PAGE_SIZE)
buffer[size++] = c;
else
goto ready;
return result;
addr++;
start++;
if (!c && start >= end)
goto ready;
return result;
} while (addr & ~PAGE_MASK);
}
ready:
/* remove the trailing blanks, used to fill out argv,envp space */
while (result>0 && buffer[result-1]==' ')
result--;
return result;
}
......
......@@ -967,7 +967,7 @@ static void do_mount_root(void)
#ifdef CONFIG_BLK_DEV_FD
if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
floppy_eject();
#ifdef CONFIG_BLK_DEV_RAM
#ifndef CONFIG_BLK_DEV_RAM
printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
#endif
printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
......
......@@ -38,4 +38,15 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
memcpy((char *) &_dest, (char *) &_dump.regs, \
sizeof(elf_gregset_t)); }
/* $0 is set by ld.so to a pointer to a function which might be
registered using atexit. This provides a mean for the dynamic
linker to call DT_FINI functions for shared libraries that have
been loaded before the code runs.
So that we can use the same startup file with static executables,
we start programs with a value of 0 to indicate that there is no
such function. */
#define ELF_PLAT_INIT(_r) _r->r0 = 0
#endif
......@@ -17,17 +17,46 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
#define elf_check_arch(x) ((x) == EM_M68K)
#define elf_check_arch(x) ((x) == EM_68K)
/*
* These are used to set parameters in the core dumps.
* FIXME(eric) I don't know what the correct endianness to use is.
*/
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB;
#define ELF_ARCH EM_M68K
#define ELF_ARCH EM_68K
/* For SVR4/m68k the function pointer to be registered with
`atexit' is passed in %a1. Although my copy of the ABI has
no such statement, it is actually used on ASV. */
#define ELF_PLAT_INIT(_r) _r->a1 = 0
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
/* Bleech. */ \
pr_reg[0] = regs->d1; \
pr_reg[1] = regs->d2; \
pr_reg[2] = regs->d3; \
pr_reg[3] = regs->d4; \
pr_reg[4] = regs->d5; \
pr_reg[7] = regs->a0; \
pr_reg[8] = regs->a1; \
pr_reg[14] = regs->d0; \
pr_reg[15] = rdusp(); \
pr_reg[16] = 0; /* orig_d0 */ \
pr_reg[17] = regs->sr; \
pr_reg[18] = regs->pc; \
{ \
struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \
pr_reg[5] = sw->d6; \
pr_reg[6] = sw->d7; \
pr_reg[9] = sw->a2; \
pr_reg[10] = sw->a3; \
pr_reg[11] = sw->a4; \
pr_reg[12] = sw->a5; \
pr_reg[13] = sw->a6; \
}
#endif
/*
* These are the public elements of the Linux kernel AX.25 code. A similar
* file netrom.h exists for the NET/ROM protocol.
*/
#ifndef AX25_KERNEL_H
#define AX25_KERNEL_H
#define PF_AX25 AF_AX25
#define AX25_MTU 256
#define AX25_MAX_DIGIS 6
typedef struct
{
char ax25_call[7]; /* 6 call + SSID (shifted ascii!) */
}
ax25_address;
struct sockaddr_ax25
{
short sax25_family;
ax25_address sax25_call;
int sax25_ndigis;
/* Digipeater ax25_address sets follow */
};
#define sax25_uid sax25_ndigis
struct full_sockaddr_ax25
{
struct sockaddr_ax25 fsa_ax25;
ax25_address fsa_digipeater[AX25_MAX_DIGIS];
};
struct ax25_routes_struct
{
ax25_address port_addr;
ax25_address dest_addr;
unsigned char digi_count;
ax25_address digi_addr[AX25_MAX_DIGIS];
};
struct ax25_route_opt_struct
{
ax25_address port_addr;
ax25_address dest_addr;
int cmd;
int arg;
};
struct ax25_ctl_struct
{
ax25_address port_addr;
ax25_address source_addr;
ax25_address dest_addr;
unsigned int cmd;
unsigned long arg;
};
struct ax25_bpqaddr_struct
{
char dev[16];
ax25_address addr;
};
#define AX25_MAX_DIGIS 6 /* This is wrong, should be 8 */
#define AX25_WINDOW 1
#define AX25_T1 2
......@@ -79,16 +34,8 @@ struct ax25_bpqaddr_struct
#define SIOCAX25OPTRT (SIOCPROTOPRIVATE+7)
#define SIOCAX25CTLCON (SIOCPROTOPRIVATE+8)
#define AX25_SET_RT_PERMANENT 1
#define AX25_SET_RT_IPMODE 2
#define AX25_RT_DYNAMIC 0
#define AX25_RT_PERMANENT 1
#define AX25_RT_IPMODE_DEFAULT ' '
#define AX25_RT_IPMODE_DATAGRAM 'D'
#define AX25_RT_IPMODE_VC 'V'
#define AX25_NOUID_DEFAULT 0
#define AX25_NOUID_BLOCK 1
......@@ -113,8 +60,54 @@ struct ax25_bpqaddr_struct
#define AX25_VALUES_IPMAXQUEUE 15 /* Maximum number of buffers enqueued */
#define AX25_MAX_VALUES 20
struct ax25_parms_struct
{
typedef struct {
char ax25_call[7]; /* 6 call + SSID (shifted ascii!) */
} ax25_address;
struct sockaddr_ax25 {
short sax25_family;
ax25_address sax25_call;
int sax25_ndigis;
/* Digipeater ax25_address sets follow */
};
#define sax25_uid sax25_ndigis
struct full_sockaddr_ax25 {
struct sockaddr_ax25 fsa_ax25;
ax25_address fsa_digipeater[AX25_MAX_DIGIS];
};
struct ax25_routes_struct {
ax25_address port_addr;
ax25_address dest_addr;
unsigned char digi_count;
ax25_address digi_addr[AX25_MAX_DIGIS];
};
struct ax25_route_opt_struct {
ax25_address port_addr;
ax25_address dest_addr;
int cmd;
int arg;
};
struct ax25_ctl_struct {
ax25_address port_addr;
ax25_address source_addr;
ax25_address dest_addr;
unsigned int cmd;
unsigned long arg;
};
struct ax25_bpqaddr_struct {
char dev[16];
ax25_address addr;
};
struct ax25_parms_struct {
ax25_address port_addr;
unsigned short values[AX25_MAX_VALUES];
};
#endif
......@@ -38,7 +38,6 @@ typedef unsigned long Elf32_Word;
#define EM_88K 5
#define EM_486 6 /* Perhaps disused */
#define EM_860 7
#define EM_PPC 20
#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
......
......@@ -116,6 +116,9 @@ struct vm_operations_struct {
* is used for linear searches (eg. clock algorithm scans).
*/
typedef struct page {
/* these must be first (free area handling) */
struct page *next;
struct page *prev;
struct inode *inode;
unsigned long offset;
struct page *next_hash;
......@@ -124,8 +127,6 @@ typedef struct page {
unsigned dirty:16,
age:8;
struct wait_queue *wait;
struct page *next;
struct page *prev;
struct page *prev_hash;
struct buffer_head * buffers;
unsigned long swap_unlock_entry;
......@@ -247,6 +248,7 @@ extern inline unsigned long get_free_page(int priority)
#define free_page(addr) free_pages((addr),0)
extern void free_pages(unsigned long addr, unsigned long order);
extern void __free_page(struct page *);
extern void show_free_areas(void);
extern unsigned long put_dirty_page(struct task_struct * tsk,unsigned long page,
......
/*
* These are the public elements of the Linux kernel NET/ROM implementation.
* For kernel AX.25 see the file ax25.h. This file requires ax25.h for the
* definition of the ax25_address structure.
*/
#ifndef NETROM_KERNEL_H
#define NETROM_KERNEL_H
#define PF_NETROM AF_NETROM
#define NETROM_MTU 236
......@@ -45,3 +54,5 @@ struct nr_ctl_struct {
unsigned int cmd;
unsigned long arg;
};
#endif
......@@ -126,7 +126,7 @@
#define AX25_DEF_N2 10
#define AX25_DEF_IDLE 20
#define AX25_DEF_PACLEN 256
#define AX25_DEF_IPMAXQUEUE 1 /* 1 * ax25->window */
#define AX25_DEF_IPMAXQUEUE 2 /* 1 * ax25->window */
#define AX25_DEF_DIGI (AX25_DIGI_INBAND|AX25_DIGI_XBAND)
typedef struct ax25_uid_assoc {
......@@ -203,15 +203,13 @@ extern void dama_check_need_response(ax25_cb *, int, int); /* dl1bke 960114 */
extern void dama_establish_data_link(ax25_cb *);
/* ax25_route.c */
extern void ax25_rt_rx_frame(ax25_address *, struct device *, ax25_digi *);
extern int ax25_rt_get_info(char *, char **, off_t, int, int);
extern int ax25_cs_get_info(char *, char **, off_t, int, int);
extern int ax25_rt_autobind(ax25_cb *, ax25_address *);
extern void ax25_rt_build_path(ax25_cb *, ax25_address *);
extern void ax25_rt_build_path(ax25_cb *, ax25_address *, struct device *);
extern void ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *);
extern void ax25_rt_device_down(struct device *);
extern int ax25_rt_ioctl(unsigned int, void *);
extern void ax25_ip_mode_set(ax25_address *, struct device *, char);
extern char ax25_ip_mode_get(ax25_address *, struct device *);
extern unsigned short ax25_dev_get_value(struct device *, int);
extern void ax25_dev_device_up(struct device *);
......
......@@ -64,10 +64,21 @@ typedef struct {
struct sock *sk; /* Backlink to socket */
} nr_cb;
struct nr_neigh {
struct nr_neigh *next;
ax25_address callsign;
ax25_digi *digipeat;
struct device *dev;
unsigned char quality;
unsigned char locked;
unsigned short count;
unsigned int number;
};
struct nr_route {
unsigned char quality;
unsigned char obs_count;
unsigned short neighbour;
unsigned char quality;
unsigned char obs_count;
struct nr_neigh *neighbour;
};
struct nr_node {
......@@ -79,17 +90,6 @@ struct nr_node {
struct nr_route routes[3];
};
struct nr_neigh {
struct nr_neigh *next;
ax25_address callsign;
ax25_digi *digipeat;
struct device *dev;
unsigned char quality;
unsigned char locked;
unsigned short count;
unsigned short number;
};
/* af_netrom.c */
extern struct nr_parms_struct nr_default;
extern int nr_rx_frame(struct sk_buff *, struct device *);
......
......@@ -78,7 +78,7 @@ void invalidate_inode_pages(struct inode * inode)
page->prev = NULL;
remove_page_from_hash_queue(page);
page->inode = NULL;
free_page(page_address(page));
__free_page(page);
continue;
}
}
......@@ -111,15 +111,16 @@ void truncate_inode_pages(struct inode * inode, unsigned long start)
page->prev = NULL;
remove_page_from_hash_queue(page);
page->inode = NULL;
free_page(page_address(page));
__free_page(page);
continue;
}
p = &page->next;
offset = start - offset;
/* partial truncate, clear end of page */
if (offset < PAGE_SIZE) {
memset((void *) (offset + page_address(page)), 0, PAGE_SIZE - offset);
flush_page_to_ram(page_address(page));
unsigned long address = page_address(page);
memset((void *) (offset + address), 0, PAGE_SIZE - offset);
flush_page_to_ram(address);
}
}
}
......@@ -175,7 +176,7 @@ int shrink_mmap(int priority, int dma)
if (page->inode) {
remove_page_from_hash_queue(page);
remove_page_from_inode_queue(page);
free_page(page_address(page));
__free_page(page);
return 1;
}
......
......@@ -36,30 +36,34 @@ int nr_free_pages = 0;
#define NR_MEM_LISTS 6
/* The start of this MUST match the start of "struct page" */
struct free_area_struct {
struct page list;
struct page *next;
struct page *prev;
unsigned int * map;
};
#define memory_head(x) ((struct page *)x)
static struct free_area_struct free_area[NR_MEM_LISTS];
static inline void init_mem_queue(struct page * head)
static inline void init_mem_queue(struct free_area_struct * head)
{
head->next = head;
head->prev = head;
head->next = memory_head(head);
head->prev = memory_head(head);
}
static inline void add_mem_queue(struct page * head, struct page * entry)
static inline void add_mem_queue(struct free_area_struct * head, struct page * entry)
{
struct page * next = head->next;
entry->prev = head;
entry->prev = memory_head(head);
entry->next = next;
next->prev = entry;
head->next = entry;
}
static inline void remove_mem_queue(struct page * head, struct page * entry)
static inline void remove_mem_queue(struct page * entry)
{
struct page * next = entry->next;
struct page * prev = entry->prev;
......@@ -85,9 +89,12 @@ static inline void remove_mem_queue(struct page * head, struct page * entry)
/*
* Buddy system. Hairy. You really aren't expected to understand this
*
* Hint: -mask = 1+~mask
*/
static inline void free_pages_ok(unsigned long map_nr, unsigned long order)
{
struct free_area_struct *area = free_area + order;
unsigned long index = map_nr >> (1 + order);
unsigned long mask = (~0UL) << order;
unsigned long flags;
......@@ -98,23 +105,32 @@ static inline void free_pages_ok(unsigned long map_nr, unsigned long order)
#define list(x) (mem_map+(x))
map_nr &= mask;
nr_free_pages += 1 << order;
while (order < NR_MEM_LISTS-1) {
if (!change_bit(index, free_area[order].map))
nr_free_pages -= mask;
while (mask + (1 << (NR_MEM_LISTS-1))) {
if (!change_bit(index, area->map))
break;
remove_mem_queue(&free_area[order].list, list(map_nr ^ (1+~mask)));
remove_mem_queue(list(map_nr ^ -mask));
mask <<= 1;
order++;
area++;
index >>= 1;
map_nr &= mask;
}
add_mem_queue(&free_area[order].list, list(map_nr));
add_mem_queue(area, list(map_nr));
#undef list
restore_flags(flags);
}
void __free_page(struct page *page)
{
if (!PageReserved(page) && atomic_dec_and_test(&page->count)) {
unsigned long map_nr = page->map_nr;
delete_from_swap_cache(map_nr);
free_pages_ok(map_nr, 0);
}
}
void free_pages(unsigned long addr, unsigned long order)
{
unsigned long map_nr = MAP_NR(addr);
......@@ -141,8 +157,8 @@ void free_pages(unsigned long addr, unsigned long order)
#define RMQUEUE(order, dma) \
do { struct free_area_struct * area = free_area+order; \
unsigned long new_order = order; \
do { struct page *prev = &area->list, *ret; \
while (&area->list != (ret = prev->next)) { \
do { struct page *prev = memory_head(area), *ret; \
while (memory_head(area) != (ret = prev->next)) { \
if (!dma || CAN_DMA(ret)) { \
unsigned long map_nr = ret->map_nr; \
(prev->next = ret->next)->prev = prev; \
......@@ -162,7 +178,7 @@ do { struct free_area_struct * area = free_area+order; \
do { unsigned long size = 1 << high; \
while (high > low) { \
area--; high--; size >>= 1; \
add_mem_queue(&area->list, map); \
add_mem_queue(area, map); \
MARK_USED(index, high, area); \
index += size; \
map += size; \
......@@ -219,7 +235,7 @@ void show_free_areas(void)
for (order=0 ; order < NR_MEM_LISTS; order++) {
struct page * tmp;
unsigned long nr = 0;
for (tmp = free_area[order].list.next ; tmp != &free_area[order].list ; tmp = tmp->next) {
for (tmp = free_area[order].next ; tmp != memory_head(free_area+order) ; tmp = tmp->next) {
nr ++;
}
total += nr * ((PAGE_SIZE>>10) << order);
......@@ -269,7 +285,7 @@ unsigned long free_area_init(unsigned long start_mem, unsigned long end_mem)
for (i = 0 ; i < NR_MEM_LISTS ; i++) {
unsigned long bitmap_size;
init_mem_queue(&free_area[i].list);
init_mem_queue(free_area+i);
mask += mask;
end_mem = (end_mem + ~mask) & mask;
bitmap_size = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT + i);
......
This diff is collapsed.
/*
* AX.25 release 031
* AX.25 release 032
*
* This is ALPHA test software. This code may break your machine, randomly fail to work with new
* releases, misbehave and/or generally screw up. It might even work.
......@@ -32,6 +32,8 @@
* Joerg(DL1BKE) Renamed it to "IDLE" with a slightly
* different behaviour. Fixed defrag
* routine (I hope)
* AX.25 032 Jonathan(G4KLX) Remove auto-router.
* Darryl(G7LED) AX.25 segmentation fixed.
*/
#include <linux/config.h>
......@@ -70,66 +72,57 @@ static int ax25_rx_iframe(ax25_cb *, struct sk_buff *);
static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb)
{
struct sk_buff *skbn, *skbo;
int hdrlen;
int hdrlen, nhdrlen;
if (ax25->fragno != 0) {
if (!(*skb->data & SEG_FIRST)) {
if ((ax25->fragno - 1) == (*skb->data & SEG_REM)) {
/* enqueue fragment */
/* Enqueue fragment */
ax25->fragno = *skb->data & SEG_REM;
skb_pull(skb, 1); /* skip fragno */
ax25->fraglen += skb->len;
skb_queue_tail(&ax25->frag_queue, skb);
/* last fragment received? */
/* Last fragment received ? */
if (ax25->fragno == 0) {
if ((skbn = alloc_skb(AX25_MAX_HEADER_LEN + ax25->fraglen, GFP_ATOMIC)) == NULL)
return 0;
if ((skbn = alloc_skb(AX25_MAX_HEADER_LEN + ax25->fraglen, GFP_ATOMIC)) == NULL) {
while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL)
kfree_skb(skbo, FREE_READ);
return 1;
}
skbn->free = 1;
skbn->arp = 1;
skbn->dev = skb->dev;
skbn->dev = ax25->device;
if (ax25->sk != NULL) {
skbn->sk = ax25->sk;
atomic_add(skbn->truesize, &ax25->sk->rmem_alloc);
}
/* get first fragment from queue */
skb_reserve(skbn, AX25_MAX_HEADER_LEN);
/* Get first fragment from queue */
skbo = skb_dequeue(&ax25->frag_queue);
hdrlen = skbo->data - skbo->h.raw - 2; /* skip PID & fragno */
skb_push(skbo, hdrlen + 2); /* start of address field */
skbn->data = skb_put(skbn, hdrlen); /* get space for info */
memcpy(skbn->data, skbo->data, hdrlen); /* copy address field */
skb_pull(skbo, hdrlen + 2); /* start of data */
skb_pull(skbn, hdrlen + 1); /* ditto */
hdrlen = skbo->data - skbo->h.raw;
nhdrlen = hdrlen - 2;
/* copy data from first fragment */
skb_push(skbo, hdrlen);
skb_push(skbn, nhdrlen);
skbn->h.raw = skbn->data;
memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
kfree_skb(skbo, FREE_READ);
/* add other fragment's data */
/* Copy AX.25 headers */
memcpy(skbn->data, skbo->data, nhdrlen);
skb_pull(skbn, nhdrlen);
skb_pull(skbo, hdrlen);
while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL) {
/* Copy data from the fragments */
do {
memcpy(skb_put(skbn, skbo->len), skbo->data, skbo->len);
kfree_skb(skbo, FREE_READ);
}
} while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL);
ax25->fraglen = 0; /* reset counter */
/*
* mysteriously we need to re-adjust skb->data.
* Anyway, it seems to work. Do we have the address fields
* encoded TWICE in one sk_buff?
*/
skb_pull(skbn, hdrlen);
ax25->fraglen = 0;
if (ax25_rx_iframe(ax25, skbn) == 0)
kfree_skb(skbn, FREE_READ);
......@@ -139,9 +132,10 @@ static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb)
}
}
} else {
/* first fragment received? */
/* First fragment received */
if (*skb->data & SEG_FIRST) {
while ((skbo = skb_dequeue(&ax25->frag_queue)) != NULL)
kfree_skb(skbo, FREE_READ);
ax25->fragno = *skb->data & SEG_REM;
skb_pull(skb, 1); /* skip fragno */
ax25->fraglen = skb->len;
......@@ -181,7 +175,6 @@ static int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
case AX25_P_IP:
skb_pull(skb, 1); /* Remove PID */
skb->h.raw = skb->data;
ax25_ip_mode_set(&ax25->dest_addr, ax25->device, 'V');
ip_rcv(skb, ax25->device, NULL); /* Wrong ptype */
queued = 1;
break;
......@@ -273,7 +266,7 @@ static int ax25_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
break;
default:
if (dama && pf) /* dl1bke 960116 */
if (dama && pf)
ax25_send_control(ax25, SABM, POLLON, C_COMMAND);
break;
}
......@@ -490,7 +483,7 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
}
if (ax25->condition & OWN_RX_BUSY_CONDITION) {
if (pf) {
if (ax25->dama_slave) /* dl1bke 960114 */
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
ax25_enquiry_response(ax25);
......@@ -498,20 +491,21 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
break;
}
if (ns == ax25->vr) {
ax25->vr = (ax25->vr + 1) % ax25->modulus;
queued = ax25_rx_iframe(ax25, skb);
if (ax25->condition & OWN_RX_BUSY_CONDITION) {
ax25->vr = ns; /* ax25->vr - 1 */
if (pf) {
if (ax25->dama_slave) /* dl1bke 960114 */
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
ax25_enquiry_response(ax25);
}
break;
}
ax25->vr = (ax25->vr + 1) % ax25->modulus;
ax25->condition &= ~REJECT_CONDITION;
if (pf) {
if (ax25->dama_slave) /* dl1bke 960114 */
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
ax25_enquiry_response(ax25);
......@@ -524,14 +518,14 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
} else {
if (ax25->condition & REJECT_CONDITION) {
if (pf) {
if (ax25->dama_slave) /* dl1bke 960114 */
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
ax25_enquiry_response(ax25);
}
} else {
ax25->condition |= REJECT_CONDITION;
if (ax25->dama_slave) /* dl1bke 960114 */
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
ax25_send_control(ax25, REJ, pf, C_RESPONSE);
......@@ -660,7 +654,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
case RR:
ax25->condition &= ~PEER_RX_BUSY_CONDITION;
if ( pf && (type == C_RESPONSE || (ax25->dama_slave && type == C_COMMAND)) ) {
if (pf && (type == C_RESPONSE || (ax25->dama_slave && type == C_COMMAND))) {
ax25->t1timer = 0;
if (ax25_validate_nr(ax25, nr)) {
ax25_frames_acked(ax25, nr);
......@@ -691,7 +685,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
case REJ:
ax25->condition &= ~PEER_RX_BUSY_CONDITION;
if ( pf && (type == C_RESPONSE || (ax25->dama_slave && type == C_COMMAND)) ) {
if (pf && (type == C_RESPONSE || (ax25->dama_slave && type == C_COMMAND))) {
ax25->t1timer = 0;
if (ax25_validate_nr(ax25, nr)) {
ax25_frames_acked(ax25, nr);
......@@ -735,7 +729,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
}
ax25_frames_acked(ax25, nr);
if (ax25->condition & OWN_RX_BUSY_CONDITION) {
if (pf) { /* dl1bke 960114 */
if (pf) {
if (ax25->dama_slave)
ax25_enquiry_response(ax25);
else
......@@ -744,9 +738,11 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
break;
}
if (ns == ax25->vr) {
ax25->vr = (ax25->vr + 1) % ax25->modulus;
queued = ax25_rx_iframe(ax25, skb);
if (ax25->condition & OWN_RX_BUSY_CONDITION) {
if (pf) { /* dl1bke 960114 */
ax25->vr = ns; /* ax25->vr - 1 */
if (pf) {
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
......@@ -754,10 +750,9 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
}
break;
}
ax25->vr = (ax25->vr + 1) % ax25->modulus;
ax25->condition &= ~REJECT_CONDITION;
if (pf) {
if (ax25->dama_slave) /* dl1bke 960114 */
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
ax25_enquiry_response(ax25);
......@@ -769,7 +764,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
}
} else {
if (ax25->condition & REJECT_CONDITION) {
if (pf) { /* dl1bke 960114 */
if (pf) {
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
......@@ -777,7 +772,7 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
}
} else {
ax25->condition |= REJECT_CONDITION;
if (ax25->dama_slave) /* dl1bke 960114 */
if (ax25->dama_slave)
dama_enquiry_response(ax25);
else
ax25_send_control(ax25, REJ, pf, C_RESPONSE);
......
/*
* AX.25 release 031
* AX.25 release 032
*
* This is ALPHA test software. This code may break your machine, randomly fail to work with new
* releases, misbehave and/or generally screw up. It might even work.
......@@ -25,7 +25,6 @@
* AX.25 030 Jonathan(G4KLX) Added fragmentation to ax25_output.
* Added support for extended AX.25.
* AX.25 031 Joerg(DL1BKE) Added DAMA support
*
* Joerg(DL1BKE) Modified fragmenter to fragment vanilla
* AX.25 I-Frames. Added PACLEN parameter.
* Joerg(DL1BKE) Fixed a problem with buffer allocation
......@@ -214,7 +213,7 @@ void ax25_kick(ax25_cb *ax25)
do {
if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
skb_queue_head(&ax25->write_queue, skb);
return;
break;
}
next = (ax25->vs + 1) % ax25->modulus;
......
This diff is collapsed.
/*
* AX.25 release 031
* AX.25 release 032
*
* This is ALPHA test software. This code may break your machine, randomly fail to work with new
* releases, misbehave and/or generally screw up. It might even work.
......@@ -101,7 +101,7 @@ void ax25_frames_acked(ax25_cb *ax25, unsigned short nr)
skb->free = 1;
kfree_skb(skb, FREE_WRITE);
ax25->va = (ax25->va + 1) % ax25->modulus;
if (ax25->dama_slave) /* dl1bke 960120 */
if (ax25->dama_slave)
ax25->n2count = 0;
}
}
......
/*
* AX.25 release 031
* AX.25 release 032
*
* This is ALPHA test software. This code may break your machine, randomly fail to work with new
* releases, misbehave and/or generally screw up. It might even work.
......@@ -113,7 +113,7 @@ static void ax25_timer(unsigned long param)
if (ax25->sk != NULL) {
if (ax25->sk->rmem_alloc < (ax25->sk->rcvbuf / 2) && (ax25->condition & OWN_RX_BUSY_CONDITION)) {
ax25->condition &= ~OWN_RX_BUSY_CONDITION;
if (!ax25->dama_slave) /* dl1bke */
if (!ax25->dama_slave)
ax25_send_control(ax25, RR, POLLOFF, C_RESPONSE);
ax25->condition &= ~ACK_PENDING_CONDITION;
break;
......@@ -123,7 +123,7 @@ static void ax25_timer(unsigned long param)
* Check for frames to transmit.
*/
if (!ax25->dama_slave)
ax25_kick(ax25); /* dl1bke 960114 */
ax25_kick(ax25);
break;
default:
......@@ -134,7 +134,7 @@ static void ax25_timer(unsigned long param)
if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
if (ax25->condition & ACK_PENDING_CONDITION) {
ax25->condition &= ~ACK_PENDING_CONDITION;
if (!ax25->dama_slave) /* dl1bke 960114 */
if (!ax25->dama_slave)
ax25_timeout_response(ax25);
}
}
......@@ -272,7 +272,7 @@ void ax25_t1_timeout(ax25_cb * ax25)
#endif
ax25_clear_queues(ax25);
ax25->state = AX25_STATE_0;
ax25_send_control(ax25, DISC, POLLON, C_COMMAND); /* dl1bke */
ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
if (ax25->sk != NULL) {
ax25->sk->state = TCP_CLOSE;
......@@ -283,14 +283,14 @@ void ax25_t1_timeout(ax25_cb * ax25)
}
} else {
ax25->n2count++;
if (!ax25_dev_is_dama_slave(ax25->device)) /* dl1bke */
if (!ax25_dev_is_dama_slave(ax25->device))
ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
}
break;
case AX25_STATE_3:
ax25->n2count = 1;
if (!ax25->dama_slave) /* dl1bke 960114 */
if (!ax25->dama_slave)
ax25_transmit_enquiry(ax25);
ax25->state = AX25_STATE_4;
break;
......@@ -314,7 +314,7 @@ void ax25_t1_timeout(ax25_cb * ax25)
}
} else {
ax25->n2count++;
if (!ax25->dama_slave) /* dl1bke 960114 */
if (!ax25->dama_slave)
ax25_transmit_enquiry(ax25);
}
break;
......
......@@ -315,7 +315,7 @@ int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag,
#endif
IS_SKB(skb);
if (skb->len+encap > dev2->mtu && (ntohs(iph->frag_off) & IP_DF))
if (skb->len+encap > dev2->mtu && (iph->frag_off & htons(IP_DF)))
{
ip_statistics.IpFragFails++;
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(dev2->mtu), dev);
......
......@@ -645,7 +645,7 @@ void ip_fragment(struct sock *sk, struct sk_buff *skb, struct device *dev, int i
* Check for any "DF" flag. [DF means do not fragment]
*/
if (ntohs(iph->frag_off) & IP_DF)
if (iph->frag_off & htons(IP_DF))
{
ip_statistics.IpFragFails++;
NETDEBUG(printk("ip_queue_xmit: frag needed\n"));
......
......@@ -279,7 +279,7 @@ void tcp_enqueue_partial(struct sk_buff * skb, struct sock * sk)
/*
* Wait up to 1 second for the buffer to fill.
*/
sk->partial_timer.expires = jiffies+HZ;
sk->partial_timer.expires = jiffies+HZ/10;
sk->partial_timer.function = (void (*)(unsigned long)) tcp_send_partial;
sk->partial_timer.data = (unsigned long) sk;
add_timer(&sk->partial_timer);
......@@ -966,6 +966,10 @@ void tcp_send_ack(struct sock *sk)
sock_wfree(sk, buff);
return;
}
#ifndef CONFIG_NO_PATH_MTU_DISCOVERY
buff->ip_hdr->frag_off |= htons(IP_DF);
#endif
t1 =(struct tcphdr *)skb_put(buff,sizeof(struct tcphdr));
/*
......
......@@ -934,7 +934,7 @@ static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
sax->fsa_ax25.sax25_ndigis = 1;
sax->fsa_ax25.sax25_call = sk->nr->user_addr;
sax->fsa_digipeater[0] = sk->nr->dest_addr;
*uaddr_len = sizeof(struct sockaddr_ax25) + AX25_ADDR_LEN;
*uaddr_len = sizeof(struct full_sockaddr_ax25);
} else {
sax->fsa_ax25.sax25_family = AF_NETROM;
sax->fsa_ax25.sax25_ndigis = 0;
......@@ -952,14 +952,13 @@ int nr_rx_frame(struct sk_buff *skb, struct device *dev)
ax25_address *src, *dest, *user;
unsigned short circuit_index, circuit_id;
unsigned short frametype, window, timeout;
skb->sk = NULL; /* Initially we don't know who it's for */
/*
* skb->data points to the netrom frame start
*/
src = (ax25_address *)(skb->data + 0);
dest = (ax25_address *)(skb->data + 7);
......@@ -1327,7 +1326,7 @@ static int nr_get_info(char *buffer, char **start, off_t offset, int length, int
cli();
len += sprintf(buffer, "user_addr dest_node src_node dev my your st vs vr va t1 t2 n2 rtt wnd paclen Snd-Q Rcv-Q\n");
len += sprintf(buffer, "user_addr dest_node src_node dev my your st vs vr va t1 t2 n2 rtt wnd paclen Snd-Q Rcv-Q\n");
for (s = nr_list; s != NULL; s = s->next) {
if ((dev = s->nr->device) == NULL)
......@@ -1339,7 +1338,7 @@ static int nr_get_info(char *buffer, char **start, off_t offset, int length, int
ax2asc(&s->nr->user_addr));
len += sprintf(buffer + len, "%-9s ",
ax2asc(&s->nr->dest_addr));
len += sprintf(buffer + len, "%-9s %-3s %02X/%02X %02X/%02X %2d %2d %2d %2d %3d/%03d %2d/%02d %2d/%02d %3d %3d %6d %5d %5d\n",
len += sprintf(buffer + len, "%-9s %-3s %02X/%02X %02X/%02X %2d %3d %3d %3d %3d/%03d %2d/%02d %2d/%02d %3d %3d %6d %5d %5d\n",
ax2asc(&s->nr->source_addr),
devname, s->nr->my_index, s->nr->my_id,
s->nr->your_index, s->nr->your_id,
......
......@@ -168,7 +168,7 @@ void nr_kick(struct sock *sk)
do {
if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
skb_queue_head(&sk->write_queue, skb);
return;
break;
}
next = (sk->nr->vs + 1) % NR_MODULUS;
......
......@@ -16,13 +16,10 @@
* NET/ROM 001 Jonathan(G4KLX) First attempt.
* NET/ROM 003 Jonathan(G4KLX) Use SIOCADDRT/SIOCDELRT ioctl values
* for NET/ROM routes.
* Use '*' for a blank mnemonic in /proc/net/nr_nodes.
* Change default quality for new neighbour when same
* as node callsign.
* Alan Cox(GW4PTS) Added the firewall hooks.
*
* TO DO
* Sort out the which pointer when shuffling entries in the routes
* section. Also reset the which pointer when a route becomes "good"
* again, ie when a NODES broadcast is processed via calls to
* nr_add_node().
*/
#include <linux/config.h>
......@@ -54,12 +51,14 @@
#include <linux/firewall.h>
#include <net/netrom.h>
static int nr_neigh_no = 1;
static unsigned int nr_neigh_no = 1;
static int nr_route_on = 1;
static struct nr_node *nr_node_list = NULL;
static struct nr_neigh *nr_neigh_list = NULL;
static void nr_remove_neigh(struct nr_neigh *);
/*
* Add a new route to a node, and in the process add the node and the
* neighbour if it is new.
......@@ -72,7 +71,10 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
struct nr_route nr_route;
unsigned long flags;
int i, found;
if (nr_dev_get(nr) != NULL) /* Can't add routes to ourself */
return -EINVAL;
for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next)
if (ax25cmp(nr, &nr_node->callsign) == 0)
break;
......@@ -91,7 +93,10 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
nr_neigh->callsign = *ax25;
nr_neigh->digipeat = NULL;
nr_neigh->dev = dev;
nr_neigh->quality = nr_default.quality;
if (ax25cmp(nr, ax25) == 0)
nr_neigh->quality = quality;
else
nr_neigh->quality = nr_default.quality;
nr_neigh->locked = 0;
nr_neigh->count = 0;
nr_neigh->number = nr_neigh_no++;
......@@ -118,14 +123,14 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
return -ENOMEM;
nr_node->callsign = *nr;
memcpy(&nr_node->mnemonic, mnemonic, sizeof(nr_node->mnemonic));
strcpy(nr_node->mnemonic, mnemonic);
nr_node->which = 0;
nr_node->count = 1;
nr_node->routes[0].quality = quality;
nr_node->routes[0].obs_count = obs_count;
nr_node->routes[0].neighbour = nr_neigh->number;
nr_node->routes[0].neighbour = nr_neigh;
save_flags(flags);
cli();
......@@ -138,10 +143,13 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
nr_neigh->count++;
return 0;
} else {
if (nr_node->mnemonic[0] == '\0')
strcpy(nr_node->mnemonic, mnemonic);
}
for (found = 0, i = 0; i < nr_node->count; i++) {
if (nr_node->routes[i].neighbour == nr_neigh->number) {
if (nr_node->routes[i].neighbour == nr_neigh) {
nr_node->routes[i].quality = quality;
nr_node->routes[i].obs_count = obs_count;
found = 1;
......@@ -157,16 +165,22 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
nr_node->routes[0].quality = quality;
nr_node->routes[0].obs_count = obs_count;
nr_node->routes[0].neighbour = nr_neigh->number;
nr_node->routes[0].neighbour = nr_neigh;
nr_node->which++;
nr_node->count++;
nr_neigh->count++;
} else {
/* It must be better than the worst */
if (quality > nr_node->routes[2].quality) {
nr_node->routes[2].neighbour->count--;
if (nr_node->routes[2].neighbour->count == 0 && !nr_node->routes[2].neighbour->locked)
nr_remove_neigh(nr_node->routes[2].neighbour);
nr_node->routes[2].quality = quality;
nr_node->routes[2].obs_count = obs_count;
nr_node->routes[2].neighbour = nr_neigh->number;
nr_node->routes[2].neighbour = nr_neigh;
nr_neigh->count++;
}
......@@ -212,7 +226,7 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
}
for (i = 0; i < nr_node->count; i++) {
if (nr_node->routes[i].neighbour == nr_neigh->number) {
if (nr_node->routes[i].neighbour == nr_neigh) {
if (i < nr_node->which)
nr_node->which = i;
break;
......@@ -307,7 +321,7 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct d
if (nr_neigh == NULL) return -EINVAL;
for (i = 0; i < nr_node->count; i++) {
if (nr_node->routes[i].neighbour == nr_neigh->number) {
if (nr_node->routes[i].neighbour == nr_neigh) {
nr_neigh->count--;
if (nr_neigh->count == 0 && !nr_neigh->locked)
......@@ -403,7 +417,7 @@ static int nr_del_neigh(ax25_address *callsign, struct device *dev, unsigned int
*/
static int nr_dec_obs(void)
{
struct nr_neigh *t, *nr_neigh;
struct nr_neigh *nr_neigh;
struct nr_node *s, *nr_node;
int i;
......@@ -420,21 +434,12 @@ static int nr_dec_obs(void)
break;
case 1: /* From 1 -> 0 */
nr_neigh = nr_neigh_list;
while (nr_neigh != NULL) {
t = nr_neigh;
nr_neigh = nr_neigh->next;
if (t->number == s->routes[i].neighbour) {
t->count--;
nr_neigh = s->routes[i].neighbour;
nr_neigh->count--;
if (t->count == 0 && !t->locked)
nr_remove_neigh(t);
break;
}
}
if (nr_neigh->count == 0 && !nr_neigh->locked)
nr_remove_neigh(nr_neigh);
s->count--;
......@@ -483,7 +488,7 @@ void nr_rt_device_down(struct device *dev)
nr_node = nr_node->next;
for (i = 0; i < t->count; i++) {
if (t->routes[i].neighbour == s->number) {
if (t->routes[i].neighbour == s) {
t->count--;
switch (i) {
......@@ -609,13 +614,16 @@ int nr_rt_ioctl(unsigned int cmd, void *arg)
case SIOCNRDECOBS:
return nr_dec_obs();
case SIOCNRRTCTL:
if ((err = verify_area(VERIFY_READ, arg, sizeof(int))) != 0)
return err;
opt = get_fs_long((void *)arg);
nr_route_on = opt ? 1 : 0;
return 0;
default:
return -EINVAL;
}
return 0;
......@@ -637,7 +645,7 @@ void nr_link_failed(ax25_address *callsign, struct device *dev)
if (nr_neigh == NULL) return;
for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next)
if (nr_node->which >= nr_node->count && nr_node->routes[nr_node->which].neighbour == nr_neigh->number)
if (nr_node->which < nr_node->count && nr_node->routes[nr_node->which].neighbour == nr_neigh)
nr_node->which++;
}
......@@ -645,7 +653,6 @@ void nr_link_failed(ax25_address *callsign, struct device *dev)
* Route a frame to an appropriate AX.25 connection. A NULL ax25_cb
* indicates an internally generated frame.
*/
int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
{
ax25_address *nr_src, *nr_dest;
......@@ -655,12 +662,12 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
unsigned char *dptr;
#ifdef CONFIG_FIREWALL
if(ax25 && call_in_firewall(PF_NETROM, skb->dev, skb->data, NULL)!=FW_ACCEPT)
if (ax25 != NULL && call_in_firewall(PF_NETROM, skb->dev, skb->data, NULL) != FW_ACCEPT)
return 0;
if(!ax25 && call_out_firewall(PF_NETROM, skb->dev, skb->data, NULL)!=FW_ACCEPT)
if (ax25 == NULL && call_out_firewall(PF_NETROM, skb->dev, skb->data, NULL) != FW_ACCEPT)
return 0;
#endif
nr_src = (ax25_address *)(skb->data + 0);
nr_dest = (ax25_address *)(skb->data + 7);
......@@ -684,27 +691,20 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
if (nr_node == NULL || nr_node->which >= nr_node->count)
return 0;
for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next)
if (nr_neigh->number == nr_node->routes[nr_node->which].neighbour)
break;
if (nr_neigh == NULL)
return 0;
nr_neigh = nr_node->routes[nr_node->which].neighbour;
if ((dev = nr_dev_first()) == NULL)
return 0;
#ifdef CONFIG_FIREWALL
if(ax25 && call_fw_firewall(PF_NETROM, skb->dev, skb->data, NULL)!=FW_ACCEPT)
if (ax25 != NULL && call_fw_firewall(PF_NETROM, skb->dev, skb->data, NULL) != FW_ACCEPT)
return 0;
#endif
dptr = skb_push(skb, 1);
*dptr = AX25_P_NETROM;
ax25_send_frame(skb, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->digipeat, nr_neigh->dev);
return 1;
return ax25_send_frame(skb, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->digipeat, nr_neigh->dev);
}
int nr_nodes_get_info(char *buffer, char **start, off_t offset,
......@@ -715,7 +715,7 @@ int nr_nodes_get_info(char *buffer, char **start, off_t offset,
off_t pos = 0;
off_t begin = 0;
int i;
cli();
len += sprintf(buffer, "callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
......@@ -723,7 +723,7 @@ int nr_nodes_get_info(char *buffer, char **start, off_t offset,
for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next) {
len += sprintf(buffer + len, "%-9s %-7s %d %d",
ax2asc(&nr_node->callsign),
nr_node->mnemonic,
(nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
nr_node->which + 1,
nr_node->count);
......@@ -731,7 +731,7 @@ int nr_nodes_get_info(char *buffer, char **start, off_t offset,
len += sprintf(buffer + len, " %3d %d %05d",
nr_node->routes[i].quality,
nr_node->routes[i].obs_count,
nr_node->routes[i].neighbour);
nr_node->routes[i].neighbour->number);
}
len += sprintf(buffer + len, "\n");
......@@ -742,7 +742,7 @@ int nr_nodes_get_info(char *buffer, char **start, off_t offset,
len = 0;
begin = pos;
}
if (pos > offset + length)
break;
}
......@@ -754,7 +754,7 @@ int nr_nodes_get_info(char *buffer, char **start, off_t offset,
if (len > length) len = length;
return(len);
return len;
}
int nr_neigh_get_info(char *buffer, char **start, off_t offset,
......@@ -764,7 +764,7 @@ int nr_neigh_get_info(char *buffer, char **start, off_t offset,
int len = 0;
off_t pos = 0;
off_t begin = 0;
cli();
len += sprintf(buffer, "addr callsign dev qual lock count\n");
......@@ -796,7 +796,7 @@ int nr_neigh_get_info(char *buffer, char **start, off_t offset,
if (len > length) len = length;
return(len);
return len;
}
#endif
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