Commit 170720a2 authored by Linus Torvalds's avatar Linus Torvalds

Import 0.99.14m

parent 01928531
VERSION = 0.99
PATCHLEVEL = 14
ALPHA = l
ALPHA = m
all: Version zImage
......
......@@ -92,9 +92,8 @@ int el3_probe(struct device *dev)
short *phys_addr = (short *)dev->dev_addr;
static int current_tag = 0;
/* First check for a board on the EISA bus. This first check should
really be in init/main.c, along with a MCA check. */
if (strncmp((char*)0x0FFFD9, "EISA", 4) == 0) {
/* First check for a board on the EISA bus. */
if (EISA_bus) {
for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
if (inw(ioaddr) != 0x6d50)
continue;
......
/* fdomain.c -- Future Domain TMC-16x0 driver
/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
* Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu
* Revised: Sun Oct 31 19:53:49 1993 by faith@cs.unc.edu
* Revised: Tue Jan 4 20:43:57 1994 by faith@cs.unc.edu
* Author: Rickard E. Faith, faith@cs.unc.edu
* Copyright 1992, 1993 Rickard E. Faith
* Copyright 1992, 1993, 1994 Rickard E. Faith
*
* $Id: fdomain.c,v 5.6 1993/11/01 02:40:32 root Exp $
* $Id: fdomain.c,v 5.8 1994/01/05 01:44:16 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
......@@ -144,7 +144,7 @@
#include <linux/string.h>
#include <linux/ioport.h>
#define VERSION "$Revision: 5.6 $"
#define VERSION "$Revision: 5.8 $"
/* START OF USER DEFINABLE OPTIONS */
......@@ -324,7 +324,6 @@ struct signature {
#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
static void print_banner( void )
{
printk( "%s", fdomain_16x0_info() );
......
/* fdomain.h -- Header for Future Domain TMC-16x0 driver
* Created: Sun May 3 18:47:33 1992 by faith@cs.unc.edu
* Revised: Sun Jun 6 11:56:40 1993 by faith@cs.unc.edu
* Revised: Tue Jan 4 20:44:04 1994 by faith@cs.unc.edu
* Author: Rickard E. Faith, faith@cs.unc.edu
* Copyright 1992, 1993 Rickard E. Faith
* Copyright 1992, 1993, 1994 Rickard E. Faith
*
* $Id: fdomain.h,v 5.2 1993/10/24 16:40:41 root Exp $
* $Id: fdomain.h,v 5.3 1994/01/05 01:44:16 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
......
......@@ -58,7 +58,7 @@ extern inline void ins##s(unsigned short port, void * addr, unsigned long count)
: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
#define __OUTS(s) \
extern inline void outs##s(unsigned short port, void * addr, unsigned long count) \
extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
......
......@@ -24,6 +24,7 @@
/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
struct rtentry {
unsigned long rt_hash; /* hash key for lookups */
#define rt_genmask rt_hash
struct sockaddr rt_dst;
struct sockaddr rt_gateway;
short rt_flags;
......
......@@ -290,11 +290,21 @@ extern unsigned long volatile jiffies;
extern struct timeval xtime;
extern int need_resched;
/*
* System setup flags..
*/
extern int hard_math;
extern int x86;
extern int ignore_irq13;
extern int wp_works_ok;
/*
* Bus types (default is ISA, but people can check others with these..)
* MCA_bus hardcoded to 0 for now.
*/
extern int EISA_bus;
#define MCA_bus 0
#define CURRENT_TIME (xtime.tv_sec)
extern void sleep_on(struct wait_queue ** p);
......
......@@ -361,6 +361,8 @@ asmlinkage void start_kernel(void)
}
low_memory_start = PAGE_ALIGN(low_memory_start);
memory_start = paging_init(memory_start,memory_end);
if (strncmp((char*)0x0FFFD9, "EISA", 4) == 0)
EISA_bus = 1;
trap_init();
init_IRQ();
sched_init();
......
......@@ -67,6 +67,11 @@ int x86 = 0; /* set by boot/head.S to 3 or 4 */
int ignore_irq13 = 0; /* set if exception 16 works */
int wp_works_ok = 0; /* set if paging hardware honours WP */
/*
* Bus types ..
*/
int EISA_bus = 0;
extern int _setitimer(int, struct itimerval *, struct itimerval *);
unsigned long * prof_buffer = NULL;
unsigned long prof_len = 0;
......
......@@ -780,6 +780,17 @@ dev_get_info(char *buffer)
return pos - buffer;
}
static inline int bad_mask(unsigned long mask, unsigned long addr)
{
if (addr & (mask = ~mask))
return 1;
mask = ntohl(mask);
if (mask & (mask+1))
return 1;
return 0;
}
/* Perform the SIOCxIFxxx calls. */
static int
dev_ifsioc(void *arg, unsigned int getset)
......@@ -878,11 +889,16 @@ dev_ifsioc(void *arg, unsigned int getset)
memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
ret = 0;
break;
case SIOCSIFNETMASK:
dev->pa_mask = (*(struct sockaddr_in *)
&ifr.ifr_netmask).sin_addr.s_addr;
case SIOCSIFNETMASK: {
unsigned long mask = (*(struct sockaddr_in *)
&ifr.ifr_netmask).sin_addr.s_addr;
ret = -EINVAL;
if (bad_mask(mask,0))
break;
dev->pa_mask = mask;
ret = 0;
break;
}
case SIOCGIFMETRIC:
ifr.ifr_metric = dev->metric;
memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
......@@ -970,9 +986,9 @@ dev_ioctl(unsigned int cmd, void *arg)
return retval;
printk("%s: adding HOST route of %8.8lx.\n", dev->name,
htonl(ipc.paddr));
rt_add(RTF_HOST, ipc.paddr, 0, dev);
rt_add(RTF_HOST, ipc.paddr, 0, 0, dev);
if (ipc.router != 0 && ipc.router != -1) {
rt_add(RTF_GATEWAY, ipc.paddr, ipc.router, dev);
rt_add(RTF_GATEWAY, ipc.paddr, 0, ipc.router, dev);
printk("%s: adding GATEWAY route of %8.8lx.\n",
dev->name, htonl(ipc.paddr));
......
......@@ -211,11 +211,11 @@ icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev)
switch(icmph->code & 7) {
case ICMP_REDIR_NET:
rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY),
ip, icmph->un.gateway, dev);
ip, 0, icmph->un.gateway, dev);
break;
case ICMP_REDIR_HOST:
rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_HOST | RTF_GATEWAY),
ip, icmph->un.gateway, dev);
ip, 0, icmph->un.gateway, dev);
break;
case ICMP_REDIR_NETTOS:
case ICMP_REDIR_HOSTTOS:
......
......@@ -115,39 +115,41 @@ void rt_flush(struct device *dev)
}
/*
* Used by 'rt_add()' when we can't get the netmask from the device..
* Used by 'rt_add()' when we can't get the netmask any other way..
*
* If the lower byte or two are zero, we guess the mask based on the
* number of zero 8-bit net numbers, otherwise we use the "default"
* masks judging by the destination address.
*
* We should really use masks everywhere, but the current system
* interface for adding routes doesn't even contain a netmask field.
* Similarly, ICMP redirect messages contain only the address to
* redirect.. Anyway, this function should give reasonable values
* for almost anything.
* masks judging by the destination address and our device netmask.
*/
static unsigned long guess_mask(unsigned long dst)
static unsigned long guess_mask(unsigned long dst, struct device * dev)
{
unsigned long mask = 0xffffffff;
while (mask & dst)
mask <<= 8;
mask >>= 8;
if (mask)
return ~mask;
dst = ntohl(dst);
if (IN_CLASSA(dst))
return htonl(IN_CLASSA_NET);
if (IN_CLASSB(dst))
return htonl(IN_CLASSB_NET);
return htonl(IN_CLASSC_NET);
mask = htonl(IN_CLASSA_NET);
else if (IN_CLASSB(dst))
mask = htonl(IN_CLASSB_NET);
else
mask = htonl(IN_CLASSC_NET);
if (dev->flags & IFF_POINTOPOINT)
return mask;
if ((dst ^ dev->pa_addr) & mask)
return mask;
return dev->pa_mask;
}
static inline struct device * get_gw_dev(unsigned long gw)
{
struct rtable * rt;
for (rt = rt_base ; rt ; rt = rt->rt_next) {
for (rt = rt_base ; ; rt = rt->rt_next) {
if (!rt)
return NULL;
if ((gw ^ rt->rt_dst) & rt->rt_mask)
continue;
/* gateways behind gateways are a no-no */
......@@ -155,23 +157,21 @@ static inline struct device * get_gw_dev(unsigned long gw)
return NULL;
return rt->rt_dev;
}
return NULL;
}
/*
* rewrote rt_add(), as the old one was weird. Linus
*/
void
rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
rt_add(short flags, unsigned long dst, unsigned long mask, unsigned long gw, struct device *dev)
{
struct rtable *r, *rt;
struct rtable **rp;
unsigned long mask;
unsigned long cpuflags;
if (flags & RTF_HOST) {
mask = 0xffffffff;
} else {
} else if (!mask) {
if (!((dst ^ dev->pa_addr) & dev->pa_mask)) {
mask = dev->pa_mask;
flags &= ~RTF_GATEWAY;
......@@ -180,7 +180,7 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
return;
}
} else
mask = guess_mask(dst);
mask = guess_mask(dst, dev);
dst &= mask;
}
if (gw == dev->pa_addr)
......@@ -239,44 +239,44 @@ rt_add(short flags, unsigned long dst, unsigned long gw, struct device *dev)
return;
}
static int
rt_new(struct rtentry *r)
static inline int bad_mask(unsigned long mask, unsigned long addr)
{
struct device *dev;
if (addr & (mask = ~mask))
return 1;
mask = ntohl(mask);
if (mask & (mask+1))
return 1;
return 0;
}
if ((r->rt_dst.sa_family != AF_INET) ||
(r->rt_gateway.sa_family != AF_INET)) {
DPRINTF((DBG_RT, "RT: We only know about AF_INET !\n"));
return(-EAFNOSUPPORT);
}
static int rt_new(struct rtentry *r)
{
struct device *dev;
unsigned long flags, daddr, mask, gw;
/*
* I admit that the following bits of code were "inspired" by
* the Berkeley UNIX system source code. I could think of no
* other way to find out how to make it compatible with it (I
* want this to be compatible to get "routed" up and running).
* -FvK
*/
if (r->rt_dst.sa_family != AF_INET)
return -EAFNOSUPPORT;
/* If we have a 'gateway' route here, check the correct address. */
if (!(r->rt_flags & RTF_GATEWAY))
dev = dev_check(((struct sockaddr_in *) &r->rt_dst)->sin_addr.s_addr);
else
dev = get_gw_dev(((struct sockaddr_in *) &r->rt_gateway)->sin_addr.s_addr);
flags = r->rt_flags;
daddr = ((struct sockaddr_in *) &r->rt_dst)->sin_addr.s_addr;
mask = r->rt_genmask;
gw = ((struct sockaddr_in *) &r->rt_gateway)->sin_addr.s_addr;
DPRINTF((DBG_RT, "RT: dev for %s gw ",
in_ntoa((*(struct sockaddr_in *)&r->rt_dst).sin_addr.s_addr)));
DPRINTF((DBG_RT, "%s (0x%04X) is 0x%X (%s)\n",
in_ntoa((*(struct sockaddr_in *)&r->rt_gateway).sin_addr.s_addr),
r->rt_flags, dev, (dev == NULL) ? "NONE" : dev->name));
if (flags & RTF_GATEWAY) {
if (r->rt_gateway.sa_family != AF_INET)
return -EAFNOSUPPORT;
dev = get_gw_dev(gw);
} else
dev = dev_check(daddr);
if (dev == NULL) return(-ENETUNREACH);
if (dev == NULL)
return -ENETUNREACH;
rt_add(r->rt_flags, (*(struct sockaddr_in *) &r->rt_dst).sin_addr.s_addr,
(*(struct sockaddr_in *) &r->rt_gateway).sin_addr.s_addr, dev);
if (bad_mask(mask, daddr))
mask = 0;
return(0);
rt_add(flags, daddr, mask, gw, dev);
return 0;
}
......
......@@ -37,7 +37,7 @@ struct rtable {
extern void rt_flush(struct device *dev);
extern void rt_add(short flags, unsigned long addr,
extern void rt_add(short flags, unsigned long addr, unsigned long mask,
unsigned long gw, struct device *dev);
extern struct rtable *rt_route(unsigned long daddr, struct options *opt);
extern int rt_get_info(char * buffer);
......
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