Commit f40ed092 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.65

parent feb3aa0e
...@@ -638,6 +638,10 @@ S: 59 Bugden Avenue ...@@ -638,6 +638,10 @@ S: 59 Bugden Avenue
S: Gowrie ACT 2904 S: Gowrie ACT 2904
S: Australia S: Australia
N: Alessandro Rubini
E: rubini@ipvvis.unipv.it
D: the gpm mouse server and kernel support for it
N: Robert Sanders N: Robert Sanders
E: gt8134b@prism.gatech.edu E: gt8134b@prism.gatech.edu
D: Dosemu D: Dosemu
......
VERSION = 1 VERSION = 1
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 64 SUBLEVEL = 65
ARCH = i386 ARCH = i386
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
* block operation is done. Note that with 2048 byte blocks you * block operation is done. Note that with 2048 byte blocks you
* cannot execute files from the CD. * cannot execute files from the CD.
* *
* XA compatability * XA compatibility
* *
* The driver should support XA disks for both the CDU31A and CDU33A. * The driver should support XA disks for both the CDU31A and CDU33A.
* It does this transparently, the using program doesn't need to set it. * It does this transparently, the using program doesn't need to set it.
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
* has it's own minor device number, starting with 0. The support is * has it's own minor device number, starting with 0. The support is
* pretty transparent, music, TOC operations, and read operations should * pretty transparent, music, TOC operations, and read operations should
* all work transparently on any session. Note that since the driver * all work transparently on any session. Note that since the driver
* writer doesn't have a multi-session disk, this is all theoritical. * writer doesn't have a multi-session disk, this is all theoretical.
* Also, music operation will obviously only work on one session at a * Also, music operation will obviously only work on one session at a
* time. * time.
* *
......
...@@ -2930,7 +2930,7 @@ static struct cont_t poll_cont={ ...@@ -2930,7 +2930,7 @@ static struct cont_t poll_cont={
/* revalidate the floppy disk, i.e. trigger format autodetection by reading /* revalidate the floppy disk, i.e. trigger format autodetection by reading
* the bootblock (block 0). "Autodetection" is also needed to check wether * the bootblock (block 0). "Autodetection" is also needed to check whether
* there is a disk in the drive at all... Thus we also do it for fixed * there is a disk in the drive at all... Thus we also do it for fixed
* geometry formats */ * geometry formats */
static int floppy_revalidate(dev_t dev) static int floppy_revalidate(dev_t dev)
......
Sun Nov 6 21:05:44 1994 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (change_speed): Add support for direct access of
57,600 and 115,200 bps.
Wed Nov 2 10:32:36 1994 Theodore Y. Ts'o (tytso@rt-11) Wed Nov 2 10:32:36 1994 Theodore Y. Ts'o (tytso@rt-11)
* n_tty.c (n_tty_receive_room): Only allow excess characters * n_tty.c (n_tty_receive_room): Only allow excess characters
...@@ -14,7 +19,7 @@ Sat Oct 29 18:17:34 1994 Theodore Y. Ts'o (tytso@rt-11) ...@@ -14,7 +19,7 @@ Sat Oct 29 18:17:34 1994 Theodore Y. Ts'o (tytso@rt-11)
Thu Oct 27 23:14:29 1994 Theodore Y. Ts'o (tytso@rt-11) Thu Oct 27 23:14:29 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_ioctl.c (wait_until_sent): Added debugging printk statements * tty_ioctl.c (wait_until_sent): Added debugging printk statements
(under the #ifdef TTY_DEBUG_WAIT_UNTL_SENT) (under the #ifdef TTY_DEBUG_WAIT_UNTIL_SENT)
* serial.c (rs_interrupt, rs_interrupt_single, receive_chars, * serial.c (rs_interrupt, rs_interrupt_single, receive_chars,
change_speed, rs_close): rs_close now disables receiver change_speed, rs_close): rs_close now disables receiver
...@@ -33,12 +38,12 @@ Thu Oct 27 23:14:29 1994 Theodore Y. Ts'o (tytso@rt-11) ...@@ -33,12 +38,12 @@ Thu Oct 27 23:14:29 1994 Theodore Y. Ts'o (tytso@rt-11)
Mon Oct 24 23:36:21 1994 Theodore Y. Ts'o (tytso@rt-11) Mon Oct 24 23:36:21 1994 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_close): Add a timeout to the transmitter flush * serial.c (rs_close): Add a timeout to the transmitter flush
loop; this is just a sanity check in case we have flakey loop; this is just a sanity check in case we have flaky
(or non-existent-but-configured-by-the-user) hardware. (or non-existent-but-configured-by-the-user) hardware.
Fri Oct 21 09:37:23 1994 Theodore Y. Ts'o (tytso@rt-11) Fri Oct 21 09:37:23 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (tty_fasync): When asyncronous I/O is enabled, if the * tty_io.c (tty_fasync): When asynchronous I/O is enabled, if the
process or process group has not be specified yet, set it process or process group has not be specified yet, set it
to be the tty's process group, or if that is not yet set, to be the tty's process group, or if that is not yet set,
to the current process's pid. to the current process's pid.
...@@ -55,7 +60,7 @@ Tue Oct 18 10:02:43 1994 Theodore Y. Ts'o (tytso@rt-11) ...@@ -55,7 +60,7 @@ Tue Oct 18 10:02:43 1994 Theodore Y. Ts'o (tytso@rt-11)
preventing transmit interrupts from being re-enabled in preventing transmit interrupts from being re-enabled in
rs_start(). Fortunately in most cases it would be rs_start(). Fortunately in most cases it would be
re-enabled elsewhere, but this still should be fixed re-enabled elsewhere, but this still should be fixed
corectly. correctly.
Sun Oct 9 23:46:03 1994 Theodore Y. Ts'o (tytso@rt-11) Sun Oct 9 23:46:03 1994 Theodore Y. Ts'o (tytso@rt-11)
......
...@@ -190,7 +190,7 @@ void to_utf8(ushort c) { ...@@ -190,7 +190,7 @@ void to_utf8(ushort c) {
put_queue(0x80 | ((c >> 6) & 0x3f)); put_queue(0x80 | ((c >> 6) & 0x3f));
put_queue(0x80 | (c & 0x3f)); put_queue(0x80 | (c & 0x3f));
} }
/* uft-8 is defined for words of up to 36 bits, /* utf-8 is defined for words of up to 36 bits,
but we need only 16 bits here */ but we need only 16 bits here */
} }
...@@ -688,9 +688,10 @@ static void incr_console(void) ...@@ -688,9 +688,10 @@ static void incr_console(void)
static void send_intr(void) static void send_intr(void)
{ {
if (!tty || (tty->termios && I_IGNBRK(tty))) if (!tty)
return; return;
tty_insert_flip_char(tty, 0, TTY_BREAK); tty_insert_flip_char(tty, 0, TTY_BREAK);
tty_schedule_flip(tty);
} }
static void scroll_forw(void) static void scroll_forw(void)
......
...@@ -1084,6 +1084,13 @@ static void change_speed(struct async_struct *info) ...@@ -1084,6 +1084,13 @@ static void change_speed(struct async_struct *info)
if (!(port = info->port)) if (!(port = info->port))
return; return;
i = cflag & CBAUD; i = cflag & CBAUD;
if (i & CBAUDEX) {
i &= ~CBAUDEX;
if (i < 1 || i > 2)
info->tty->termios->c_cflag &= ~CBAUDEX;
else
i += 15;
}
if (i == 15) { if (i == 15) {
if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
i += 1; i += 1;
...@@ -1833,7 +1840,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) ...@@ -1833,7 +1840,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
/* /*
* At this point we stop accepting input. To do this, we * At this point we stop accepting input. To do this, we
* disable the receive line status interrupts, and tell the * disable the receive line status interrupts, and tell the
* interrut driver to stop checking the data ready bit in the * interrupt driver to stop checking the data ready bit in the
* line status register. * line status register.
*/ */
info->IER &= ~UART_IER_RLSI; info->IER &= ~UART_IER_RLSI;
......
...@@ -183,7 +183,7 @@ el2_probe1(struct device *dev, int ioaddr) ...@@ -183,7 +183,7 @@ el2_probe1(struct device *dev, int ioaddr)
printk("%s: 3c503 at %#3x,", dev->name, ioaddr); printk("%s: 3c503 at %#3x,", dev->name, ioaddr);
/* Retrive and print the ethernet address. */ /* Retrieve and print the ethernet address. */
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i)); printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
The Fujitsu MB86695 datasheet. The Fujitsu MB86695 datasheet.
After the initial version of this driver was written Gerry Sockins of After the initial version of this driver was written Gerry Sockins of
ATI provided their EEPROM configurationcode header file. ATI provided their EEPROM configuration code header file.
Thanks to NIIBE Yutaka <gniibe@mri.co.jp> for bug fixes. Thanks to NIIBE Yutaka <gniibe@mri.co.jp> for bug fixes.
Bugs: Bugs:
......
...@@ -115,7 +115,7 @@ ...@@ -115,7 +115,7 @@
#define IOB 0x1f /* Compare bits for I/O Base Address */ #define IOB 0x1f /* Compare bits for I/O Base Address */
/* /*
** I/O Congiguration/Management Register bit definitions (EWRK3_CMR) ** I/O Configuration/Management Register bit definitions (EWRK3_CMR)
*/ */
#define RA 0x80 /* Read Ahead */ #define RA 0x80 /* Read Ahead */
#define WB 0x40 /* Write Behind */ #define WB 0x40 /* Write Behind */
......
...@@ -109,7 +109,7 @@ the buffers are only used when needed as low-memory bounce buffers. ...@@ -109,7 +109,7 @@ the buffers are only used when needed as low-memory bounce buffers.
IIIB. 16M memory limitations. IIIB. 16M memory limitations.
For the ISA bus master mode all structures used directly by the LANCE, For the ISA bus master mode all structures used directly by the LANCE,
the initialization block, Rx and Tx rings, and data buffers, must be the initialization block, Rx and Tx rings, and data buffers, must be
accessable from the ISA bus, i.e. in the lower 16M of real memory. accessible from the ISA bus, i.e. in the lower 16M of real memory.
This is a problem for current Linux kernels on >16M machines. The network This is a problem for current Linux kernels on >16M machines. The network
devices are initialized after memory initialization, and the kernel doles out devices are initialized after memory initialization, and the kernel doles out
memory from the top of memory downward. The current solution is to have a memory from the top of memory downward. The current solution is to have a
...@@ -207,7 +207,7 @@ struct lance_private { ...@@ -207,7 +207,7 @@ struct lance_private {
}; };
/* A mapping from the chip ID number to the part number and features. /* A mapping from the chip ID number to the part number and features.
These are fro the datasheets -- in real life the '970 version These are from the datasheets -- in real life the '970 version
reportedly has the same ID as the '965. */ reportedly has the same ID as the '965. */
static struct lance_chip_type { static struct lance_chip_type {
int id_number; int id_number;
...@@ -239,7 +239,7 @@ static void set_multicast_list(struct device *dev, int num_addrs, void *addrs); ...@@ -239,7 +239,7 @@ static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
/* This lance probe is unlike the other board probes in 1.0.*. The LANCE may /* This lance probe is unlike the other board probes in 1.0.*. The LANCE may
have to allocate a contiguous low-memory region for bounce buffers. have to allocate a contiguous low-memory region for bounce buffers.
This requirement is satified by having the lance initialization occur before the This requirement is satisfied by having the lance initialization occur before the
memory management system is started, and thus well before the other probes. */ memory management system is started, and thus well before the other probes. */
unsigned long lance_init(unsigned long mem_start, unsigned long mem_end) unsigned long lance_init(unsigned long mem_start, unsigned long mem_end)
{ {
......
...@@ -174,7 +174,7 @@ static int netcard_probe1(struct device *dev, int ioaddr) ...@@ -174,7 +174,7 @@ static int netcard_probe1(struct device *dev, int ioaddr)
/* Fill in the 'dev' fields. */ /* Fill in the 'dev' fields. */
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
/* Retrive and print the ethernet address. */ /* Retrieve and print the ethernet address. */
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i)); printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
* Alan Cox : Default to 192.168.0.0 (RFC 1597) * Alan Cox : Default to 192.168.0.0 (RFC 1597)
* A.N.Kuznetsov : dev_tint() recursion fix. * A.N.Kuznetsov : dev_tint() recursion fix.
* Dmitry Gorodchanin : SLIP memory leaks * Dmitry Gorodchanin : SLIP memory leaks
* Alan Cox : Oops - fix AX.25 buffer lengths
* *
* *
* FIXME: This driver still makes some IP'ish assumptions. It should build cleanly KISS TNC only without * FIXME: This driver still makes some IP'ish assumptions. It should build cleanly KISS TNC only without
...@@ -164,7 +165,11 @@ static void sl_changedmtu(struct slip *sl) ...@@ -164,7 +165,11 @@ static void sl_changedmtu(struct slip *sl)
int l; int l;
int omtu=sl->mtu; int omtu=sl->mtu;
#ifdef CONFIG_AX25
sl->mtu=dev->mtu+73
#else
sl->mtu=dev->mtu; sl->mtu=dev->mtu;
#endif
l=(dev->mtu *2); l=(dev->mtu *2);
/* /*
* allow for arrival of larger UDP packets, even if we say not to * allow for arrival of larger UDP packets, even if we say not to
...@@ -357,7 +362,11 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len) ...@@ -357,7 +362,11 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len)
int actual, count; int actual, count;
#ifdef CONFIG_AX25
if(sl->mtu != sl->dev->mtu+73)/* Someone has been ifconfigging */
#else
if(sl->mtu != sl->dev->mtu) /* Someone has been ifconfigging */ if(sl->mtu != sl->dev->mtu) /* Someone has been ifconfigging */
#endif
sl_changedmtu(sl); sl_changedmtu(sl);
if(len>sl->mtu) /* Sigh, shouldn't occur BUT ... */ if(len>sl->mtu) /* Sigh, shouldn't occur BUT ... */
...@@ -562,7 +571,11 @@ sl_open(struct device *dev) ...@@ -562,7 +571,11 @@ sl_open(struct device *dev)
return(-ENOMEM); return(-ENOMEM);
} }
#ifdef CONFIG_AX25
sl->mtu = dev->mtu+73
#else
sl->mtu = dev->mtu; sl->mtu = dev->mtu;
#endif
sl->dev->mem_start = (unsigned long) p; sl->dev->mem_start = (unsigned long) p;
sl->dev->mem_end = (unsigned long) (sl->dev->mem_start + l); sl->dev->mem_end = (unsigned long) (sl->dev->mem_start + l);
...@@ -655,7 +668,11 @@ static void slip_receive_buf(struct tty_struct *tty, unsigned char *cp, ...@@ -655,7 +668,11 @@ static void slip_receive_buf(struct tty_struct *tty, unsigned char *cp,
* Argh! mtu change time! - costs us the packet part received * Argh! mtu change time! - costs us the packet part received
* at the change * at the change
*/ */
#ifdef CONFIG_AX25
if(sl->mtu!=sl->dev->mtu+73)
#else
if(sl->mtu!=sl->dev->mtu) if(sl->mtu!=sl->dev->mtu)
#endif
sl_changedmtu(sl); sl_changedmtu(sl);
/* Read the characters out of the buffer */ /* Read the characters out of the buffer */
......
...@@ -121,7 +121,7 @@ Sat Aug 6 21:29:36 1994 Eric Youngdale (eric@andante) ...@@ -121,7 +121,7 @@ Sat Aug 6 21:29:36 1994 Eric Youngdale (eric@andante)
* g_NCR5380.c: * g_NCR5380.c:
* pas16.c: Correct usage of NCR5380_init. * pas16.c: Correct usage of NCR5380_init.
* scsi.c: Remove redunant (and unused variables). * scsi.c: Remove redundant (and unused variables).
* sd.c: Use memset to clear all of rscsi_disks before we use it. * sd.c: Use memset to clear all of rscsi_disks before we use it.
......
...@@ -88,7 +88,7 @@ aic7770-list@poplar1.cfr.washington.edu with a message body of: ...@@ -88,7 +88,7 @@ aic7770-list@poplar1.cfr.washington.edu with a message body of:
Please direct questions and discussions to that list instead of me. When Please direct questions and discussions to that list instead of me. When
sending bug reports, please include a description of your hardware, the sending bug reports, please include a description of your hardware, the
release numbers displayed by the driver at boot time, and as accurate a release numbers displayed by the driver at boot time, and as accurate a
facsimilie of any error message you're mailing about. facsimile of any error message you're mailing about.
John Aycock John Aycock
aycock@cpsc.ucalgary.ca aycock@cpsc.ucalgary.ca
...@@ -79,7 +79,7 @@ MTBSFM As above but ape positioned after filemark. ...@@ -79,7 +79,7 @@ MTBSFM As above but ape positioned after filemark.
MTFSR Space forward over count records. MTFSR Space forward over count records.
MTBSR Space backward over count records. MTBSR Space backward over count records.
MTFSS Space forward over count setmarks. MTFSS Space forward over count setmarks.
MTBSS Space backward over coutn setmarks. MTBSS Space backward over count setmarks.
MTWEOF Write count filemarks. MTWEOF Write count filemarks.
MTWSM Write count setmarks. MTWSM Write count setmarks.
MTREW Rewind tape. MTREW Rewind tape.
......
...@@ -176,7 +176,7 @@ start: ...@@ -176,7 +176,7 @@ start:
# into the message out phase since we have ATN asserted. Prepare # into the message out phase since we have ATN asserted. Prepare
# the message to send, locking out the device driver. If the device # the message to send, locking out the device driver. If the device
# driver hasn't beaten us with an ABORT or RESET message, then tack # driver hasn't beaten us with an ABORT or RESET message, then tack
# on a SDTR negotation if required. # on a SDTR negotiation if required.
# #
# Messages are stored in scratch RAM starting with a flag byte (high bit # Messages are stored in scratch RAM starting with a flag byte (high bit
# set means active message), one length byte, and then the message itself. # set means active message), one length byte, and then the message itself.
...@@ -812,7 +812,7 @@ assert1: ...@@ -812,7 +812,7 @@ assert1:
# Find out if disconnection is ok from the information the BIOS has left # Find out if disconnection is ok from the information the BIOS has left
# us. The target ID should be in the upper four bits of SINDEX; A will # us. The target ID should be in the upper four bits of SINDEX; A will
# contain either 0x40 (disconnection ok) or 0x00 (diconnection not ok) # contain either 0x40 (disconnection ok) or 0x00 (disconnection not ok)
# on exit. # on exit.
# #
# This is the only place the target ID is limited to three bits, so we # This is the only place the target ID is limited to three bits, so we
......
/* /*
* eata.c - Low-level SCSI driver for EISA EATA SCSI controllers. * eata.c - Low-level SCSI driver for EISA EATA SCSI controllers.
* *
* 18 Nov 1994 rev. 1.08 for linux 1.1.64
* Forces sg_tablesize = 64 and can_queue = 64 if these
* values are not correctly detected (DPT PM2012).
*
* 14 Nov 1994 rev. 1.07 for linux 1.1.63 Final BETA release. * 14 Nov 1994 rev. 1.07 for linux 1.1.63 Final BETA release.
* 04 Aug 1994 rev. 1.00 for linux 1.1.39 First BETA release. * 04 Aug 1994 rev. 1.00 for linux 1.1.39 First BETA release.
* *
...@@ -306,17 +310,23 @@ static inline int port_detect (ushort *port_base, unsigned int j, ...@@ -306,17 +310,23 @@ static inline int port_detect (ushort *port_base, unsigned int j,
irqlist[info.irq] = j; irqlist[info.irq] = j;
strcpy(BN(j), name); strcpy(BN(j), name);
if (sh[j]->sg_tablesize > MAX_SGLIST)
sh[j]->sg_tablesize = MAX_SGLIST;
if (sh[j]->can_queue > MAX_MAILBOXES)
sh[j]->can_queue = MAX_MAILBOXES;
printk("%s: SCSI ID %d, PORT 0x%03x, IRQ %u, SG %d, "\ printk("%s: SCSI ID %d, PORT 0x%03x, IRQ %u, SG %d, "\
"Mbox %d, CmdLun %d.\n", BN(j), sh[j]->this_id, "Mbox %d, CmdLun %d.\n", BN(j), sh[j]->this_id,
sh[j]->io_port, sh[j]->irq, sh[j]->sg_tablesize, sh[j]->io_port, sh[j]->irq, sh[j]->sg_tablesize,
sh[j]->can_queue, sh[j]->hostt->cmd_per_lun); sh[j]->can_queue, sh[j]->hostt->cmd_per_lun);
/* DPT PM2012 does not allow to detect sg_tablesize correctly */
if (sh[j]->sg_tablesize > MAX_SGLIST || sh[j]->sg_tablesize < 2) {
printk("%s: detect, forcing to use %d SG lists.\n", BN(j), MAX_SGLIST);
sh[j]->sg_tablesize = MAX_SGLIST;
}
/* DPT PM2012 does not allow to detect can_queue correctly */
if (sh[j]->can_queue > MAX_MAILBOXES || sh[j]->can_queue < 2) {
printk("%s: detect, forcing to use %d Mbox.\n", BN(j), MAX_MAILBOXES);
sh[j]->can_queue = MAX_MAILBOXES;
}
#if defined (DEBUG_DETECT) #if defined (DEBUG_DETECT)
printk("%s: Version 0x%x, SYNC 0x%x, infol %ld, cpl %ld spl %ld.\n", printk("%s: Version 0x%x, SYNC 0x%x, infol %ld, cpl %ld spl %ld.\n",
name, info.version, info.sync, ntohl(info.data_len), name, info.version, info.sync, ntohl(info.data_len),
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef _EISA_EATA_H #ifndef _EISA_EATA_H
#define _EISA_EATA_H #define _EISA_EATA_H
#define EATA_VERSION "1.07.00" #define EATA_VERSION "1.08.00"
int eata_detect(Scsi_Host_Template *); int eata_detect(Scsi_Host_Template *);
int eata_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int eata_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
......
...@@ -21,7 +21,14 @@ CAUTION! ...@@ -21,7 +21,14 @@ CAUTION!
This version of driver works with applications written and This version of driver works with applications written and
compiled for v2.*. The problem is that APPLICATIONS COMPILED compiled for v2.*. The problem is that APPLICATIONS COMPILED
WITH soundcard.h OF THIS VERSION WILL NOT WORK WITH OLDER DRIVER. WITH soundcard.h OF THIS VERSION WILL NOT WORK WITH OLDER DRIVER.
Be carefull when distributing applications compiled with this Be careful when distributing applications compiled with this
version (just the apps using /dev/sequencer are incompatible). version (just the apps using /dev/sequencer are incompatible).
*********************************************************
* IF YOU HAVE ANY PROBLEMS WITH THE SOUND DRIVER, *
* PLEASE READ THE SOUND-HOWTO. IT'S AVAILABLE FROM YOUR *
* NEAREST LINUX FTP SITE AND CONTAINS ANSWER TO YOUR *
* PROBLEM. *
*********************************************************
Hannu Hannu
...@@ -64,7 +64,7 @@ OBJS= open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \ ...@@ -64,7 +64,7 @@ OBJS= open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \
block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \ block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
select.o fifo.o locks.o filesystems.o dcache.o $(BINFMTS) select.o fifo.o locks.o filesystems.o dcache.o $(BINFMTS)
all: fs.o filesystems.a modules all: fs.o filesystems.a modules modules_fs
fs.o: $(OBJS) fs.o: $(OBJS)
$(LD) -r -o fs.o $(OBJS) $(LD) -r -o fs.o $(OBJS)
...@@ -80,6 +80,16 @@ ifdef MODULES ...@@ -80,6 +80,16 @@ ifdef MODULES
modules: modules:
$(MAKE) CFLAGS="$(CFLAGS) -DMODULE" $(MODULES) $(MAKE) CFLAGS="$(CFLAGS) -DMODULE" $(MODULES)
(cd ../modules;for i in $(MODULES); do ln -sf ../fs/$$i .; done) (cd ../modules;for i in $(MODULES); do ln -sf ../fs/$$i .; done)
else
modules:
endif
ifdef MODULE_FS_SUBDIRS
modules_fs:
set -e; for i in $(MODULE_FS_SUBDIRS); do \ set -e; for i in $(MODULE_FS_SUBDIRS); do \
test ! -d $$i || \ test ! -d $$i || \
{ $(MAKE) -C $$i; }; done { $(MAKE) -C $$i; }; done
...@@ -87,7 +97,7 @@ modules: ...@@ -87,7 +97,7 @@ modules:
else else
modules: modules_fs:
endif endif
......
...@@ -150,7 +150,7 @@ unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exe ...@@ -150,7 +150,7 @@ unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exe
/* This is much more generalized than the library routine read function, /* This is much more generalized than the library routine read function,
so we keep this separate. Techincally the library read function so we keep this separate. Technically the library read function
is only provided so that we can read a.out libraries that have is only provided so that we can read a.out libraries that have
an ELF header */ an ELF header */
......
...@@ -374,10 +374,10 @@ static int count(char ** argv) ...@@ -374,10 +374,10 @@ static int count(char ** argv)
int error, i = 0; int error, i = 0;
char ** tmp, *p; char ** tmp, *p;
error = verify_area(VERIFY_READ, argv, sizeof(char *)); if ((tmp = argv) != NULL) {
error = verify_area(VERIFY_READ, tmp, sizeof(char *));
if (error) if (error)
return error; return error;
if ((tmp = argv) != 0) {
while ((p = (char *) get_fs_long((unsigned long *) (tmp++))) != NULL) { while ((p = (char *) get_fs_long((unsigned long *) (tmp++))) != NULL) {
i++; i++;
error = verify_area(VERIFY_READ, p, 1); error = verify_area(VERIFY_READ, p, 1);
......
...@@ -359,8 +359,8 @@ int parse_rock_ridge_inode(struct iso_directory_record * de, ...@@ -359,8 +359,8 @@ int parse_rock_ridge_inode(struct iso_directory_record * de,
printk("RR CL (%x)\n",inode->i_ino); printk("RR CL (%x)\n",inode->i_ino);
#endif #endif
inode->u.isofs_i.i_first_extent = isonum_733(rr->u.CL.location) << inode->u.isofs_i.i_first_extent = isonum_733(rr->u.CL.location) <<
(ISOFS_BLOCK_BITS - ISOFS_BUFFER_BITS(inode)); inode -> i_sb -> u.isofs_sb.s_log_zone_size;
reloc = iget(inode->i_sb, inode->u.isofs_i.i_first_extent << ISOFS_BUFFER_BITS(inode)); reloc = iget(inode->i_sb, inode->u.isofs_i.i_first_extent);
inode->i_mode = reloc->i_mode; inode->i_mode = reloc->i_mode;
inode->i_nlink = reloc->i_nlink; inode->i_nlink = reloc->i_nlink;
inode->i_uid = reloc->i_uid; inode->i_uid = reloc->i_uid;
......
...@@ -103,9 +103,10 @@ int msdos_file_read( ...@@ -103,9 +103,10 @@ int msdos_file_read(
char *buf, char *buf,
int count) int count)
{ {
char *start; char *start = buf;
int left; char *end = buf + count;
int i; int i;
int left_in_file;
struct msdos_pre pre; struct msdos_pre pre;
...@@ -144,6 +145,7 @@ int msdos_file_read( ...@@ -144,6 +145,7 @@ int msdos_file_read(
/* pre read enough, since we don't know how many blocks */ /* pre read enough, since we don't know how many blocks */
/* we really need */ /* we really need */
int ahead = read_ahead[MAJOR(inode->i_dev)]; int ahead = read_ahead[MAJOR(inode->i_dev)];
PRINTK (("to_reada %d ahead %d\n",to_reada,ahead));
if (ahead == 0) ahead = 8; if (ahead == 0) ahead = 8;
to_reada += ahead; to_reada += ahead;
} }
...@@ -151,10 +153,10 @@ int msdos_file_read( ...@@ -151,10 +153,10 @@ int msdos_file_read(
pre.nblist = 0; pre.nblist = 0;
msdos_prefetch (inode,&pre,to_reada); msdos_prefetch (inode,&pre,to_reada);
} }
start = buf;
pre.nolist = 0; pre.nolist = 0;
PRINTK (("count %d ahead %d nblist %d\n",count,read_ahead[MAJOR(inode->i_dev)],pre.nblist)); PRINTK (("count %d ahead %d nblist %d\n",count,read_ahead[MAJOR(inode->i_dev)],pre.nblist));
while ((left = MIN(inode->i_size-filp->f_pos,count-(buf-start))) > 0){ while ((left_in_file = inode->i_size - filp->f_pos) > 0
&& buf < end){
struct buffer_head *bh = pre.bhlist[pre.nolist]; struct buffer_head *bh = pre.bhlist[pre.nolist];
char *data; char *data;
int size,offset; int size,offset;
...@@ -176,15 +178,17 @@ int msdos_file_read( ...@@ -176,15 +178,17 @@ int msdos_file_read(
break; break;
} }
offset = filp->f_pos & (SECTOR_SIZE-1); offset = filp->f_pos & (SECTOR_SIZE-1);
filp->f_pos += (size = MIN(SECTOR_SIZE-offset,left));
data = bh->b_data + offset; data = bh->b_data + offset;
size = MIN(SECTOR_SIZE-offset,left_in_file);
if (MSDOS_I(inode)->i_binary) { if (MSDOS_I(inode)->i_binary) {
size = MIN(size,end-buf);
memcpy_tofs(buf,data,size); memcpy_tofs(buf,data,size);
buf += size; buf += size;
filp->f_pos += size;
}else{ }else{
int cnt; for (; size && buf < end; size--) {
for (cnt = size; cnt; cnt--) {
char ch = *data++; char ch = *data++;
filp->f_pos++;
if (ch == 26){ if (ch == 26){
filp->f_pos = inode->i_size; filp->f_pos = inode->i_size;
break; break;
...@@ -199,7 +203,6 @@ int msdos_file_read( ...@@ -199,7 +203,6 @@ int msdos_file_read(
for (i=0; i<pre.nblist; i++) brelse (pre.bhlist[i]); for (i=0; i<pre.nblist; i++) brelse (pre.bhlist[i]);
if (start == buf) return -EIO; if (start == buf) return -EIO;
if (!IS_RDONLY(inode)) inode->i_atime = CURRENT_TIME; if (!IS_RDONLY(inode)) inode->i_atime = CURRENT_TIME;
PRINTK (("file_read ret %d\n",(buf-start)));
filp->f_reada = 1; /* Will be reset if a lseek is done */ filp->f_reada = 1; /* Will be reset if a lseek is done */
return buf-start; return buf-start;
} }
......
...@@ -483,13 +483,10 @@ int init_module(void) ...@@ -483,13 +483,10 @@ int init_module(void)
void cleanup_module(void) void cleanup_module(void)
{ {
if (MOD_IN_USE) if (MOD_IN_USE)
printk("ne: device busy, remove delayed\n"); printk("msdos: device busy, remove delayed\n");
else else
{ {
unregister_filesystem(&msdos_fs_type); unregister_filesystem(&msdos_fs_type);
/* This is not clear why the floppy drivers does not initialise */
/* the table, but we left it the way we saw it first */
blksize_size[FLOPPY_MAJOR] = NULL;
} }
} }
......
...@@ -122,7 +122,7 @@ int permission(struct inode * inode,int mask) ...@@ -122,7 +122,7 @@ int permission(struct inode * inode,int mask)
* put_write_access() releases this write permission. * put_write_access() releases this write permission.
* This is used for regular files. * This is used for regular files.
* We cannot support write (and maybe mmap read-write shared) accesses and * We cannot support write (and maybe mmap read-write shared) accesses and
* MAP_DENYWRITE mmapings simultaneously. * MAP_DENYWRITE mmappings simultaneously.
*/ */
int get_write_access(struct inode * inode) int get_write_access(struct inode * inode)
{ {
...@@ -527,7 +527,7 @@ static int do_mkdir(const char * pathname, int mode) ...@@ -527,7 +527,7 @@ static int do_mkdir(const char * pathname, int mode)
} }
dir->i_count++; dir->i_count++;
down(&dir->i_sem); down(&dir->i_sem);
error = dir->i_op->mkdir(dir,basename,namelen,mode); error = dir->i_op->mkdir(dir, basename, namelen, mode & 0777 & ~current->fs->umask);
up(&dir->i_sem); up(&dir->i_sem);
iput(dir); iput(dir);
return error; return error;
......
...@@ -71,15 +71,15 @@ static int nfs_follow_link(struct inode *dir, struct inode *inode, ...@@ -71,15 +71,15 @@ static int nfs_follow_link(struct inode *dir, struct inode *inode,
} }
error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), &mem, error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), &mem,
&res, &len, NFS_MAXPATHLEN); &res, &len, NFS_MAXPATHLEN);
while ((res2 = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_NFS)) == NULL) {
schedule();
}
if (error) { if (error) {
iput(inode); iput(inode);
iput(dir); iput(dir);
kfree(mem); kfree(mem);
return error; return error;
} }
while ((res2 = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_NFS)) == NULL) {
schedule();
}
memcpy(res2, res, len); memcpy(res2, res, len);
res2[len] = '\0'; res2[len] = '\0';
kfree(mem); kfree(mem);
......
...@@ -410,7 +410,7 @@ struct super_block *UMSDOS_read_super( ...@@ -410,7 +410,7 @@ struct super_block *UMSDOS_read_super(
msdos directory, with all limitation of msdos. msdos directory, with all limitation of msdos.
*/ */
struct super_block *sb = msdos_read_super(s,data,silent); struct super_block *sb = msdos_read_super(s,data,silent);
printk ("UMSDOS Alpha 0.5 (compatibility level %d.%d, fast msdos)\n" printk ("UMSDOS Alpha 0.5a (compatibility level %d.%d, fast msdos)\n"
,UMSDOS_VERSION,UMSDOS_RELEASE); ,UMSDOS_VERSION,UMSDOS_RELEASE);
if (sb != NULL){ if (sb != NULL){
sb->s_op = &umsdos_sops; sb->s_op = &umsdos_sops;
......
...@@ -838,7 +838,9 @@ int UMSDOS_rmdir( ...@@ -838,7 +838,9 @@ int UMSDOS_rmdir(
if (ret == 0){ if (ret == 0){
int empty; int empty;
umsdos_lockcreate(dir); umsdos_lockcreate(dir);
if ((empty = umsdos_isempty (sdir)) != 0){ if (sdir->i_count > 1){
ret = -EBUSY;
}else if ((empty = umsdos_isempty (sdir)) != 0){
PRINTK (("isempty %d i_count %d ",empty,sdir->i_count)); PRINTK (("isempty %d i_count %d ",empty,sdir->i_count));
if (empty == 1){ if (empty == 1){
/* We have to removed the EMD file */ /* We have to removed the EMD file */
......
...@@ -84,7 +84,7 @@ extern __inline__ unsigned long test_bit(int nr, void * addr) ...@@ -84,7 +84,7 @@ extern __inline__ unsigned long test_bit(int nr, void * addr)
/* /*
* ffz = Find First Zero in word. Undefined if no zero exists, * ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check agains ~0UL first.. * so code should check against ~0UL first..
* *
* This uses the cmpbge insn to check which byte contains the zero. * This uses the cmpbge insn to check which byte contains the zero.
* I don't know if that's actually a good idea, but it's fun and the * I don't know if that's actually a good idea, but it's fun and the
......
#ifndef __ALPHA_IO_H
#define __ALPHA_IO_H
/*
* Defines for the AlphaPC EISA IO and memory address space.
*/
#ifndef mb
#define mb() __asm__ __volatile__("mb": : :"memory")
#endif
/*
* NOTE! Currently it never uses the HAE register, so these work only
* for the low 25 bits of EISA addressing. That covers all of the IO
* address space (16 bits), and most of the "normal" EISA memory space.
* I'll fix it eventually, but I'll need to come up with a clean way
* to handle races with interrupt services wanting to change HAE...
*/
/*
* NOTE 2! The memory operations do not set any memory barriers, as it's
* not needed for cases like a frame buffer that is essentially memory-like.
* You need to do them by hand if the operations depend on ordering.
*
* Similarly, the port IO operations do a "mb" only after a write operation:
* if an mb is needed before (as in the case of doing memory mapped IO
* first, and then a port IO operation to the same device), it needs to be
* done by hand.
*
* After the above has bitten me 100 times, I'll give up and just do the
* mb all the time, but right now I'm hoping this will work out. Avoiding
* mb's may potentially be a noticeable speed improvement, but I can't
* honestly say I've tested it.
*
* Handling interrupts that need to do mb's to synchronize to non-interrupts
* is another fun race area. Don't do it (because if you do, I'll have to
* do *everything* with interrupts disabled, ugh).
*/
/*
* Virtual -> physical identity mapping starts at this offset
*/
#define IDENT_ADDR (0xfffffc0000000000UL)
/*
* EISA Interrupt Acknowledge address
*/
#define EISA_INTA (IDENT_ADDR + 0x100000000UL)
/*
* FEPROM addresses
*/
#define EISA_FEPROM0 (IDENT_ADDR + 0x180000000UL)
#define EISA_FEPROM1 (IDENT_ADDR + 0x1A0000000UL)
/*
* VL82C106 base address
*/
#define EISA_VL82C106 (IDENT_ADDR + 0x1C0000000UL)
/*
* EISA "Host Address Extension" address (bits 25-31 of the EISA address)
*/
#define EISA_HAE (IDENT_ADDR + 0x1D0000000UL)
/*
* "SYSCTL" register address
*/
#define EISA_SYSCTL (IDENT_ADDR + 0x1E0000000UL)
/*
* "spare" register address
*/
#define EISA_SPARE (IDENT_ADDR + 0x1F0000000UL)
/*
* EISA memory address offset
*/
#define EISA_MEM (IDENT_ADDR + 0x200000000UL)
/*
* EISA IO address offset
*/
#define EISA_IO (IDENT_ADDR + 0x300000000UL)
/*
* IO functions
*
* The "local" functions are those that don't go out to the EISA bus,
* but instead act on the VL82C106 chip directly.. This is mainly the
* keyboard, RTC, printer and first two serial lines..
*/
extern inline unsigned long inb_local(unsigned long addr)
{
long result = *(volatile int *) ((addr << 9) + EISA_VL82C106);
return 0xffUL & result;
}
extern inline void outb_local(unsigned char b, unsigned long addr)
{
*(volatile unsigned int *) ((addr << 9) + EISA_VL82C106) = b;
mb();
}
extern inline unsigned long inb(unsigned long addr)
{
long result = *(volatile int *) ((addr << 7) + EISA_IO + 0x00);
result >>= (addr & 3) * 8;
return 0xffUL & result;
}
extern inline unsigned long inw(unsigned long addr)
{
long result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
result >>= (addr & 3) * 8;
return 0xffffUL & result;
}
extern inline unsigned long inl(unsigned long addr)
{
return *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x60);
}
extern inline void outb(unsigned char b, unsigned long addr)
{
*(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
mb();
}
extern inline void outw(unsigned short b, unsigned long addr)
{
*(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
mb();
}
extern inline void outl(unsigned int b, unsigned long addr)
{
*(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x60) = b;
mb();
}
/*
* Memory functions
*/
extern inline unsigned long readb(unsigned long addr)
{
long result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
result >>= (addr & 3) * 8;
return 0xffUL & result;
}
extern inline unsigned long readw(unsigned long addr)
{
long result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
result >>= (addr & 3) * 8;
return 0xffffUL & result;
}
extern inline unsigned long readl(unsigned long addr)
{
return *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x60);
}
extern inline void writeb(unsigned short b, unsigned long addr)
{
*(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
}
extern inline void writew(unsigned short b, unsigned long addr)
{
*(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
}
extern inline void writel(unsigned int b, unsigned long addr)
{
*(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x60) = b;
}
#endif
#ifndef __ALPHA_STRING_H
#define __ALPHA_STRING_H
/* This doesn't actually work that well for unaligned stuff ;-p */
extern inline void * memcpy(void * to, const void * from, size_t n)
{
const unsigned long * f = from;
unsigned long * t = to;
int size = n;
for (;;) {
size -= 8;
if (size < 0)
return to;
*(t++) = *(f++);
}
}
#endif
#ifndef __ALPHA_SYSTEM_H #ifndef __ALPHA_SYSTEM_H
#define __ALPHA_SYSTEM_H #define __ALPHA_SYSTEM_H
/*
* System defines.. Note that this is included both from .c and .S
* files, so it does only defines, not any C code.
*/
/*
* We leave one page for the initial stack page, and one page for
* the initial process structure. Also, the console eats 3 MB for
* the initial bootloader (one of which we can reclaim later).
* So the initial load address is 0xfffffc0000304000UL
*/
#define INIT_PCB 0xfffffc0000300000
#define INIT_STACK 0xfffffc0000302000
#define START_ADDR 0xfffffc0000304000
#define SIZE (32*1024)
/* /*
* Common PAL-code * Common PAL-code
*/ */
...@@ -18,6 +34,12 @@ ...@@ -18,6 +34,12 @@
#define PAL_gentrap 170 #define PAL_gentrap 170
#define PAL_nphalt 190 #define PAL_nphalt 190
/*
* VMS specific PAL-code
*/
#define PAL_swppal 10
#define PAL_mfpr_vptb 41
/* /*
* OSF specific PAL-code * OSF specific PAL-code
*/ */
...@@ -40,6 +62,10 @@ ...@@ -40,6 +62,10 @@
#define PAL_rtsys 61 #define PAL_rtsys 61
#define PAL_rti 63 #define PAL_rti 63
#ifndef mb
#define mb() __asm__ __volatile__("mb": : :"memory")
#endif
#define invalidate_all() \ #define invalidate_all() \
__asm__ __volatile__( \ __asm__ __volatile__( \
"lda $16,-2($31)\n\t" \ "lda $16,-2($31)\n\t" \
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#define IOCPARM_SHIFT IOCCMD_SHIFT #define IOCPARM_SHIFT IOCCMD_SHIFT
#define IOC_SIZE(cmd) (((cmd) & IOCSIZE_MASK) >> IOCSIZE_SHIFT) #define IOC_SIZE(cmd) (((cmd) & IOCSIZE_MASK) >> IOCSIZE_SHIFT)
#define IOCBASECMD(cmd) ((cmd) & ~IOOCPARM_MASK #define IOCBASECMD(cmd) ((cmd) & ~IOCPARM_MASK)
#define IOCGROUP(cmd) (((cmd) >> 8) & 0xFF) #define IOCGROUP(cmd) (((cmd) >> 8) & 0xFF)
/* _IO(magic, subcode); size field is zero and the /* _IO(magic, subcode); size field is zero and the
......
...@@ -51,7 +51,7 @@ struct unimapdesc { ...@@ -51,7 +51,7 @@ struct unimapdesc {
struct unipair *entries; struct unipair *entries;
}; };
#define PIO_UNIMAP 0x4B67 /* put unicode-to-font mapping in kernel */ #define PIO_UNIMAP 0x4B67 /* put unicode-to-font mapping in kernel */
#define PIO_UNIMAPCLR 0x4B68 /* clear table, possibly advise hashalgorithm */ #define PIO_UNIMAPCLR 0x4B68 /* clear table, possibly advise hash algorithm */
struct unimapinit { struct unimapinit {
u_short advised_hashsize; /* 0 if no opinion */ u_short advised_hashsize; /* 0 if no opinion */
u_short advised_hashstep; /* 0 if no opinion */ u_short advised_hashstep; /* 0 if no opinion */
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#define IS_LOOPBACK 2 /* address is for LOOPBACK */ #define IS_LOOPBACK 2 /* address is for LOOPBACK */
#define IS_BROADCAST 3 /* address is a valid broadcast */ #define IS_BROADCAST 3 /* address is a valid broadcast */
#define IS_INVBCAST 4 /* Wrong netmask bcast not for us (unused)*/ #define IS_INVBCAST 4 /* Wrong netmask bcast not for us (unused)*/
#define IS_MULTICAST 5 /* Multicast IP address */
/* /*
* The DEVICE structure. * The DEVICE structure.
......
...@@ -159,7 +159,7 @@ struct termios { ...@@ -159,7 +159,7 @@ struct termios {
#define FF1 0100000 #define FF1 0100000
/* c_cflag bit meaning */ /* c_cflag bit meaning */
#define CBAUD 0000017 #define CBAUD 0010017
#define B0 0000000 /* hang up */ #define B0 0000000 /* hang up */
#define B50 0000001 #define B50 0000001
#define B75 0000002 #define B75 0000002
...@@ -189,7 +189,10 @@ struct termios { ...@@ -189,7 +189,10 @@ struct termios {
#define PARODD 0001000 #define PARODD 0001000
#define HUPCL 0002000 #define HUPCL 0002000
#define CLOCAL 0004000 #define CLOCAL 0004000
#define CIBAUD 03600000 /* input baud rate (not used) */ #define CBAUDEX 0010000
#define B57600 0010001
#define B115200 0010002
#define CIBAUD 002003600000 /* input baud rate (not used) */
#define CRTSCTS 020000000000 /* flow control */ #define CRTSCTS 020000000000 /* flow control */
/* c_lflag bits */ /* c_lflag bits */
...@@ -222,7 +225,7 @@ struct termios { ...@@ -222,7 +225,7 @@ struct termios {
#define TIOCM_CD TIOCM_CAR #define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG #define TIOCM_RI TIOCM_RNG
/* ioctl (fd, TIOCSERGTLSR, &result) where result may be as below */ /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
......
...@@ -456,11 +456,11 @@ asmlinkage void start_kernel(void) ...@@ -456,11 +456,11 @@ asmlinkage void start_kernel(void)
memory_start = blk_dev_init(memory_start,memory_end); memory_start = blk_dev_init(memory_start,memory_end);
sti(); sti();
calibrate_delay(); calibrate_delay();
#ifdef CONFIG_INET
memory_start = net_dev_init(memory_start,memory_end);
#endif
#ifdef CONFIG_SCSI #ifdef CONFIG_SCSI
memory_start = scsi_dev_init(memory_start,memory_end); memory_start = scsi_dev_init(memory_start,memory_end);
#endif
#ifdef CONFIG_INET
memory_start = net_dev_init(memory_start,memory_end);
#endif #endif
memory_start = inode_init(memory_start,memory_end); memory_start = inode_init(memory_start,memory_end);
memory_start = file_table_init(memory_start,memory_end); memory_start = file_table_init(memory_start,memory_end);
......
...@@ -1042,6 +1042,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -1042,6 +1042,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (wp_works_ok < 0 && address == TASK_SIZE && (error_code & PAGE_PRESENT)) { if (wp_works_ok < 0 && address == TASK_SIZE && (error_code & PAGE_PRESENT)) {
wp_works_ok = 1; wp_works_ok = 1;
pg0[0] = PAGE_SHARED; pg0[0] = PAGE_SHARED;
invalidate();
printk("This processor honours the WP bit even when in supervisor mode. Good.\n"); printk("This processor honours the WP bit even when in supervisor mode. Good.\n");
return; return;
} }
......
...@@ -55,7 +55,6 @@ static inline int mprotect_fixup_all(struct vm_area_struct * vma, ...@@ -55,7 +55,6 @@ static inline int mprotect_fixup_all(struct vm_area_struct * vma,
{ {
vma->vm_flags = newflags; vma->vm_flags = newflags;
vma->vm_page_prot = prot; vma->vm_page_prot = prot;
merge_segments(current->mm->mmap);
return 0; return 0;
} }
...@@ -79,7 +78,6 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma, ...@@ -79,7 +78,6 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma,
if (n->vm_ops && n->vm_ops->open) if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n); n->vm_ops->open(n);
insert_vm_struct(current, n); insert_vm_struct(current, n);
merge_segments(current->mm->mmap);
return 0; return 0;
} }
...@@ -103,7 +101,6 @@ static inline int mprotect_fixup_end(struct vm_area_struct * vma, ...@@ -103,7 +101,6 @@ static inline int mprotect_fixup_end(struct vm_area_struct * vma,
if (n->vm_ops && n->vm_ops->open) if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n); n->vm_ops->open(n);
insert_vm_struct(current, n); insert_vm_struct(current, n);
merge_segments(current->mm->mmap);
return 0; return 0;
} }
...@@ -139,7 +136,6 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma, ...@@ -139,7 +136,6 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma,
} }
insert_vm_struct(current, left); insert_vm_struct(current, left);
insert_vm_struct(current, right); insert_vm_struct(current, right);
merge_segments(current->mm->mmap);
return 0; return 0;
} }
...@@ -179,7 +175,8 @@ static int mprotect_fixup(struct vm_area_struct * vma, ...@@ -179,7 +175,8 @@ static int mprotect_fixup(struct vm_area_struct * vma,
asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot) asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot)
{ {
unsigned long end, tmp; unsigned long end, tmp;
struct vm_area_struct * vma; struct vm_area_struct * vma, * next;
int error;
if (start & ~PAGE_MASK) if (start & ~PAGE_MASK)
return -EINVAL; return -EINVAL;
...@@ -201,27 +198,33 @@ asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot) ...@@ -201,27 +198,33 @@ asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot)
return -EFAULT; return -EFAULT;
for ( ; ; ) { for ( ; ; ) {
int error;
unsigned int newflags; unsigned int newflags;
/* Here we know that vma->vm_start <= start < vma->vm_end. */
newflags = prot | (vma->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC)); newflags = prot | (vma->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
if ((newflags & ~(newflags >> 4)) & 0xf) if ((newflags & ~(newflags >> 4)) & 0xf) {
return -EACCES; error = -EACCES;
break;
}
if (vma->vm_end >= end) if (vma->vm_end >= end) {
return mprotect_fixup(vma, start, end, newflags); error = mprotect_fixup(vma, start, end, newflags);
break;
}
tmp = vma->vm_end; tmp = vma->vm_end;
next = vma->vm_next;
error = mprotect_fixup(vma, start, tmp, newflags); error = mprotect_fixup(vma, start, tmp, newflags);
if (error) if (error)
return error; break;
start = tmp; start = tmp;
if (vma->vm_end <= start) { vma = next;
vma = vma->vm_next; if (!vma || vma->vm_start != start) {
if (vma && vma->vm_start < start) error = -EFAULT;
vma = vma->vm_next; break;
if (!vma || vma->vm_start != start)
return -EFAULT;
} }
} }
merge_segments(current->mm->mmap);
return error;
} }
...@@ -151,6 +151,8 @@ int ip_chk_addr(unsigned long addr) ...@@ -151,6 +151,8 @@ int ip_chk_addr(unsigned long addr)
return IS_BROADCAST; return IS_BROADCAST;
} }
} }
if(IN_MULTICAST(addr))
return IS_MULTICAST;
return 0; /* no match at all */ return 0; /* no match at all */
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
* Ulrich Kunitz : Fixed ICMP timestamp reply * Ulrich Kunitz : Fixed ICMP timestamp reply
* A.N.Kuznetsov : Multihoming fixes. * A.N.Kuznetsov : Multihoming fixes.
* Laco Rusnak : Multihoming fixes. * Laco Rusnak : Multihoming fixes.
* Alan Cox : Tightened up icmp_send().
* *
* *
* *
...@@ -100,6 +101,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev) ...@@ -100,6 +101,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
struct icmphdr *icmph; struct icmphdr *icmph;
int len; int len;
struct device *ndev=NULL; /* Make this =dev to force replies on the same interface */ struct device *ndev=NULL; /* Make this =dev to force replies on the same interface */
unsigned long our_addr;
int atype;
/* /*
* Find the original IP header. * Find the original IP header.
...@@ -107,6 +110,28 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev) ...@@ -107,6 +110,28 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
iph = (struct iphdr *) (skb_in->data + dev->hard_header_len); iph = (struct iphdr *) (skb_in->data + dev->hard_header_len);
/*
* No replies to MAC multicast
*/
if(skb_in->pkt_type!=PACKET_HOST)
return;
/*
* No replies to IP multicasting
*/
atype=ip_chk_addr(iph->daddr);
if(atype==IS_BROADCAST || IN_MULTICAST(iph->daddr))
return;
/*
* Only reply to first fragment.
*/
if(ntohs(iph->frag_off)&IP_OFFSET)
return;
/* /*
* We must NEVER NEVER send an ICMP error to an ICMP error message * We must NEVER NEVER send an ICMP error to an ICMP error message
*/ */
...@@ -178,14 +203,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev) ...@@ -178,14 +203,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
* Build Layer 2-3 headers for message back to source. * Build Layer 2-3 headers for message back to source.
*/ */
{ unsigned long our_addr = dev->pa_addr; our_addr = dev->pa_addr;
if (iph->daddr != our_addr && ip_chk_addr(iph->daddr) == IS_MYADDR) if (iph->daddr != our_addr && ip_chk_addr(iph->daddr) == IS_MYADDR)
our_addr = iph->daddr; our_addr = iph->daddr;
offset = ip_build_header(skb, our_addr, iph->saddr, offset = ip_build_header(skb, our_addr, iph->saddr,
&ndev, IPPROTO_ICMP, NULL, len, &ndev, IPPROTO_ICMP, NULL, len,
skb_in->ip_hdr->tos,255); skb_in->ip_hdr->tos,255);
}
if (offset < 0) if (offset < 0)
{ {
icmp_statistics.IcmpOutErrors++; icmp_statistics.IcmpOutErrors++;
......
...@@ -1486,15 +1486,17 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -1486,15 +1486,17 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
* Remember if the frame is fragmented. * Remember if the frame is fragmented.
*/ */
if(iph->frag_off)
{
if (iph->frag_off & 0x0020) if (iph->frag_off & 0x0020)
is_frag|=1; is_frag|=1;
/* /*
* Last fragment ? * Last fragment ?
*/ */
if (ntohs(iph->frag_off) & 0x1fff) if (ntohs(iph->frag_off) & 0x1fff)
is_frag|=2; is_frag|=2;
}
/* /*
* Do any IP forwarding required. chk_addr() is expensive -- avoid it someday. * Do any IP forwarding required. chk_addr() is expensive -- avoid it someday.
...@@ -1514,7 +1516,7 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -1514,7 +1516,7 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
* Don't forward multicast or broadcast frames. * Don't forward multicast or broadcast frames.
*/ */
if(skb->pkt_type!=PACKET_HOST) if(skb->pkt_type!=PACKET_HOST || brd==IS_BROADCAST)
{ {
kfree_skb(skb,FREE_WRITE); kfree_skb(skb,FREE_WRITE);
return 0; return 0;
...@@ -1613,7 +1615,7 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -1613,7 +1615,7 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
if (!flag) if (!flag)
{ {
if (brd != IS_BROADCAST) if (brd != IS_BROADCAST && brd!=IS_MULTICAST)
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
kfree_skb(skb, FREE_WRITE); kfree_skb(skb, FREE_WRITE);
} }
......
...@@ -948,18 +948,12 @@ int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) ...@@ -948,18 +948,12 @@ int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
if (sock->ipx_source_addr.net == 0L) if (sock->ipx_source_addr.net == 0L)
sock->ipx_source_addr.net = ln->net; sock->ipx_source_addr.net = ln->net;
if(sock->rmem_alloc>=sock->rcvbuf) if(sock_queue_rcv_skb(sock, skb)<0)
{ {
kfree_skb(skb,FREE_READ); /* Socket is full */ kfree_skb(skb,FREE_READ); /* Socket is full */
return(0); return(0);
} }
sock->rmem_alloc+=skb->mem_len;
skb->sk = sock;
skb_queue_tail(&sock->receive_queue,skb);
if(!sock->dead)
sock->data_ready(sock,skb->len);
return(0); return(0);
} }
......
...@@ -125,7 +125,7 @@ int raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -125,7 +125,7 @@ int raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
/* Charge it to the socket. */ /* Charge it to the socket. */
if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) if(sock_queue_rcv_skb(sk,skb)<0)
{ {
ip_statistics.IpInDiscards++; ip_statistics.IpInDiscards++;
skb->sk=NULL; skb->sk=NULL;
...@@ -133,10 +133,7 @@ int raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -133,10 +133,7 @@ int raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
return(0); return(0);
} }
sk->rmem_alloc += skb->mem_len;
ip_statistics.IpInDelivers++; ip_statistics.IpInDelivers++;
skb_queue_tail(&sk->receive_queue,skb);
sk->data_ready(sk,skb->len);
release_sock(sk); release_sock(sk);
return(0); return(0);
} }
...@@ -189,41 +186,10 @@ static int raw_sendto(struct sock *sk, unsigned char *from, ...@@ -189,41 +186,10 @@ static int raw_sendto(struct sock *sk, unsigned char *from,
if (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST) if (sk->broadcast == 0 && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
return -EACCES; return -EACCES;
sk->inuse = 1; skb=sock_alloc_send_skb(sk, len+sk->prot->max_header, noblock, &err);
skb = NULL; if(skb==NULL)
while (skb == NULL) return err;
{
if(sk->err!=0)
{
err= -sk->err;
sk->err=0;
release_sock(sk);
return(err);
}
skb = sk->prot->wmalloc(sk,
len + sk->prot->max_header,
0, GFP_KERNEL);
if (skb == NULL)
{
int tmp;
if (noblock)
return(-EAGAIN);
tmp = sk->wmem_alloc;
release_sock(sk);
cli();
if (tmp <= sk->wmem_alloc) {
interruptible_sleep_on(sk->sleep);
if (current->signal & ~current->blocked) {
sti();
return(-ERESTARTSYS);
}
}
sk->inuse = 1;
sti();
}
}
skb->sk = sk; skb->sk = sk;
skb->free = 1; skb->free = 1;
skb->localroute = sk->localroute | (flags&MSG_DONTROUTE); skb->localroute = sk->localroute | (flags&MSG_DONTROUTE);
......
...@@ -406,6 +406,93 @@ void sock_rfree(struct sock *sk, struct sk_buff *skb, unsigned long size) ...@@ -406,6 +406,93 @@ void sock_rfree(struct sock *sk, struct sk_buff *skb, unsigned long size)
} }
} }
/*
* Generic send/receive buffer handlers
*/
struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, int noblock, int *errcode)
{
struct sk_buff *skb;
int err;
sk->inuse=1;
do
{
if(sk->err!=0)
{
cli();
err= -sk->err;
sk->err=0;
sti();
*errcode=err;
return NULL;
}
if(sk->shutdown&SEND_SHUTDOWN)
{
*errcode=-EPIPE;
return NULL;
}
skb = sock_wmalloc(sk, size, 0, GFP_KERNEL);
if(skb==NULL)
{
unsigned long tmp;
if(noblock)
{
*errcode=-EAGAIN;
return NULL;
}
if(sk->shutdown&SEND_SHUTDOWN)
{
*errcode=-EPIPE;
return NULL;
}
tmp = sk->wmem_alloc;
cli();
if(sk->shutdown&SEND_SHUTDOWN)
{
sti();
*errcode=-EPIPE;
return NULL;
}
if( tmp <= sk->wmem_alloc)
{
interruptible_sleep_on(sk->sleep);
if (current->signal & ~current->blocked)
{
sti();
*errcode = -ERESTARTSYS;
return NULL;
}
}
sti();
}
}
while(skb==NULL);
return skb;
}
/*
* Queue a received datagram if it will fit. Stream and sequenced protocols
* can't normally use this as they need to fit buffers in and play with them.
*/
int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
if(sk->rmem_alloc + skb->mem_len >= sk->rcvbuf)
return -ENOMEM;
sk->rmem_alloc+=skb->mem_len;
skb->sk=sk;
skb_queue_tail(&sk->receive_queue,skb);
if(!sk->dead)
sk->data_ready(sk,skb->len);
return 0;
}
void release_sock(struct sock *sk) void release_sock(struct sock *sk)
{ {
......
...@@ -271,7 +271,10 @@ extern unsigned long sock_rspace(struct sock *sk); ...@@ -271,7 +271,10 @@ extern unsigned long sock_rspace(struct sock *sk);
extern unsigned long sock_wspace(struct sock *sk); extern unsigned long sock_wspace(struct sock *sk);
extern int sock_setsockopt(struct sock *sk,int level,int op,char *optval,int optlen); extern int sock_setsockopt(struct sock *sk,int level,int op,char *optval,int optlen);
extern int sock_getsockopt(struct sock *sk,int level,int op,char *optval,int *optlen); extern int sock_getsockopt(struct sock *sk,int level,int op,char *optval,int *optlen);
extern struct sk_buff *sock_alloc_send_skb(struct sock *skb, unsigned long size, int noblock, int *errcode);
extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
/* declarations from timer.c */ /* declarations from timer.c */
extern struct sock *timer_base; extern struct sock *timer_base;
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
* Alan Cox : Fixed assorted sk->rqueue->next errors * Alan Cox : Fixed assorted sk->rqueue->next errors
* Alan Cox : PSH doesn't end a TCP read. Switched a bit to skb ops. * Alan Cox : PSH doesn't end a TCP read. Switched a bit to skb ops.
* Alan Cox : Tidied tcp_data to avoid a potential nasty. * Alan Cox : Tidied tcp_data to avoid a potential nasty.
* Alan Cox : Added some beter commenting, as the tcp is hard to follow * Alan Cox : Added some better commenting, as the tcp is hard to follow
* Alan Cox : Removed incorrect check for 20 * psh * Alan Cox : Removed incorrect check for 20 * psh
* Michael O'Reilly : ack < copied bug fix. * Michael O'Reilly : ack < copied bug fix.
* Johannes Stille : Misc tcp fixes (not all in yet). * Johannes Stille : Misc tcp fixes (not all in yet).
...@@ -94,6 +94,13 @@ ...@@ -94,6 +94,13 @@
* accept() and async I/O. * accept() and async I/O.
* Alan Cox : Relaxed the rules on tcp_sendto(). * Alan Cox : Relaxed the rules on tcp_sendto().
* Yury Shevchuk : Really fixed accept() blocking problem. * Yury Shevchuk : Really fixed accept() blocking problem.
* Craig I. Hagan : Allow for BSD compatible TIME_WAIT for
* clients/servers which listen in on
* fixed ports.
* Alan Cox : Cleaned the above up and shrank it to
* a sensible code size.
* Alan Cox : Self connect lockup fix.
* Alan Cox : No connect to multicast.
* *
* *
* To Fix: * To Fix:
...@@ -1413,27 +1420,8 @@ static void cleanup_rbuf(struct sock *sk) ...@@ -1413,27 +1420,8 @@ static void cleanup_rbuf(struct sock *sk)
static int tcp_read_urg(struct sock * sk, int nonblock, static int tcp_read_urg(struct sock * sk, int nonblock,
unsigned char *to, int len, unsigned flags) unsigned char *to, int len, unsigned flags)
{ {
#ifdef NOTDEF
struct wait_queue wait = { current, NULL };
#endif
while (len > 0)
{
if (sk->urginline || !sk->urg_data || sk->urg_data == URG_READ) if (sk->urginline || !sk->urg_data || sk->urg_data == URG_READ)
return -EINVAL; return -EINVAL;
sk->inuse = 1;
if (sk->urg_data & URG_VALID)
{
char c = sk->urg_data;
if (!(flags & MSG_PEEK))
sk->urg_data = URG_READ;
put_fs_byte(c, to);
release_sock(sk);
return 1;
}
release_sock(sk);
if (sk->err) if (sk->err)
{ {
int tmp = -sk->err; int tmp = -sk->err;
...@@ -1455,6 +1443,17 @@ static int tcp_read_urg(struct sock * sk, int nonblock, ...@@ -1455,6 +1443,17 @@ static int tcp_read_urg(struct sock * sk, int nonblock,
sk->done = 1; sk->done = 1;
return 0; return 0;
} }
sk->inuse = 1;
if (sk->urg_data & URG_VALID)
{
char c = sk->urg_data;
if (!(flags & MSG_PEEK))
sk->urg_data = URG_READ;
put_fs_byte(c, to);
release_sock(sk);
return 1;
}
release_sock(sk);
/* /*
* Fixed the recv(..., MSG_OOB) behaviour. BSD docs and * Fixed the recv(..., MSG_OOB) behaviour. BSD docs and
...@@ -1464,24 +1463,6 @@ static int tcp_read_urg(struct sock * sk, int nonblock, ...@@ -1464,24 +1463,6 @@ static int tcp_read_urg(struct sock * sk, int nonblock,
* Mike <pall@rz.uni-karlsruhe.de> * Mike <pall@rz.uni-karlsruhe.de>
*/ */
return -EAGAIN; return -EAGAIN;
#ifdef NOTDEF
/* remove the loop, if this dead code gets removed! */
if (nonblock)
return -EAGAIN;
if (current->signal & ~current->blocked)
return -ERESTARTSYS;
current->state = TASK_INTERRUPTIBLE;
add_wait_queue(sk->sleep, &wait);
if ((sk->urg_data & URG_NOTYET) && sk->err == 0 &&
!(sk->shutdown & RCV_SHUTDOWN))
schedule();
remove_wait_queue(sk->sleep, &wait);
current->state = TASK_RUNNING;
#endif
}
return 0;
} }
...@@ -1959,6 +1940,15 @@ static inline unsigned long default_mask(unsigned long dst) ...@@ -1959,6 +1940,15 @@ static inline unsigned long default_mask(unsigned long dst)
return htonl(IN_CLASSC_NET); return htonl(IN_CLASSC_NET);
} }
/*
* Default sequence number picking algorithm.
*/
extern inline long tcp_init_seq(void)
{
return jiffies * SEQ_TICK - seq_offset;
}
/* /*
* This routine handles a connection request. * This routine handles a connection request.
* It should make sure we haven't already responded. * It should make sure we haven't already responded.
...@@ -1969,7 +1959,7 @@ static inline unsigned long default_mask(unsigned long dst) ...@@ -1969,7 +1959,7 @@ static inline unsigned long default_mask(unsigned long dst)
static void tcp_conn_request(struct sock *sk, struct sk_buff *skb, static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
unsigned long daddr, unsigned long saddr, unsigned long daddr, unsigned long saddr,
struct options *opt, struct device *dev) struct options *opt, struct device *dev, unsigned long seq)
{ {
struct sk_buff *buff; struct sk_buff *buff;
struct tcphdr *t1; struct tcphdr *t1;
...@@ -2058,7 +2048,7 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb, ...@@ -2058,7 +2048,7 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
newsk->copied_seq = skb->h.th->seq; newsk->copied_seq = skb->h.th->seq;
newsk->state = TCP_SYN_RECV; newsk->state = TCP_SYN_RECV;
newsk->timeout = 0; newsk->timeout = 0;
newsk->write_seq = jiffies * SEQ_TICK - seq_offset; newsk->write_seq = seq;
newsk->window_seq = newsk->write_seq; newsk->window_seq = newsk->write_seq;
newsk->rcv_ack_seq = newsk->write_seq; newsk->rcv_ack_seq = newsk->write_seq;
newsk->urg_data = 0; newsk->urg_data = 0;
...@@ -3516,6 +3506,7 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len) ...@@ -3516,6 +3506,7 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
struct device *dev=NULL; struct device *dev=NULL;
unsigned char *ptr; unsigned char *ptr;
int tmp; int tmp;
int atype;
struct tcphdr *t1; struct tcphdr *t1;
struct rtable *rt; struct rtable *rt;
...@@ -3539,17 +3530,8 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len) ...@@ -3539,17 +3530,8 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
* Don't want a TCP connection going to a broadcast address * Don't want a TCP connection going to a broadcast address
*/ */
if (ip_chk_addr(usin->sin_addr.s_addr) == IS_BROADCAST) if ((atype=ip_chk_addr(usin->sin_addr.s_addr)) == IS_BROADCAST || atype==IS_MULTICAST)
{
return -ENETUNREACH; return -ENETUNREACH;
}
/*
* Connect back to the same socket: Blows up so disallow it
*/
if(sk->saddr == usin->sin_addr.s_addr && sk->num==ntohs(usin->sin_port))
return -EBUSY;
sk->inuse = 1; sk->inuse = 1;
sk->daddr = usin->sin_addr.s_addr; sk->daddr = usin->sin_addr.s_addr;
...@@ -3971,6 +3953,11 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -3971,6 +3953,11 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
case TCP_FIN_WAIT1: case TCP_FIN_WAIT1:
case TCP_FIN_WAIT2: case TCP_FIN_WAIT2:
case TCP_TIME_WAIT: case TCP_TIME_WAIT:
/*
* is it a good packet?
*/
if (!tcp_sequence(sk, th, len, opt, saddr,dev)) if (!tcp_sequence(sk, th, len, opt, saddr,dev))
{ {
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
...@@ -4005,6 +3992,8 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -4005,6 +3992,8 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
} }
if (th->syn) if (th->syn)
{ {
long seq=sk->write_seq;
int st=sk->state;
tcp_statistics.TcpEstabResets++; tcp_statistics.TcpEstabResets++;
sk->err = ECONNRESET; sk->err = ECONNRESET;
tcp_set_state(sk,TCP_CLOSE); tcp_set_state(sk,TCP_CLOSE);
...@@ -4013,11 +4002,45 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -4013,11 +4002,45 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
if (!sk->dead) { if (!sk->dead) {
sk->state_change(sk); sk->state_change(sk);
} }
/*
* The BSD port reuse protocol violation.
* I do sometimes wonder how the *bsd people
* have the nerve to talk about 'standards'.
*
* If seq > last used on connection then
* open a new connection and use 128000+seq of
* old connection.
*
*/
if(st==TCP_TIME_WAIT && th->seq > sk->acked_seq && sk->dead)
{
release_sock(sk);
/*
* Find the listening socket.
*/
sk=get_sock(&tcp_prot, th->source, daddr, th->dest, saddr);
if(sk && sk->state==TCP_LISTEN)
{
sk->inuse=1;
tcp_conn_request(sk, skb, daddr, saddr,opt, dev,seq+128000);
release_sock(sk);
/* Fall through in case people are
also using the piggy backed SYN + data
protocol violation */
}
else
{
kfree_skb(skb, FREE_READ);
return 0;
}
}
else
{
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
release_sock(sk); release_sock(sk);
return(0); return(0);
} }
}
if (th->ack && !tcp_ack(sk, th, saddr, len)) { if (th->ack && !tcp_ack(sk, th, saddr, len)) {
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
release_sock(sk); release_sock(sk);
...@@ -4046,6 +4069,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -4046,6 +4069,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
release_sock(sk); release_sock(sk);
return(0); return(0);
case TCP_CLOSE: case TCP_CLOSE:
if (sk->dead || sk->daddr) { if (sk->dead || sk->daddr) {
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
...@@ -4083,7 +4107,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -4083,7 +4107,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
* into the buffer. We can't respond until the * into the buffer. We can't respond until the
* user tells us to accept the connection. * user tells us to accept the connection.
*/ */
tcp_conn_request(sk, skb, daddr, saddr, opt, dev); tcp_conn_request(sk, skb, daddr, saddr, opt, dev, tcp_init_seq());
release_sock(sk); release_sock(sk);
return(0); return(0);
} }
...@@ -4129,6 +4153,25 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -4129,6 +4153,25 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
{ {
if (th->syn) if (th->syn)
{ {
/* Crossed SYN's are fine - but talking to
yourself is right out... */
if(sk->saddr==saddr && sk->daddr==daddr &&
sk->dummy_th.source==th->source &&
sk->dummy_th.dest==th->dest)
{
tcp_statistics.TcpAttemptFails++;
sk->err = ECONNREFUSED;
tcp_set_state(sk,TCP_CLOSE);
sk->shutdown = SHUTDOWN_MASK;
sk->zapped = 1;
if (!sk->dead)
{
sk->state_change(sk);
}
kfree_skb(skb, FREE_READ);
release_sock(sk);
return(0);
}
tcp_set_state(sk,TCP_SYN_RECV); tcp_set_state(sk,TCP_SYN_RECV);
} }
kfree_skb(skb, FREE_READ); kfree_skb(skb, FREE_READ);
...@@ -4405,7 +4448,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, int *o ...@@ -4405,7 +4448,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, int *o
val=sk->user_mss; val=sk->user_mss;
break; break;
case TCP_NODELAY: case TCP_NODELAY:
val=sk->nonagle; /* Until Johannes stuff is in */ val=sk->nonagle;
break; break;
default: default:
return(-ENOPROTOOPT); return(-ENOPROTOOPT);
......
...@@ -261,11 +261,11 @@ static int udp_send(struct sock *sk, struct sockaddr_in *sin, ...@@ -261,11 +261,11 @@ static int udp_send(struct sock *sk, struct sockaddr_in *sin,
*/ */
size = sk->prot->max_header + len; size = sk->prot->max_header + len;
skb = sk->prot->wmalloc(sk, size, 0, GFP_KERNEL); skb = sock_alloc_send_skb(sk, size, 0, &tmp);
if (skb == NULL) if (skb == NULL)
return(-ENOBUFS); return tmp;
skb->sk = NULL; /* to avoid changing sk->saddr */ skb->sk = NULL; /* to avoid changing sk->saddr */
skb->free = 1; skb->free = 1;
...@@ -620,7 +620,9 @@ int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -620,7 +620,9 @@ int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
* Charge it to the socket, dropping if the queue is full. * Charge it to the socket, dropping if the queue is full.
*/ */
if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) skb->len = len - sizeof(*uh);
if (sock_queue_rcv_skb(sk,skb)<0)
{ {
udp_statistics.UdpInErrors++; udp_statistics.UdpInErrors++;
ip_statistics.IpInDiscards++; ip_statistics.IpInDiscards++;
...@@ -630,20 +632,7 @@ int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -630,20 +632,7 @@ int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
release_sock(sk); release_sock(sk);
return(0); return(0);
} }
sk->rmem_alloc += skb->mem_len;
udp_statistics.UdpInDatagrams++; udp_statistics.UdpInDatagrams++;
/*
* Now add it to the data chain and wake things up.
*/
skb->len = len - sizeof(*uh);
skb_queue_tail(&sk->receive_queue,skb);
if (!sk->dead)
sk->data_ready(sk,skb->len);
release_sock(sk); release_sock(sk);
return(0); return(0);
} }
......
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