Commit c2700b1f authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.16

parent 7eb2fd0c
VERSION = 1 VERSION = 1
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 15 SUBLEVEL = 16
all: Version zImage all: Version zImage
......
This diff is collapsed.
...@@ -482,6 +482,10 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) ...@@ -482,6 +482,10 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
put_tty_queue(c, tty); put_tty_queue(c, tty);
tty->canon_head = tty->read_head; tty->canon_head = tty->read_head;
tty->canon_data++; tty->canon_data++;
if (tty->fasync)
kill_fasync(tty->fasync, SIGIO);
if (tty->read_wait)
wake_up_interruptible(&tty->read_wait);
return; return;
} }
} }
...@@ -560,8 +564,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, unsigned char *cp, ...@@ -560,8 +564,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, unsigned char *cp,
tty->driver.flush_chars(tty); tty->driver.flush_chars(tty);
} }
if (tty->icanon ? tty->canon_data : if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
(tty->read_cnt >= tty->minimum_to_wake)) {
if (tty->fasync) if (tty->fasync)
kill_fasync(tty->fasync, SIGIO); kill_fasync(tty->fasync, SIGIO);
if (tty->read_wait) if (tty->read_wait)
......
...@@ -1006,8 +1006,8 @@ static void shutdown(struct async_struct * info) ...@@ -1006,8 +1006,8 @@ static void shutdown(struct async_struct * info)
cli(); cli();
if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
info->MCR &= ~UART_MCR_DTR; info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
info->MCR_noint &= ~UART_MCR_DTR; info->MCR_noint &= ~(UART_MCR_DTR|UART_MCR_RTS);
} }
serial_outp(info, UART_MCR, info->MCR_noint); serial_outp(info, UART_MCR, info->MCR_noint);
......
...@@ -302,7 +302,7 @@ static char *format_names[] = { ...@@ -302,7 +302,7 @@ static char *format_names[] = {
* Exception 16 (BOM) is added for beginning-of-media (catch BOM). * Exception 16 (BOM) is added for beginning-of-media (catch BOM).
*/ */
static struct exception_list_type { static struct exception_list_type {
short mask, code; unsigned short mask, code;
char *msg; char *msg;
} exception_list[] = { } exception_list[] = {
{0, 0, {0, 0,
...@@ -1008,7 +1008,7 @@ static int ll_do_qic_cmd(int cmd, time_t timeout) ...@@ -1008,7 +1008,7 @@ static int ll_do_qic_cmd(int cmd, time_t timeout)
stat = TE_OK; stat = TE_OK;
} }
if (stat != TE_OK) { if (stat != TE_OK) {
printk(TPQIC_NAME ": ll_do_qic_cmd(%x, %d) failed\n", cmd, timeout); printk(TPQIC_NAME ": ll_do_qic_cmd(%x, %ld) failed\n", cmd, timeout);
return -EIO; return -EIO;
} }
...@@ -1044,7 +1044,7 @@ static int ll_do_qic_cmd(int cmd, time_t timeout) ...@@ -1044,7 +1044,7 @@ static int ll_do_qic_cmd(int cmd, time_t timeout)
/* sense() will set eof/eom as required */ /* sense() will set eof/eom as required */
if (stat==TE_EX) { if (stat==TE_EX) {
if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK) { if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK) {
printk(TPQIC_NAME ": Exception persist in ll_do_qic_cmd[1](%x, %d)", cmd, timeout); printk(TPQIC_NAME ": Exception persist in ll_do_qic_cmd[1](%x, %ld)", cmd, timeout);
status_dead = YES; status_dead = YES;
return -ENXIO; return -ENXIO;
/* if rdstatus fails too, we're in trouble */ /* if rdstatus fails too, we're in trouble */
...@@ -1065,7 +1065,7 @@ static int ll_do_qic_cmd(int cmd, time_t timeout) ...@@ -1065,7 +1065,7 @@ static int ll_do_qic_cmd(int cmd, time_t timeout)
if (tp_sense((cmd==QCMD_SEEK_EOD ? /*****************************/ if (tp_sense((cmd==QCMD_SEEK_EOD ? /*****************************/
TP_EOR|TP_NDT|TP_UDA|TP_BNL|TP_WRP|TP_BOM|TP_EOM|TP_FIL : TP_EOR|TP_NDT|TP_UDA|TP_BNL|TP_WRP|TP_BOM|TP_EOM|TP_FIL :
TP_WRP|TP_BOM|TP_EOM|TP_FIL))!=TE_OK) { TP_WRP|TP_BOM|TP_EOM|TP_FIL))!=TE_OK) {
printk(TPQIC_NAME ": Exception persist in ll_do_qic_cmd[2](%x, %d)\n", cmd, timeout); printk(TPQIC_NAME ": Exception persist in ll_do_qic_cmd[2](%x, %ld)\n", cmd, timeout);
if (cmd!=QCMD_RD_FM) if (cmd!=QCMD_RD_FM)
status_dead = YES; status_dead = YES;
return -ENXIO; return -ENXIO;
...@@ -1816,7 +1816,7 @@ static int tape_qic02_read(struct inode * inode, struct file * filp, char * buf, ...@@ -1816,7 +1816,7 @@ static int tape_qic02_read(struct inode * inode, struct file * filp, char * buf,
int stat; int stat;
if (TP_DIAGS(current_tape_dev)) if (TP_DIAGS(current_tape_dev))
printk(TPQIC_NAME ": request READ, minor=%x, buf=%p, count=%x, pos=%x, flags=%x\n", printk(TPQIC_NAME ": request READ, minor=%x, buf=%p, count=%x, pos=%lx, flags=%x\n",
MINOR(dev), buf, count, filp->f_pos, flags); MINOR(dev), buf, count, filp->f_pos, flags);
if (count % TAPE_BLKSIZE) { /* Only allow mod 512 bytes at a time. */ if (count % TAPE_BLKSIZE) { /* Only allow mod 512 bytes at a time. */
...@@ -1849,7 +1849,7 @@ static int tape_qic02_read(struct inode * inode, struct file * filp, char * buf, ...@@ -1849,7 +1849,7 @@ static int tape_qic02_read(struct inode * inode, struct file * filp, char * buf,
/* Must ensure that user program sees exactly one EOF token (==0) */ /* Must ensure that user program sees exactly one EOF token (==0) */
if (return_read_eof==YES) { if (return_read_eof==YES) {
printk("read: return_read_eof==%d, reported_read_eof==%d, total_bytes_done==%d\n", return_read_eof, reported_read_eof, total_bytes_done); printk("read: return_read_eof==%d, reported_read_eof==%d, total_bytes_done==%ld\n", return_read_eof, reported_read_eof, total_bytes_done);
if (reported_read_eof==NO) { if (reported_read_eof==NO) {
/* have not yet returned EOF to user program */ /* have not yet returned EOF to user program */
...@@ -1985,7 +1985,7 @@ static int tape_qic02_write(struct inode * inode, struct file * filp, char * buf ...@@ -1985,7 +1985,7 @@ static int tape_qic02_write(struct inode * inode, struct file * filp, char * buf
unsigned long bytes_todo, bytes_done, total_bytes_done = 0; unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
if (TP_DIAGS(current_tape_dev)) if (TP_DIAGS(current_tape_dev))
printk(TPQIC_NAME ": request WRITE, minor=%x, buf=%p, count=%x, pos=%x, flags=%x\n", printk(TPQIC_NAME ": request WRITE, minor=%x, buf=%p, count=%x, pos=%lx, flags=%x\n",
MINOR(dev), buf, count, filp->f_pos, flags); MINOR(dev), buf, count, filp->f_pos, flags);
if (count % TAPE_BLKSIZE) { /* only allow mod 512 bytes at a time */ if (count % TAPE_BLKSIZE) { /* only allow mod 512 bytes at a time */
...@@ -2107,7 +2107,7 @@ static int tape_qic02_write(struct inode * inode, struct file * filp, char * buf ...@@ -2107,7 +2107,7 @@ static int tape_qic02_write(struct inode * inode, struct file * filp, char * buf
} }
} }
tpqputs("write request for <0 bytes"); tpqputs("write request for <0 bytes");
printk(TPQIC_NAME ": status_bytes_wr %x, buf %p, total_bytes_done %x, count %x\n", status_bytes_wr, buf, total_bytes_done, count); printk(TPQIC_NAME ": status_bytes_wr %x, buf %p, total_bytes_done %lx, count %x\n", status_bytes_wr, buf, total_bytes_done, count);
return -EINVAL; return -EINVAL;
} /* tape_qic02_write */ } /* tape_qic02_write */
...@@ -2337,7 +2337,7 @@ static int tape_qic02_ioctl(struct inode * inode, struct file * filp, ...@@ -2337,7 +2337,7 @@ static int tape_qic02_ioctl(struct inode * inode, struct file * filp,
#endif #endif
if (TP_DIAGS(current_tape_dev)) if (TP_DIAGS(current_tape_dev))
printk(TPQIC_NAME ": ioctl(%4x, %4x, %4x)\n", dev_maj, iocmd, ioarg); printk(TPQIC_NAME ": ioctl(%4x, %4x, %4lx)\n", dev_maj, iocmd, ioarg);
if (!inode || !ioarg) if (!inode || !ioarg)
return -EINVAL; return -EINVAL;
......
...@@ -180,18 +180,18 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc) ...@@ -180,18 +180,18 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty->termios->c_line = ldisc; tty->termios->c_line = ldisc;
if (tty->ldisc.open) { if (tty->ldisc.open) {
retval = (tty->ldisc.open)(tty); retval = (tty->ldisc.open)(tty);
if (!retval) if (retval >= 0)
return 0; return retval;
tty->ldisc = o_ldisc; tty->ldisc = o_ldisc;
tty->termios->c_line = tty->ldisc.num; tty->termios->c_line = tty->ldisc.num;
if (tty->ldisc.open && tty->ldisc.open(tty)) { if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
tty->ldisc = ldiscs[N_TTY]; tty->ldisc = ldiscs[N_TTY];
tty->termios->c_line = N_TTY; tty->termios->c_line = N_TTY;
if (tty->ldisc.open) { if (tty->ldisc.open) {
int r = tty->ldisc.open(tty); int r = tty->ldisc.open(tty);
if (r) if (r < 0)
panic("Couldn't open N_TTY ldisc for " panic("Couldn't open N_TTY ldisc for "
"%s --- error %d.", "%s --- error %d.",
tty_name(tty), r); tty_name(tty), r);
...@@ -344,9 +344,9 @@ void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops) ...@@ -344,9 +344,9 @@ void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
tty->termios->c_line = N_TTY; tty->termios->c_line = N_TTY;
if (tty->ldisc.open) { if (tty->ldisc.open) {
i = (tty->ldisc.open)(tty); i = (tty->ldisc.open)(tty);
if (i) if (i < 0)
printk("do_tty_hangup: N_TTY open: error %d\n", printk("do_tty_hangup: N_TTY open: error %d\n",
i); -i);
} }
} }
...@@ -815,7 +815,7 @@ static int init_dev(dev_t device, struct tty_struct **ret_tty) ...@@ -815,7 +815,7 @@ static int init_dev(dev_t device, struct tty_struct **ret_tty)
(*driver->refcount)++; (*driver->refcount)++;
if (tty->ldisc.open) { if (tty->ldisc.open) {
retval = (tty->ldisc.open)(tty); retval = (tty->ldisc.open)(tty);
if (retval) if (retval < 0)
goto end_init; goto end_init;
} }
tty = NULL; tty = NULL;
...@@ -836,7 +836,7 @@ static int init_dev(dev_t device, struct tty_struct **ret_tty) ...@@ -836,7 +836,7 @@ static int init_dev(dev_t device, struct tty_struct **ret_tty)
(*driver->other->refcount)++; (*driver->other->refcount)++;
if (o_tty->ldisc.open) { if (o_tty->ldisc.open) {
retval = (o_tty->ldisc.open)(o_tty); retval = (o_tty->ldisc.open)(o_tty);
if (retval) if (retval < 0)
goto end_init; goto end_init;
} }
o_tty = NULL; o_tty = NULL;
......
...@@ -41,6 +41,11 @@ static char *version = ...@@ -41,6 +41,11 @@ static char *version =
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#ifdef MODULE
#include <linux/module.h>
#include "../../tools/version.h"
#endif
#ifndef HAVE_AUTOIRQ #ifndef HAVE_AUTOIRQ
/* From auto_irq.c, should be in a *.h file. */ /* From auto_irq.c, should be in a *.h file. */
extern void autoirq_setup(int waittime); extern void autoirq_setup(int waittime);
...@@ -223,6 +228,9 @@ el_open(struct device *dev) ...@@ -223,6 +228,9 @@ el_open(struct device *dev)
outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */ outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */
if (el_debug > 2) if (el_debug > 2)
printk("finished el_open().\n"); printk("finished el_open().\n");
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
return (0); return (0);
} }
...@@ -463,6 +471,9 @@ el1_close(struct device *dev) ...@@ -463,6 +471,9 @@ el1_close(struct device *dev)
outb(AX_RESET, AX_CMD); /* Reset the chip */ outb(AX_RESET, AX_CMD); /* Reset the chip */
irq2dev_map[dev->irq] = 0; irq2dev_map[dev->irq] = 0;
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
return 0; return 0;
} }
...@@ -499,3 +510,31 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs) ...@@ -499,3 +510,31 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
* kept-new-versions: 5 * kept-new-versions: 5
* End: * End:
*/ */
#ifdef MODULE
char kernel_version[] = UTS_RELEASE;
static struct device dev_3c501 = {
"" /*"3c501"*/,
0, 0, 0, 0,
0x280, 7,
0, 0, 0, NULL, el1_probe };
int
init_module(void)
{
if (register_netdev(&dev_3c501) != 0)
return -EIO;
return 0;
}
void
cleanup_module(void)
{
if (MOD_IN_USE)
printk("3c501: device busy, remove delayed\n");
else
{
unregister_netdev(&dev_3c501);
}
}
#endif /* MODULE */
MODULES = \ MODULES = \
3c509.o \ 3c509.o \
de600.o de600.o \
3c501.o \
plip.o
...@@ -74,6 +74,14 @@ slip.o: slip.c CONFIG ...@@ -74,6 +74,14 @@ slip.o: slip.c CONFIG
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< $(CC) $(CPPFLAGS) $(CFLAGS) -c $<
endif endif
ifdef CONFIG_DE650
NETDRV_OBJS := $(NETDRV_OBJS) net.a(de650.o)
CONFIG_8390 = CONFIG_8390
endif
ifdef CONFIG_3C589
NETDRV_OBJS := $(NETDRV_OBJS) net.a(3c589.o)
endif
ifdef CONFIG_DE600 ifdef CONFIG_DE600
NETDRV_OBJS := $(NETDRV_OBJS) net.a(de600.o) NETDRV_OBJS := $(NETDRV_OBJS) net.a(de600.o)
endif endif
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/errno.h>
#define LOOPBACK /* always present, right? */ #define LOOPBACK /* always present, right? */
...@@ -123,6 +124,39 @@ ethif_probe(struct device *dev) ...@@ -123,6 +124,39 @@ ethif_probe(struct device *dev)
return 0; return 0;
} }
#ifdef CONFIG_PCMCIA_NET
extern int dl_open(struct device *dev);
extern int tc589_open(struct device *dev);
extern int ibmccae_open(struct device *dev);
static int pc_eth_open(struct device *dev);
static int pc_eth_probe(struct device *dev)
{
dev->open = &pc_eth_open;
dev->set_config = &ether_config;
dev->tbusy = 1;
return 0;
}
static int pc_eth_open(struct device *dev)
{
if (1
#ifdef CONFIG_DE650
&& dl_open(dev)
#endif
#ifdef CONFIG_3C589
&& tc589_open(dev)
#endif
#ifdef CONFIG_IBMCCAE
&& ibmccae_open(dev)
#endif
&& 1)
return -ENODEV;
else
return 0;
}
#endif /* CONFIG_PCMCIA_NET */
/* Run-time ATtachable (Pocket) devices have a different (not "eth#") name. */ /* Run-time ATtachable (Pocket) devices have a different (not "eth#") name. */
#ifdef CONFIG_ATP /* AT-LAN-TEC (RealTek) pocket adaptor. */ #ifdef CONFIG_ATP /* AT-LAN-TEC (RealTek) pocket adaptor. */
...@@ -132,6 +166,17 @@ static struct device atp_dev = { ...@@ -132,6 +166,17 @@ static struct device atp_dev = {
# define NEXT_DEV (&atp_dev) # define NEXT_DEV (&atp_dev)
#endif #endif
#ifdef CONFIG_PCMCIA_NET
static struct device pc_eth1_dev = {
"pc_eth1", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, pc_eth_probe,
};
static struct device pc_eth0_dev = {
"pc_eth0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &pc_eth1_dev, pc_eth_probe,
};
# undef NEXT_DEV
# define NEXT_DEV (&pc_eth0_dev)
#endif /* CONFIG_PCMCIA_NET */
/* The first device defaults to I/O base '0', which means autoprobe. */ /* The first device defaults to I/O base '0', which means autoprobe. */
#ifndef ETH0_ADDR #ifndef ETH0_ADDR
# define ETH0_ADDR 0 # define ETH0_ADDR 0
......
...@@ -165,6 +165,23 @@ void ether_setup(struct device *dev) ...@@ -165,6 +165,23 @@ void ether_setup(struct device *dev)
dev->pa_alen = sizeof(unsigned long); dev->pa_alen = sizeof(unsigned long);
} }
int ether_config(struct device *dev, struct ifmap *map)
{
if (map->mem_start != (u_long)(-1))
dev->mem_start = map->mem_start;
if (map->mem_end != (u_long)(-1))
dev->mem_end = map->mem_end;
if (map->base_addr != (u_short)(-1))
dev->base_addr = map->base_addr;
if (map->irq != (u_char)(-1))
dev->irq = map->irq;
if (map->dma != (u_char)(-1))
dev->dma = map->dma;
if (map->port != (u_char)(-1))
dev->if_port = map->port;
return 0;
}
int register_netdev(struct device *dev) int register_netdev(struct device *dev)
{ {
struct device *d = dev_base; struct device *d = dev_base;
......
...@@ -17,7 +17,9 @@ ...@@ -17,7 +17,9 @@
* Tested this against ncsa-telnet 2.3 and pcip_pkt using plip.com (which * Tested this against ncsa-telnet 2.3 and pcip_pkt using plip.com (which
* contains "version equ 0" and ";History:562,1" in the firts 2 * contains "version equ 0" and ";History:562,1" in the firts 2
* source-lines 28-Mar-94 * source-lines 28-Mar-94
* *
* Modularised it (Alan Cox). Will upgrade to Niibe's PLIP once its settled
* down better.
* *
* *
* This is parallel port packet pusher. It's actually more general * This is parallel port packet pusher. It's actually more general
...@@ -40,10 +42,17 @@ ...@@ -40,10 +42,17 @@
* Info: * Info:
* I <Alan> got 15K/second NFS throughput (about 20-25K second IP). I also got some ethernet cards * I <Alan> got 15K/second NFS throughput (about 20-25K second IP). I also got some ethernet cards
* so don't ask me for help. This code needs a real major rewrite. Any volunteers ? * so don't ask me for help. This code needs a real major rewrite. Any volunteers ?
*
***** So we can all compare loads of different PLIP drivers for a bit I've modularised this beastie too.
***** In addition a seperate bidirectional plip module can be done.
*/ */
static char *version = static char *version =
"NET3 PLIP.010 (from plip.c:v0.15 for 0.99pl12+, 8/11/93)\n"; "NET3 "
#ifdef MODULE
"MODULAR "
#endif
"PLIP.010 (from plip.c:v0.15 for 0.99pl12+, 8/11/93)\n";
#include <linux/config.h> #include <linux/config.h>
...@@ -95,6 +104,11 @@ make one yourself. The wiring is: ...@@ -95,6 +104,11 @@ make one yourself. The wiring is:
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#ifdef MODULE
#include <linux/module.h>
#include "../../tools/version.h"
#endif
#ifdef PRINTK #ifdef PRINTK
#undef PRINTK #undef PRINTK
#endif #endif
...@@ -219,8 +233,8 @@ plip_init(struct device *dev) ...@@ -219,8 +233,8 @@ plip_init(struct device *dev)
This routine gets exclusive access to the parallel port by allocating This routine gets exclusive access to the parallel port by allocating
its IRQ line. its IRQ line.
*/ */
static int
plip_open(struct device *dev) static int plip_open(struct device *dev)
{ {
if (dev->irq == 0) if (dev->irq == 0)
dev->irq = 7; dev->irq = 7;
...@@ -237,6 +251,9 @@ plip_open(struct device *dev) ...@@ -237,6 +251,9 @@ plip_open(struct device *dev)
dev->tbusy = 0; dev->tbusy = 0;
dev->interrupt = 0; dev->interrupt = 0;
dev->start = 1; dev->start = 1;
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
return 0; return 0;
} }
...@@ -251,6 +268,9 @@ plip_close(struct device *dev) ...@@ -251,6 +268,9 @@ plip_close(struct device *dev)
irq2dev_map[dev->irq] = NULL; irq2dev_map[dev->irq] = NULL;
sti(); sti();
outb(0x00, dev->base_addr); /* Release the interrupt. */ outb(0x00, dev->base_addr); /* Release the interrupt. */
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
return 0; return 0;
} }
...@@ -746,3 +766,76 @@ plip_get_stats(struct device *dev) ...@@ -746,3 +766,76 @@ plip_get_stats(struct device *dev)
* kept-new-versions: 5 * kept-new-versions: 5
* End: * End:
*/ */
#ifdef MODULE
char kernel_version[] = UTS_RELEASE;
static struct device dev_plip0 =
{
"plip0" /*"plip"*/,
0, 0, 0, 0, /* memory */
0x3BC, 5, /* base, irq */
0, 0, 0, NULL, plip_init
};
static struct device dev_plip1 =
{
"plip1" /*"plip"*/,
0, 0, 0, 0, /* memory */
0x378, 7, /* base, irq */
0, 0, 0, NULL, plip_init
};
static struct device dev_plip2 =
{
"plip2" /*"plip"*/,
0, 0, 0, 0, /* memory */
0x278, 2, /* base, irq */
0, 0, 0, NULL, plip_init
};
int
init_module(void)
{
int err;
if ( ((err=register_netdev(&dev_plip0)) == 0) &&
((err=register_netdev(&dev_plip1)) == 0) &&
((err=register_netdev(&dev_plip2)) == 0)
)
{
if(err==-EEXIST)
printk("plip devices already present. Module not loaded.\n");
return err;
}
return 0;
}
void
cleanup_module(void)
{
if (MOD_IN_USE)
printk("plip: device busy, remove delayed\n");
else
{
unregister_netdev(&dev_plip0);
if(dev_plip0.priv)
{
kfree_s(dev_plip0.priv,sizeof(struct netstats));
dev_plip0.priv=NULL;
}
unregister_netdev(&dev_plip1);
if(dev_plip1.priv)
{
kfree_s(dev_plip1.priv,sizeof(struct netstats));
dev_plip0.priv=NULL;
}
unregister_netdev(&dev_plip2);
if(dev_plip2.priv)
{
kfree_s(dev_plip2.priv,sizeof(struct netstats));
dev_plip2.priv=NULL;
}
}
}
#endif /* MODULE */
...@@ -377,9 +377,9 @@ ppp_changedmtu (struct ppp *ppp, int new_mtu, int new_mru) ...@@ -377,9 +377,9 @@ ppp_changedmtu (struct ppp *ppp, int new_mtu, int new_mru)
PRINTKN (2,(KERN_INFO "ppp: channel %s mtu = %d, mru = %d\n", PRINTKN (2,(KERN_INFO "ppp: channel %s mtu = %d, mru = %d\n",
dev->name, new_mtu, new_mru)); dev->name, new_mtu, new_mru));
new_xbuff = (unsigned char *) kmalloc(mtu + 4, GFP_KERNEL); new_xbuff = (unsigned char *) kmalloc(mtu + 4, GFP_ATOMIC);
new_rbuff = (unsigned char *) kmalloc(mru + 4, GFP_KERNEL); new_rbuff = (unsigned char *) kmalloc(mru + 4, GFP_ATOMIC);
new_cbuff = (unsigned char *) kmalloc(mru + 4, GFP_KERNEL); new_cbuff = (unsigned char *) kmalloc(mru + 4, GFP_ATOMIC);
/* /*
* If the buffers failed to allocate then complain. * If the buffers failed to allocate then complain.
*/ */
...@@ -558,11 +558,7 @@ ppp_open(struct tty_struct *tty) ...@@ -558,11 +558,7 @@ ppp_open(struct tty_struct *tty)
PRINTKN (2,(KERN_INFO "ppp: channel %s open\n", ppp->dev->name)); PRINTKN (2,(KERN_INFO "ppp: channel %s open\n", ppp->dev->name));
#ifdef NEW_TTY_DRIVERS
return (0);
#else
return (ppp->line); return (ppp->line);
#endif
} }
/* called when ppp interface goes "up". here this just means we start /* called when ppp interface goes "up". here this just means we start
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
* Renamed "route_get_info()" to "rt_get_info()" for consistency. * Renamed "route_get_info()" to "rt_get_info()" for consistency.
* Alan Cox (gw4pts@gw4pts.ampr.org) 4/94 * Alan Cox (gw4pts@gw4pts.ampr.org) 4/94
* Dusted off the code and added IPX. Fixed the 4K limit. * Dusted off the code and added IPX. Fixed the 4K limit.
* Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
* /proc/net/snmp.
* *
* proc net directory handling functions * proc net directory handling functions
*/ */
...@@ -47,6 +49,7 @@ extern int arp_get_info(char *, char **, off_t, int); ...@@ -47,6 +49,7 @@ extern int arp_get_info(char *, char **, off_t, int);
extern int rarp_get_info(char *, char **, off_t, int); extern int rarp_get_info(char *, char **, off_t, int);
extern int dev_get_info(char *, char **, off_t, int); extern int dev_get_info(char *, char **, off_t, int);
extern int rt_get_info(char *, char **, off_t, int); extern int rt_get_info(char *, char **, off_t, int);
extern int snmp_get_info(char *, char **, off_t, int);
#endif /* CONFIG_INET */ #endif /* CONFIG_INET */
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
extern int ipx_get_info(char *, char **, off_t, int); extern int ipx_get_info(char *, char **, off_t, int);
...@@ -107,22 +110,23 @@ static struct proc_dir_entry net_dir[] = { ...@@ -107,22 +110,23 @@ static struct proc_dir_entry net_dir[] = {
{ 131,3,"dev" }, { 131,3,"dev" },
{ 132,3,"raw" }, { 132,3,"raw" },
{ 133,3,"tcp" }, { 133,3,"tcp" },
{ 134,3,"udp" } { 134,3,"udp" },
{ 135,4,"snmp" }
#ifdef CONFIG_INET_RARP #ifdef CONFIG_INET_RARP
,{ 135,4,"rarp"} ,{ 136,4,"rarp"}
#endif #endif
#endif /* CONFIG_INET */ #endif /* CONFIG_INET */
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
,{ 136,9,"ipx_route" }, ,{ 137,9,"ipx_route" },
{ 137,3,"ipx" } { 138,3,"ipx" }
#endif /* CONFIG_IPX */ #endif /* CONFIG_IPX */
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
,{ 138,10,"ax25_route" }, ,{ 139,10,"ax25_route" },
{ 139,4,"ax25" } { 140,4,"ax25" }
#ifdef CONFIG_NETROM #ifdef CONFIG_NETROM
,{ 140,8,"nr_nodes" }, ,{ 141,8,"nr_nodes" },
{ 141,8,"nr_neigh" }, { 142,8,"nr_neigh" },
{ 142,2,"nr" } { 143,2,"nr" }
#endif /* CONFIG_NETROM */ #endif /* CONFIG_NETROM */
#endif /* CONFIG_AX25 */ #endif /* CONFIG_AX25 */
}; };
...@@ -235,35 +239,38 @@ static int proc_readnet(struct inode * inode, struct file * file, ...@@ -235,35 +239,38 @@ static int proc_readnet(struct inode * inode, struct file * file,
case 134: case 134:
length = udp_get_info(page,&start,file->f_pos,thistime); length = udp_get_info(page,&start,file->f_pos,thistime);
break; break;
#ifdef CONFIG_INET_RARP
case 135: case 135:
length = snmp_get_info(page, &start, file->f_pos,thistime);
break;
#ifdef CONFIG_INET_RARP
case 136:
length = rarp_get_info(page,&start,file->f_pos,thistime); length = rarp_get_info(page,&start,file->f_pos,thistime);
break; break;
#endif /* CONFIG_INET_RARP */ #endif /* CONFIG_INET_RARP */
#endif /* CONFIG_INET */ #endif /* CONFIG_INET */
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
case 136: case 137:
length = ipx_rt_get_info(page,&start,file->f_pos,thistime); length = ipx_rt_get_info(page,&start,file->f_pos,thistime);
break; break;
case 137: case 138:
length = ipx_get_info(page,&start,file->f_pos,thistime); length = ipx_get_info(page,&start,file->f_pos,thistime);
break; break;
#endif /* CONFIG_IPX */ #endif /* CONFIG_IPX */
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
case 138: case 139:
length = ax25_rt_get_info(page,&start,file->f_pos,thistime); length = ax25_rt_get_info(page,&start,file->f_pos,thistime);
break; break;
case 139: case 140:
length = ax25_get_info(page,&start,file->f_pos,thistime); length = ax25_get_info(page,&start,file->f_pos,thistime);
break; break;
#ifdef CONFIG_NETROM #ifdef CONFIG_NETROM
case 140: case 141:
length = nr_nodes_get_info(page,&start,file->f_pos,thistime); length = nr_nodes_get_info(page,&start,file->f_pos,thistime);
break; break;
case 141: case 142:
length = nr_neigh_get_info(page,&start,file->f_pos,thistime); length = nr_neigh_get_info(page,&start,file->f_pos,thistime);
break; break;
case 142: case 143:
length = nr_get_info(page,&start,file->f_pos,thistime); length = nr_get_info(page,&start,file->f_pos,thistime);
break; break;
#endif /* CONFIG_NETROM */ #endif /* CONFIG_NETROM */
......
...@@ -662,5 +662,6 @@ void mount_root(void) ...@@ -662,5 +662,6 @@ void mount_root(void)
return; return;
} }
} }
panic("VFS: Unable to mount root"); panic("VFS: Unable to mount root fs on %02x:%02x",
MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
} }
...@@ -193,9 +193,10 @@ extern int dev_ioctl(unsigned int cmd, void *); ...@@ -193,9 +193,10 @@ extern int dev_ioctl(unsigned int cmd, void *);
extern void dev_init(void); extern void dev_init(void);
/* This function lives elsewhere (drivers/net/net_init.c but is related) */ /* These functions live elsewhere (drivers/net/net_init.c, but related) */
extern void ether_setup(struct device *dev); extern void ether_setup(struct device *dev);
extern int ether_config(struct device *dev, struct ifmap *map);
/* Support for loadable net-drivers */ /* Support for loadable net-drivers */
extern int register_netdev(struct device *dev); extern int register_netdev(struct device *dev);
extern void unregister_netdev(struct device *dev); extern void unregister_netdev(struct device *dev);
......
...@@ -107,13 +107,13 @@ ...@@ -107,13 +107,13 @@
/* /*
* disk states (bits of diskstate_flags): * disk states (bits of diskstate_flags):
*/ */
#define upc_valid (DS[d].diskstate_flags&upc_bit) #define upc_valid (DriveStruct[d].diskstate_flags&upc_bit)
#define volume_valid (DS[d].diskstate_flags&volume_bit) #define volume_valid (DriveStruct[d].diskstate_flags&volume_bit)
#define toc_valid (DS[d].diskstate_flags&toc_bit) #define toc_valid (DriveStruct[d].diskstate_flags&toc_bit)
#define multisession_valid (DS[d].diskstate_flags&multisession_bit) #define multisession_valid (DriveStruct[d].diskstate_flags&multisession_bit)
#define cd_size_valid (DS[d].diskstate_flags&cd_size_bit) #define cd_size_valid (DriveStruct[d].diskstate_flags&cd_size_bit)
#define subq_valid (DS[d].diskstate_flags&subq_bit) #define subq_valid (DriveStruct[d].diskstate_flags&subq_bit)
#define frame_size_valid (DS[d].diskstate_flags&frame_size_bit) #define frame_size_valid (DriveStruct[d].diskstate_flags&frame_size_bit)
/* /*
...@@ -137,13 +137,13 @@ ...@@ -137,13 +137,13 @@
/* /*
* used drive states: * used drive states:
*/ */
#define st_door_closed (DS[d].status_byte&p_door_closed) #define st_door_closed (DriveStruct[d].status_byte&p_door_closed)
#define st_caddy_in (DS[d].status_byte&p_caddy_in) #define st_caddy_in (DriveStruct[d].status_byte&p_caddy_in)
#define st_spinning (DS[d].status_byte&p_spinning) #define st_spinning (DriveStruct[d].status_byte&p_spinning)
#define st_check (DS[d].status_byte&p_check) #define st_check (DriveStruct[d].status_byte&p_check)
#define st_busy (DS[d].status_byte&p_busy_new) #define st_busy (DriveStruct[d].status_byte&p_busy_new)
#define st_door_locked (DS[d].status_byte&p_door_locked) #define st_door_locked (DriveStruct[d].status_byte&p_door_locked)
#define st_diskok (DS[d].status_byte&p_disk_ok) #define st_diskok (DriveStruct[d].status_byte&p_disk_ok)
/* /*
* bits of the CDi_status register: * bits of the CDi_status register:
...@@ -175,7 +175,7 @@ ...@@ -175,7 +175,7 @@
/* /*
* drv_099 and drv_100 are the "new" drives * drv_099 and drv_100 are the "new" drives
*/ */
#define new_drive (DS[d].drv_type&0x10) #define new_drive (DriveStruct[d].drv_type&0x10)
/* /*
* audio states: * audio states:
......
...@@ -68,7 +68,11 @@ struct sk_buff { ...@@ -68,7 +68,11 @@ struct sk_buff {
used, used,
free, free,
arp; arp;
unsigned char tries,lock,localroute; unsigned char tries,lock,localroute,pkt_type;
#define PACKET_HOST 0 /* To us */
#define PACKET_BROADCAST 1
#define PACKET_MULTICAST 2
#define PACKET_OTHERHOST 3 /* Unmatched promiscuous */
unsigned short users; /* User count - see datagram.c (and soon seqpacket.c/stream.c) */ unsigned short users; /* User count - see datagram.c (and soon seqpacket.c/stream.c) */
#ifdef CONFIG_SLAVE_BALANCING #ifdef CONFIG_SLAVE_BALANCING
unsigned short in_dev_queue; unsigned short in_dev_queue;
......
#ifndef _LINUX_TERMIOS_H #ifndef _LINUX_TERMIOS_H
#define _LINUX_TERMIOS_H #define _LINUX_TERMIOS_H
#include <linux/types.h>
/* 0x54 is just a magic number to make these relatively uniqe ('T') */ /* 0x54 is just a magic number to make these relatively uniqe ('T') */
#define TCGETS 0x5401 #define TCGETS 0x5401
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* 'tty.h' defines some structures used by tty_io.c and some defines. * 'tty.h' defines some structures used by tty_io.c and some defines.
*/ */
#include <linux/fs.h>
#include <linux/termios.h> #include <linux/termios.h>
#include <linux/tqueue.h> #include <linux/tqueue.h>
#include <linux/tty_driver.h> #include <linux/tty_driver.h>
......
...@@ -87,6 +87,8 @@ ...@@ -87,6 +87,8 @@
* *
*/ */
#include <linux/fs.h>
struct tty_driver { struct tty_driver {
int magic; /* magic number for this structure */ int magic; /* magic number for this structure */
char *name; char *name;
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
* Definitions for the tty line discipline * Definitions for the tty line discipline
*/ */
#include <linux/fs.h>
#include <linux/wait.h>
struct tty_ldisc { struct tty_ldisc {
int magic; int magic;
int num; int num;
......
3c509.o de600.o 3c509.o de600.o 3c501.o plip.o
This is snapshot 014 This is snapshot 014
Fixes added for 1.1.15
o Modular PLIP and 3c501 drivers. Now you -can- have multiple 3c501's
(sort of).
o Integrated new AX.25 - this will be ready for the big time in a few
releases.
Fixes added for 1.1.14
o Compiles properly on the whole 8)
o Yet more Unix /proc protection.
o Modular PLIP and 3c501 drivers. Now you -can- have multiple 3c501's
(sort of).
This fixes the following from the 1.1.12 release (see the relevant files This fixes the following from the 1.1.12 release (see the relevant files
for the credits to authors). for the credits to authors).
......
...@@ -292,7 +292,10 @@ int dev_close(struct device *dev) ...@@ -292,7 +292,10 @@ int dev_close(struct device *dev)
*/ */
#ifdef CONFIG_INET #ifdef CONFIG_INET
ip_rt_flush(dev); ip_rt_flush(dev);
#endif #endif
#ifdef CONFIG_IPX
ipxrtr_device_down(dev);
#endif
/* /*
* Blank the IP addresses * Blank the IP addresses
*/ */
......
...@@ -167,7 +167,21 @@ unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev) ...@@ -167,7 +167,21 @@ unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev)
{ {
struct ethhdr *eth = (struct ethhdr *) skb->data; struct ethhdr *eth = (struct ethhdr *) skb->data;
char *rawp; char *rawp;
if(*eth->h_dest&1)
{
if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
skb->pkt_type=PACKET_BROADCAST;
else
skb->pkt_type=PACKET_MULTICAST;
}
if(dev->flags&IFF_PROMISC)
{
if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
skb->pkt_type=PACKET_OTHERHOST;
}
if (ntohs(eth->h_proto) >= 1536) if (ntohs(eth->h_proto) >= 1536)
return eth->h_proto; return eth->h_proto;
......
...@@ -177,6 +177,7 @@ static int ip_send(struct sk_buff *skb, unsigned long daddr, int len, struct dev ...@@ -177,6 +177,7 @@ static int ip_send(struct sk_buff *skb, unsigned long daddr, int len, struct dev
return mac; return mac;
} }
int ip_id_count = 0;
/* /*
* This routine builds the appropriate hardware/IP headers for * This routine builds the appropriate hardware/IP headers for
...@@ -192,7 +193,6 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd ...@@ -192,7 +193,6 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd
struct rtable *rt; struct rtable *rt;
unsigned char *buff; unsigned char *buff;
unsigned long raddr; unsigned long raddr;
static int count = 0;
int tmp; int tmp;
unsigned long src; unsigned long src;
...@@ -295,8 +295,7 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd ...@@ -295,8 +295,7 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd
iph->saddr = saddr; iph->saddr = saddr;
iph->protocol = type; iph->protocol = type;
iph->ihl = 5; iph->ihl = 5;
iph->id = htons(count++);
/* Setup the IP options. */ /* Setup the IP options. */
#ifdef Not_Yet_Avail #ifdef Not_Yet_Avail
build_options(iph, opt); build_options(iph, opt);
...@@ -1250,25 +1249,6 @@ static void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag) ...@@ -1250,25 +1249,6 @@ static void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag)
unsigned char *ptr; /* Data pointer */ unsigned char *ptr; /* Data pointer */
unsigned long raddr; /* Router IP address */ unsigned long raddr; /* Router IP address */
/*
* Only forward packets that were fired at us when we are in promiscuous
* mode. In standard mode we rely on the driver to filter for us.
*
* This is a mess. When the drivers class packets on the upcall this
* will tidy up!
*/
if(dev->flags&IFF_PROMISC)
{
if(memcmp(skb->data,dev->dev_addr,dev->addr_len))
return;
}
if(!memcmp(skb->data,dev->broadcast, dev->addr_len))
return;
/* /*
* According to the RFC, we must first decrease the TTL field. If * According to the RFC, we must first decrease the TTL field. If
* that reaches zero, we must reply an ICMP control message telling * that reaches zero, we must reply an ICMP control message telling
...@@ -1516,7 +1496,16 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -1516,7 +1496,16 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
if ((brd = ip_chk_addr(iph->daddr)) == 0) if ((brd = ip_chk_addr(iph->daddr)) == 0)
{ {
/*
* Don't forward multicast or broadcast frames.
*/
if(skb->pkt_type!=PACKET_HOST)
{
kfree_skb(skb,FREE_WRITE);
return 0;
}
/* /*
* The packet is for another target. Forward the frame * The packet is for another target. Forward the frame
*/ */
...@@ -1683,6 +1672,7 @@ void ip_queue_xmit(struct sock *sk, struct device *dev, ...@@ -1683,6 +1672,7 @@ void ip_queue_xmit(struct sock *sk, struct device *dev,
iph = (struct iphdr *)ptr; iph = (struct iphdr *)ptr;
skb->ip_hdr = iph; skb->ip_hdr = iph;
iph->tot_len = ntohs(skb->len-dev->hard_header_len); iph->tot_len = ntohs(skb->len-dev->hard_header_len);
iph->id = htons(ip_id_count++);
/* /*
* Do we need to fragment. Again this is inefficient. * Do we need to fragment. Again this is inefficient.
...@@ -1813,27 +1803,34 @@ void ip_do_retransmit(struct sock *sk, int all) ...@@ -1813,27 +1803,34 @@ void ip_do_retransmit(struct sock *sk, int all)
{ {
dev = skb->dev; dev = skb->dev;
IS_SKB(skb); IS_SKB(skb);
#if 0 skb->when = jiffies;
/********** THIS IS NOW DONE BY THE DEVICE LAYER **********/
/* /*
* The rebuild_header function sees if the ARP is done. * In general it's OK just to use the old packet. However we
* If not it sends a new ARP request, and if so it builds * need to use the current ack and window fields. Urg and
* the header. It isn't really needed here, and with the * urg_ptr could possibly stand to be updated as well, but we
* new ARP pretty much will not happen. * don't keep the necessary data. That shouldn't be a problem,
* if the other end is doing the right thing. Since we're
* changing the packet, we have to issue a new IP identifier.
*/ */
if (!skb->arp) /* this check may be unnecessary - retransmit only for TCP */
{ if (sk->protocol == IPPROTO_TCP) {
if (dev->rebuild_header(skb->data, dev, skb->raddr, NULL)) struct tcphdr *th;
{ struct iphdr *iph;
if (!all) int size;
break;
skb = skb->link3; iph = (struct iphdr *)(skb->data + dev->hard_header_len);
continue; th = (struct tcphdr *)(((char *)iph) + (iph->ihl << 2));
} size = skb->len - (((unsigned char *) th) - skb->data);
iph->id = htons(ip_id_count++);
ip_send_check(iph);
th->ack_seq = ntohl(sk->acked_seq);
th->window = ntohs(tcp_select_window(sk));
tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
} }
#endif
skb->when = jiffies;
/* /*
* If the interface is (still) up and running, kick it. * If the interface is (still) up and running, kick it.
......
...@@ -24,7 +24,9 @@ ...@@ -24,7 +24,9 @@
* Revision 0.24: Supports new /proc with no 4K limit * Revision 0.24: Supports new /proc with no 4K limit
* Revision 0.25: Add ephemeral sockets, passive local network * Revision 0.25: Add ephemeral sockets, passive local network
* identification, support for local net 0 and * identification, support for local net 0 and
* multiple datalinks * multiple datalinks <Greg Page>
* Revision 0.26: Device drop kills IPX routes via it. (needed for modules)
*
* *
* *
*/ */
...@@ -350,50 +352,54 @@ static int ipxrtr_create(struct ipx_route_def *r) ...@@ -350,50 +352,54 @@ static int ipxrtr_create(struct ipx_route_def *r)
static int ipxrtr_delete_localnet(ipx_route *d) static int ipxrtr_delete_localnet(ipx_route *d)
{ {
ipx_route *r=ipx_localnet_list; ipx_route **r = &ipx_localnet_list;
if(r==d) ipx_route *tmp;
{
ipx_localnet_list=r->next; while ((tmp = *r) != NULL) {
return 0; if (tmp == d) {
} *r = tmp->next;
while(r->next!=NULL)
{
if(r->nextlocal==d)
{
r->nextlocal=d->nextlocal;
return 0; return 0;
} }
r=r->nextlocal; r = &tmp->nextlocal;
} }
return -ENOENT; return -ENOENT;
} }
static int ipxrtr_delete(long net) static int ipxrtr_delete(long net)
{ {
ipx_route *r=ipx_router_list; ipx_route **r = &ipx_router_list;
if(r->net==net) ipx_route *tmp;
{
ipx_router_list=r->next; while ((tmp = *r) != NULL) {
kfree_s(r,sizeof(ipx_route)); if (tmp->net == net) {
return 0; *r = tmp->next;
} if (tmp->router_net == 0) {
while(r->next!=NULL) ipxrtr_delete_localnet(tmp);
{
if(r->next->net==net)
{
ipx_route *d=r->next;
r->next=d->next;
if (d->router_net == 0) {
ipxrtr_delete_localnet(d);
} }
kfree_s(d,sizeof(ipx_route)); kfree_s(tmp, sizeof(ipx_route));
return 0; return 0;
} }
r=r->next; r = &tmp->next;
} }
return -ENOENT; return -ENOENT;
} }
void ipxrtr_device_down(struct device *dev)
{
ipx_route **r = &ipx_router_list;
ipx_route *tmp;
while ((tmp = *r) != NULL) {
if (tmp->dev == dev) {
*r = tmp->next;
if(tmp->router_net == 0)
ipxrtr_delete_localnet(tmp);
kfree_s(tmp, sizeof(ipx_route));
}
r = &tmp->next;
}
}
static int ipxrtr_ioctl(unsigned int cmd, void *arg) static int ipxrtr_ioctl(unsigned int cmd, void *arg)
{ {
int err; int err;
......
...@@ -64,6 +64,7 @@ typedef struct sock ipx_socket; ...@@ -64,6 +64,7 @@ typedef struct sock ipx_socket;
#include "ipxcall.h" #include "ipxcall.h"
extern int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt); extern int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt);
extern void ipxrtr_device_down(struct device *dev);
......
...@@ -12,16 +12,14 @@ ...@@ -12,16 +12,14 @@
* Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de> * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
* Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de> * Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
* Erik Schoenfelder, <schoenfr@ibr.cs.tu-bs.de>
* *
* Fixes: * Fixes:
* Alan Cox : UDP sockets show the rxqueue/txqueue * Alan Cox : UDP sockets show the rxqueue/txqueue
* using hint flag for the netinfo. * using hint flag for the netinfo.
* Pauline Middelink : Pidentd support * Pauline Middelink : Pidentd support
* Alan Cox : Make /proc safer. * Alan Cox : Make /proc safer.
* * Erik Schoenfelder : /proc/net/snmp
* To Do:
* Put the creating userid in the proc/net/... files. This will
* allow us to write an RFC931 daemon for Linux
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -39,6 +37,7 @@ ...@@ -39,6 +37,7 @@
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include "ip.h" #include "ip.h"
#include "icmp.h"
#include "protocol.h" #include "protocol.h"
#include "tcp.h" #include "tcp.h"
#include "udp.h" #include "udp.h"
...@@ -141,3 +140,73 @@ int raw_get_info(char *buffer, char **start, off_t offset, int length) ...@@ -141,3 +140,73 @@ int raw_get_info(char *buffer, char **start, off_t offset, int length)
{ {
return get__netinfo(&raw_prot, buffer,1, start, offset, length); return get__netinfo(&raw_prot, buffer,1, start, offset, length);
} }
/*
* Called from the PROCfs module. This outputs /proc/net/snmp.
*/
int snmp_get_info(char *buffer, char **start, off_t offset, int length)
{
extern struct tcp_mib tcp_statistics;
extern struct udp_mib udp_statistics;
int len;
len = sprintf (buffer,
"Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates\n"
"Ip: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
ip_statistics.IpForwarding, ip_statistics.IpDefaultTTL,
ip_statistics.IpInReceives, ip_statistics.IpInHdrErrors,
ip_statistics.IpInAddrErrors, ip_statistics.IpForwDatagrams,
ip_statistics.IpInUnknownProtos, ip_statistics.IpInDiscards,
ip_statistics.IpInDelivers, ip_statistics.IpOutRequests,
ip_statistics.IpOutDiscards, ip_statistics.IpOutNoRoutes,
ip_statistics.IpReasmTimeout, ip_statistics.IpReasmReqds,
ip_statistics.IpReasmOKs, ip_statistics.IpReasmFails,
ip_statistics.IpFragOKs, ip_statistics.IpFragFails,
ip_statistics.IpFragCreates);
len += sprintf (buffer + len,
"Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps\n"
"Icmp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
icmp_statistics.IcmpInMsgs, icmp_statistics.IcmpInErrors,
icmp_statistics.IcmpInDestUnreachs, icmp_statistics.IcmpInTimeExcds,
icmp_statistics.IcmpInParmProbs, icmp_statistics.IcmpInSrcQuenchs,
icmp_statistics.IcmpInRedirects, icmp_statistics.IcmpInEchos,
icmp_statistics.IcmpInEchoReps, icmp_statistics.IcmpInTimestamps,
icmp_statistics.IcmpInTimestampReps, icmp_statistics.IcmpInAddrMasks,
icmp_statistics.IcmpInAddrMaskReps, icmp_statistics.IcmpOutMsgs,
icmp_statistics.IcmpOutErrors, icmp_statistics.IcmpOutDestUnreachs,
icmp_statistics.IcmpOutTimeExcds, icmp_statistics.IcmpOutParmProbs,
icmp_statistics.IcmpOutSrcQuenchs, icmp_statistics.IcmpOutRedirects,
icmp_statistics.IcmpOutEchos, icmp_statistics.IcmpOutEchoReps,
icmp_statistics.IcmpOutTimestamps, icmp_statistics.IcmpOutTimestampReps,
icmp_statistics.IcmpOutAddrMasks, icmp_statistics.IcmpOutAddrMaskReps);
len += sprintf (buffer + len,
"Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs\n"
"Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
tcp_statistics.TcpRtoAlgorithm, tcp_statistics.TcpRtoMin,
tcp_statistics.TcpRtoMax, tcp_statistics.TcpMaxConn,
tcp_statistics.TcpActiveOpens, tcp_statistics.TcpPassiveOpens,
tcp_statistics.TcpAttemptFails, tcp_statistics.TcpEstabResets,
tcp_statistics.TcpCurrEstab, tcp_statistics.TcpInSegs,
tcp_statistics.TcpOutSegs, tcp_statistics.TcpRetransSegs);
len += sprintf (buffer + len,
"Udp: InDatagrams NoPorts InErrors OutDatagrams\nUdp: %lu %lu %lu %lu\n",
udp_statistics.UdpInDatagrams, udp_statistics.UdpNoPorts,
udp_statistics.UdpInErrors, udp_statistics.UdpOutDatagrams);
if (offset >= len)
{
*start = buffer;
return 0;
}
*start = buffer + offset;
len -= offset;
if (len > length)
len = length;
return len;
}
...@@ -464,6 +464,7 @@ void kfree_skb(struct sk_buff *skb, int rw) ...@@ -464,6 +464,7 @@ void kfree_skb(struct sk_buff *skb, int rw)
skb->free = 2; /* Invalid so we pick up forgetful users */ skb->free = 2; /* Invalid so we pick up forgetful users */
skb->lock = 0; skb->lock = 0;
skb->pkt_type = PACKET_HOST; /* Default type */
skb->truesize = size; skb->truesize = size;
skb->mem_len = size; skb->mem_len = size;
skb->mem_addr = skb; skb->mem_addr = skb;
......
...@@ -148,6 +148,8 @@ struct sock { ...@@ -148,6 +148,8 @@ struct sock {
char ax25_retxqi; char ax25_retxqi;
char ax25_rrtimer; char ax25_rrtimer;
char ax25_timer; char ax25_timer;
unsigned char ax25_n2;
unsigned short ax25_t1,ax25_t3;
ax25_digi *ax25_digipeat; ax25_digi *ax25_digipeat;
#endif #endif
/* IP 'private area' or will be eventually */ /* IP 'private area' or will be eventually */
......
...@@ -172,7 +172,7 @@ min(unsigned int a, unsigned int b) ...@@ -172,7 +172,7 @@ min(unsigned int a, unsigned int b)
Better heuristics welcome Better heuristics welcome
*/ */
static int tcp_select_window(struct sock *sk) int tcp_select_window(struct sock *sk)
{ {
int new_window = sk->prot->rspace(sk); int new_window = sk->prot->rspace(sk);
...@@ -572,13 +572,14 @@ static void tcp_send_skb(struct sock *sk, struct sk_buff *skb) ...@@ -572,13 +572,14 @@ static void tcp_send_skb(struct sock *sk, struct sk_buff *skb)
} }
tcp_statistics.TcpOutSegs++; tcp_statistics.TcpOutSegs++;
/* We need to complete and send the packet. */
tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
skb->h.seq = ntohl(th->seq) + size - 4*th->doff; skb->h.seq = ntohl(th->seq) + size - 4*th->doff;
if (after(skb->h.seq, sk->window_seq) || if (after(skb->h.seq, sk->window_seq) ||
(sk->retransmits && sk->timeout == TIME_WRITE) || (sk->retransmits && sk->timeout == TIME_WRITE) ||
sk->packets_out >= sk->cong_window) { sk->packets_out >= sk->cong_window) {
/* checksum will be supplied by tcp_write_xmit. So
* we shouldn't need to set it at all. I'm being paraoid */
th->check = 0;
if (skb->next != NULL) { if (skb->next != NULL) {
printk("tcp_send_partial: next != NULL\n"); printk("tcp_send_partial: next != NULL\n");
skb_unlink(skb); skb_unlink(skb);
...@@ -589,6 +590,11 @@ static void tcp_send_skb(struct sock *sk, struct sk_buff *skb) ...@@ -589,6 +590,11 @@ static void tcp_send_skb(struct sock *sk, struct sk_buff *skb)
sk->ack_backlog == 0) sk->ack_backlog == 0)
reset_timer(sk, TIME_PROBE0, sk->rto); reset_timer(sk, TIME_PROBE0, sk->rto);
} else { } else {
th->ack_seq = ntohl(sk->acked_seq);
th->window = ntohs(tcp_select_window(sk));
tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
sk->sent_seq = sk->write_seq; sk->sent_seq = sk->write_seq;
sk->prot->queue_xmit(sk, skb->dev, skb, 0); sk->prot->queue_xmit(sk, skb->dev, skb, 0);
} }
...@@ -2237,6 +2243,26 @@ tcp_write_xmit(struct sock *sk) ...@@ -2237,6 +2243,26 @@ tcp_write_xmit(struct sock *sk)
kfree_skb(skb, FREE_WRITE); kfree_skb(skb, FREE_WRITE);
if (!sk->dead) sk->write_space(sk); if (!sk->dead) sk->write_space(sk);
} else { } else {
struct tcphdr *th;
struct iphdr *iph;
int size;
/*
* put in the ack seq and window at this point rather than earlier,
* in order to keep them monotonic. We really want to avoid taking
* back window allocations. That's legal, but RFC1122 says it's frowned on.
* Ack and window will in general have changed since this packet was put
* on the write queue.
*/
iph = (struct iphdr *)(skb->data +
skb->dev->hard_header_len);
th = (struct tcphdr *)(((char *)iph) +(iph->ihl << 2));
size = skb->len - (((unsigned char *) th) - skb->data);
th->ack_seq = ntohl(sk->acked_seq);
th->window = ntohs(tcp_select_window(sk));
tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
sk->sent_seq = skb->h.seq; sk->sent_seq = skb->h.seq;
sk->prot->queue_xmit(sk, skb->dev, skb, skb->free); sk->prot->queue_xmit(sk, skb->dev, skb, skb->free);
} }
...@@ -3197,7 +3223,7 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len) ...@@ -3197,7 +3223,7 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
sk->mtu = rt->rt_mtu; sk->mtu = rt->rt_mtu;
else else
{ {
#ifdef SUBNETSARELOCAL #ifdef CONFIG_INET_SNARL
if ((sk->saddr ^ sk->daddr) & default_mask(sk->saddr)) if ((sk->saddr ^ sk->daddr) & default_mask(sk->saddr))
#else #else
if ((sk->saddr ^ sk->daddr) & dev->pa_mask) if ((sk->saddr ^ sk->daddr) & dev->pa_mask)
...@@ -3319,6 +3345,12 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -3319,6 +3345,12 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
tcp_statistics.TcpInSegs++; tcp_statistics.TcpInSegs++;
if(skb->pkt_type!=PACKET_HOST)
{
kfree_skb(skb,FREE_READ);
return(0);
}
th = skb->h.th; th = skb->h.th;
/* Find the socket. */ /* Find the socket. */
......
...@@ -123,6 +123,9 @@ extern int tcp_rcv(struct sk_buff *skb, struct device *dev, ...@@ -123,6 +123,9 @@ extern int tcp_rcv(struct sk_buff *skb, struct device *dev,
extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
extern int tcp_select_window(struct sock *sk);
extern void tcp_send_check(struct tcphdr *th, unsigned long saddr,
unsigned long daddr, int len, struct sock *sk);
extern void tcp_send_probe0(struct sock *sk); extern void tcp_send_probe0(struct sock *sk);
extern void tcp_enqueue_partial(struct sk_buff *, struct sock *); extern void tcp_enqueue_partial(struct sk_buff *, struct sock *);
extern struct sk_buff * tcp_dequeue_partial(struct sock *); extern struct sk_buff * tcp_dequeue_partial(struct sock *);
......
...@@ -237,15 +237,7 @@ DEBG1("3 "); ...@@ -237,15 +237,7 @@ DEBG1("3 ");
z = 1 << j; /* table entries for j-bit table */ z = 1 << j; /* table entries for j-bit table */
/* allocate and link in new table */ /* allocate and link in new table */
if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == q = (struct huft *)malloc((z + 1)*sizeof(struct huft));
(struct huft *)NULL)
{
DEBG1("31 ");
error("malloc failed\n");
if (h)
huft_free(u[0]);
return 3; /* not enough memory */
}
DEBG1("4 "); DEBG1("4 ");
hufts += z + 1; /* track memory usage */ hufts += z + 1; /* track memory usage */
*t = q + 1; /* link to list for huft_free() */ *t = q + 1; /* link to list for huft_free() */
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is a collection of several routines from gzip-1.0.3 * This is a collection of several routines from gzip-1.0.3
* adapted for Linux. * adapted for Linux.
* *
* malloc by Hannu Savolainen 1993 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
* puts by Nick Holloway 1993 * puts by Nick Holloway 1993
*/ */
...@@ -78,6 +78,8 @@ local int get_method(int); ...@@ -78,6 +78,8 @@ local int get_method(int);
char *vidmem = (char *)0xb8000; char *vidmem = (char *)0xb8000;
int lines, cols; int lines, cols;
static void puts(const char *);
void *malloc(int size) void *malloc(int size)
{ {
void *p; void *p;
...@@ -85,16 +87,29 @@ void *malloc(int size) ...@@ -85,16 +87,29 @@ void *malloc(int size)
if (size <0) error("Malloc error\n"); if (size <0) error("Malloc error\n");
if (free_mem_ptr <= 0) error("Memory error\n"); if (free_mem_ptr <= 0) error("Memory error\n");
while(1) {
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
p = (void *)free_mem_ptr; p = (void *)free_mem_ptr;
free_mem_ptr += size; free_mem_ptr += size;
if (free_mem_ptr > 0x90000) error("\nOut of memory\n"); /*
* The part of the compresed kernel which has already been expanded
if (p == NULL) error("malloc = NULL\n"); * is no longer needed. Therefore we can reuse it for malloc.
* With bigger kernels, this is necessary.
*/
if (free_mem_ptr < (long)&end) {
if (free_mem_ptr > (long)&input_data[input_ptr])
error("\nOut of memory\n");
return p;
}
if (free_mem_ptr < 0x90000)
return p; return p;
puts("memory is tight...");
free_mem_ptr = (long)input_data;
}
} }
void free(void *where) void free(void *where)
...@@ -110,7 +125,7 @@ static void scroll() ...@@ -110,7 +125,7 @@ static void scroll()
vidmem[i] = ' '; vidmem[i] = ' ';
} }
static void puts(char *s) static void puts(const char *s)
{ {
int x,y; int x,y;
char c; char c;
...@@ -309,7 +324,7 @@ void decompress_kernel() ...@@ -309,7 +324,7 @@ void decompress_kernel()
if (EXT_MEM_K < 1024) error("<2M of mem\n"); if (EXT_MEM_K < 1024) error("<2M of mem\n");
output_data = (char *)1048576; /* Points to 1M */ output_data = (char *)0x100000; /* Points to 1M */
output_ptr = 0; output_ptr = 0;
exit_code = 0; exit_code = 0;
...@@ -361,16 +376,10 @@ local int get_method(in) ...@@ -361,16 +376,10 @@ local int get_method(in)
work = unzip; work = unzip;
method = (int)get_byte(); method = (int)get_byte();
flags = (uch)get_byte(); flags = (uch)get_byte();
if ((flags & ENCRYPTED) != 0) { if ((flags & ENCRYPTED) != 0)
error("Input is encrypted\n"); error("Input is encrypted\n");
exit_code = ERROR; if ((flags & CONTINUATION) != 0)
return -1;
}
if ((flags & CONTINUATION) != 0) {
error("Multi part input\n"); error("Multi part input\n");
exit_code = ERROR;
if (force <= 1) return -1;
}
if ((flags & RESERVED) != 0) { if ((flags & RESERVED) != 0) {
error("Input has invalid flags\n"); error("Input has invalid flags\n");
exit_code = ERROR; exit_code = ERROR;
...@@ -384,13 +393,6 @@ local int get_method(in) ...@@ -384,13 +393,6 @@ local int get_method(in)
(void)get_byte(); /* Ignore extra flags for the moment */ (void)get_byte(); /* Ignore extra flags for the moment */
(void)get_byte(); /* Ignore OS type for the moment */ (void)get_byte(); /* Ignore OS type for the moment */
if ((flags & CONTINUATION) != 0) {
unsigned part = (unsigned)get_byte();
part |= ((unsigned)get_byte())<<8;
if (verbose) {
error("Input is not part number 1\n");
}
}
if ((flags & EXTRA_FIELD) != 0) { if ((flags & EXTRA_FIELD) != 0) {
unsigned len = (unsigned)get_byte(); unsigned len = (unsigned)get_byte();
len |= ((unsigned)get_byte())<<8; len |= ((unsigned)get_byte())<<8;
...@@ -410,28 +412,7 @@ local int get_method(in) ...@@ -410,28 +412,7 @@ local int get_method(in)
if ((flags & COMMENT) != 0) { if ((flags & COMMENT) != 0) {
while (get_byte() != 0) /* null */ ; while (get_byte() != 0) /* null */ ;
} }
} else
} else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2 error("unknown compression method");
&& memcmp(inbuf, PKZIP_MAGIC, 4) == 0) {
/* To simplify the code, we support a zip file when alone only.
* We are thus guaranteed that the entire local header fits in inbuf.
*/
inptr = 0;
work = unzip;
if (check_zipfile(in) == -1) return -1;
/* check_zipfile may get ofname from the local header */
last_member = 1;
} else if (memcmp(magic, PACK_MAGIC, 2) == 0) {
error("packed input");
} else if (memcmp(magic, LZW_MAGIC, 2) == 0) {
error("compressed input");
last_member = 1;
}
if (method == -1) {
error("Corrupted input\n");
if (exit_code != ERROR) exit_code = part_nb == 1 ? ERROR : WARNING;
return part_nb == 1 ? -1 : -2;
}
return method; return method;
} }
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