Commit f40ed092 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.65

parent feb3aa0e
......@@ -638,6 +638,10 @@ S: 59 Bugden Avenue
S: Gowrie ACT 2904
S: Australia
N: Alessandro Rubini
E: rubini@ipvvis.unipv.it
D: the gpm mouse server and kernel support for it
N: Robert Sanders
E: gt8134b@prism.gatech.edu
D: Dosemu
......
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 64
SUBLEVEL = 65
ARCH = i386
......
......@@ -71,7 +71,7 @@
* block operation is done. Note that with 2048 byte blocks you
* cannot execute files from the CD.
*
* XA compatability
* XA compatibility
*
* 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.
......@@ -82,7 +82,7 @@
* has it's own minor device number, starting with 0. The support is
* pretty transparent, music, TOC operations, and read operations should
* 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
* time.
*
......
......@@ -2930,7 +2930,7 @@ static struct cont_t poll_cont={
/* 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
* geometry formats */
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)
* 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)
Thu Oct 27 23:14:29 1994 Theodore Y. Ts'o (tytso@rt-11)
* 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,
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)
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
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.
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
to be the tty's process group, or if that is not yet set,
to the current process's pid.
......@@ -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
rs_start(). Fortunately in most cases it would be
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)
......
......@@ -190,7 +190,7 @@ void to_utf8(ushort c) {
put_queue(0x80 | ((c >> 6) & 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 */
}
......@@ -688,9 +688,10 @@ static void incr_console(void)
static void send_intr(void)
{
if (!tty || (tty->termios && I_IGNBRK(tty)))
if (!tty)
return;
tty_insert_flip_char(tty, 0, TTY_BREAK);
tty_schedule_flip(tty);
}
static void scroll_forw(void)
......
......@@ -1084,6 +1084,13 @@ static void change_speed(struct async_struct *info)
if (!(port = info->port))
return;
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 ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
i += 1;
......@@ -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
* 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.
*/
info->IER &= ~UART_IER_RLSI;
......
......@@ -183,7 +183,7 @@ el2_probe1(struct device *dev, int 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++)
printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
......
......@@ -19,7 +19,7 @@
The Fujitsu MB86695 datasheet.
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.
Bugs:
......
......@@ -115,7 +115,7 @@
#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 WB 0x40 /* Write Behind */
......
......@@ -109,7 +109,7 @@ the buffers are only used when needed as low-memory bounce buffers.
IIIB. 16M memory limitations.
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
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
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
......@@ -207,7 +207,7 @@ struct lance_private {
};
/* 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. */
static struct lance_chip_type {
int id_number;
......@@ -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
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. */
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)
/* Fill in the 'dev' fields. */
dev->base_addr = ioaddr;
/* Retrive and print the ethernet address. */
/* Retrieve and print the ethernet address. */
for (i = 0; i < 6; i++)
printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
......
......@@ -25,6 +25,7 @@
* Alan Cox : Default to 192.168.0.0 (RFC 1597)
* A.N.Kuznetsov : dev_tint() recursion fix.
* 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
......@@ -163,8 +164,12 @@ static void sl_changedmtu(struct slip *sl)
unsigned char *tb,*rb,*cb,*tf,*rf,*cf;
int l;
int omtu=sl->mtu;
#ifdef CONFIG_AX25
sl->mtu=dev->mtu+73
#else
sl->mtu=dev->mtu;
#endif
l=(dev->mtu *2);
/*
* 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)
int actual, count;
if(sl->mtu != sl->dev->mtu) /* Someone has been ifconfigging */
#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 */
#endif
sl_changedmtu(sl);
if(len>sl->mtu) /* Sigh, shouldn't occur BUT ... */
......@@ -561,8 +570,12 @@ sl_open(struct device *dev)
if (p == NULL) {
return(-ENOMEM);
}
#ifdef CONFIG_AX25
sl->mtu = dev->mtu+73
#else
sl->mtu = dev->mtu;
#endif
sl->dev->mem_start = (unsigned long) p;
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,
* Argh! mtu change time! - costs us the packet part received
* at the change
*/
#ifdef CONFIG_AX25
if(sl->mtu!=sl->dev->mtu+73)
#else
if(sl->mtu!=sl->dev->mtu)
#endif
sl_changedmtu(sl);
/* Read the characters out of the buffer */
......
......@@ -121,7 +121,7 @@ Sat Aug 6 21:29:36 1994 Eric Youngdale (eric@andante)
* g_NCR5380.c:
* 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.
......
......@@ -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
sending bug reports, please include a description of your hardware, the
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
aycock@cpsc.ucalgary.ca
......@@ -79,7 +79,7 @@ MTBSFM As above but ape positioned after filemark.
MTFSR Space forward over count records.
MTBSR Space backward over count records.
MTFSS Space forward over count setmarks.
MTBSS Space backward over coutn setmarks.
MTBSS Space backward over count setmarks.
MTWEOF Write count filemarks.
MTWSM Write count setmarks.
MTREW Rewind tape.
......
......@@ -176,7 +176,7 @@ start:
# into the message out phase since we have ATN asserted. Prepare
# 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
# 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
# set means active message), one length byte, and then the message itself.
......@@ -812,7 +812,7 @@ assert1:
# 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
# contain either 0x40 (disconnection ok) or 0x00 (diconnection not ok)
# contain either 0x40 (disconnection ok) or 0x00 (disconnection not ok)
# on exit.
#
# 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.
*
* 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.
* 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,
irqlist[info.irq] = j;
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, "\
"Mbox %d, CmdLun %d.\n", BN(j), sh[j]->this_id,
sh[j]->io_port, sh[j]->irq, sh[j]->sg_tablesize,
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)
printk("%s: Version 0x%x, SYNC 0x%x, infol %ld, cpl %ld spl %ld.\n",
name, info.version, info.sync, ntohl(info.data_len),
......
......@@ -5,7 +5,7 @@
#ifndef _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_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
......
......@@ -21,7 +21,14 @@ CAUTION!
This version of driver works with applications written and
compiled for v2.*. The problem is that APPLICATIONS COMPILED
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).
*********************************************************
* 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
......@@ -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 \
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)
$(LD) -r -o fs.o $(OBJS)
......@@ -80,6 +80,16 @@ ifdef MODULES
modules:
$(MAKE) CFLAGS="$(CFLAGS) -DMODULE" $(MODULES)
(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 \
test ! -d $$i || \
{ $(MAKE) -C $$i; }; done
......@@ -87,7 +97,7 @@ modules:
else
modules:
modules_fs:
endif
......
......@@ -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,
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
an ELF header */
......
......@@ -374,10 +374,10 @@ static int count(char ** argv)
int error, i = 0;
char ** tmp, *p;
error = verify_area(VERIFY_READ, argv, sizeof(char *));
if (error)
return error;
if ((tmp = argv) != 0) {
if ((tmp = argv) != NULL) {
error = verify_area(VERIFY_READ, tmp, sizeof(char *));
if (error)
return error;
while ((p = (char *) get_fs_long((unsigned long *) (tmp++))) != NULL) {
i++;
error = verify_area(VERIFY_READ, p, 1);
......
......@@ -359,8 +359,8 @@ int parse_rock_ridge_inode(struct iso_directory_record * de,
printk("RR CL (%x)\n",inode->i_ino);
#endif
inode->u.isofs_i.i_first_extent = isonum_733(rr->u.CL.location) <<
(ISOFS_BLOCK_BITS - ISOFS_BUFFER_BITS(inode));
reloc = iget(inode->i_sb, inode->u.isofs_i.i_first_extent << 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);
inode->i_mode = reloc->i_mode;
inode->i_nlink = reloc->i_nlink;
inode->i_uid = reloc->i_uid;
......
......@@ -103,9 +103,10 @@ int msdos_file_read(
char *buf,
int count)
{
char *start;
int left;
char *start = buf;
char *end = buf + count;
int i;
int left_in_file;
struct msdos_pre pre;
......@@ -144,6 +145,7 @@ int msdos_file_read(
/* pre read enough, since we don't know how many blocks */
/* we really need */
int ahead = read_ahead[MAJOR(inode->i_dev)];
PRINTK (("to_reada %d ahead %d\n",to_reada,ahead));
if (ahead == 0) ahead = 8;
to_reada += ahead;
}
......@@ -151,10 +153,10 @@ int msdos_file_read(
pre.nblist = 0;
msdos_prefetch (inode,&pre,to_reada);
}
start = buf;
pre.nolist = 0;
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];
char *data;
int size,offset;
......@@ -176,15 +178,17 @@ int msdos_file_read(
break;
}
offset = filp->f_pos & (SECTOR_SIZE-1);
filp->f_pos += (size = MIN(SECTOR_SIZE-offset,left));
data = bh->b_data + offset;
size = MIN(SECTOR_SIZE-offset,left_in_file);
if (MSDOS_I(inode)->i_binary) {
size = MIN(size,end-buf);
memcpy_tofs(buf,data,size);
buf += size;
filp->f_pos += size;
}else{
int cnt;
for (cnt = size; cnt; cnt--) {
for (; size && buf < end; size--) {
char ch = *data++;
filp->f_pos++;
if (ch == 26){
filp->f_pos = inode->i_size;
break;
......@@ -199,7 +203,6 @@ int msdos_file_read(
for (i=0; i<pre.nblist; i++) brelse (pre.bhlist[i]);
if (start == buf) return -EIO;
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 */
return buf-start;
}
......
......@@ -483,13 +483,10 @@ int init_module(void)
void cleanup_module(void)
{
if (MOD_IN_USE)
printk("ne: device busy, remove delayed\n");
printk("msdos: device busy, remove delayed\n");
else
{
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)
* put_write_access() releases this write permission.
* This is used for regular files.
* 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)
{
......@@ -527,7 +527,7 @@ static int do_mkdir(const char * pathname, int mode)
}
dir->i_count++;
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);
iput(dir);
return error;
......
......@@ -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,
&res, &len, NFS_MAXPATHLEN);
while ((res2 = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_NFS)) == NULL) {
schedule();
}
if (error) {
iput(inode);
iput(dir);
kfree(mem);
return error;
}
while ((res2 = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_NFS)) == NULL) {
schedule();
}
memcpy(res2, res, len);
res2[len] = '\0';
kfree(mem);
......
......@@ -410,7 +410,7 @@ struct super_block *UMSDOS_read_super(
msdos directory, with all limitation of msdos.
*/
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);
if (sb != NULL){
sb->s_op = &umsdos_sops;
......
......@@ -838,7 +838,9 @@ int UMSDOS_rmdir(
if (ret == 0){
int empty;
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));
if (empty == 1){
/* We have to removed the EMD file */
......
......@@ -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,
* 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.
* 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
#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
*/
......@@ -18,6 +34,12 @@
#define PAL_gentrap 170
#define PAL_nphalt 190
/*
* VMS specific PAL-code
*/
#define PAL_swppal 10
#define PAL_mfpr_vptb 41
/*
* OSF specific PAL-code
*/
......@@ -40,6 +62,10 @@
#define PAL_rtsys 61
#define PAL_rti 63
#ifndef mb
#define mb() __asm__ __volatile__("mb": : :"memory")
#endif
#define invalidate_all() \
__asm__ __volatile__( \
"lda $16,-2($31)\n\t" \
......
......@@ -30,7 +30,7 @@
#define IOCPARM_SHIFT IOCCMD_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)
/* _IO(magic, subcode); size field is zero and the
......
......@@ -51,7 +51,7 @@ struct unimapdesc {
struct unipair *entries;
};
#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 {
u_short advised_hashsize; /* 0 if no opinion */
u_short advised_hashstep; /* 0 if no opinion */
......
......@@ -37,6 +37,7 @@
#define IS_LOOPBACK 2 /* address is for LOOPBACK */
#define IS_BROADCAST 3 /* address is a valid broadcast */
#define IS_INVBCAST 4 /* Wrong netmask bcast not for us (unused)*/
#define IS_MULTICAST 5 /* Multicast IP address */
/*
* The DEVICE structure.
......
......@@ -159,7 +159,7 @@ struct termios {
#define FF1 0100000
/* c_cflag bit meaning */
#define CBAUD 0000017
#define CBAUD 0010017
#define B0 0000000 /* hang up */
#define B50 0000001
#define B75 0000002
......@@ -189,7 +189,10 @@ struct termios {
#define PARODD 0001000
#define HUPCL 0002000
#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 */
/* c_lflag bits */
......@@ -222,7 +225,7 @@ struct termios {
#define TIOCM_CD TIOCM_CAR
#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 */
......
......@@ -456,11 +456,11 @@ asmlinkage void start_kernel(void)
memory_start = blk_dev_init(memory_start,memory_end);
sti();
calibrate_delay();
#ifdef CONFIG_INET
memory_start = net_dev_init(memory_start,memory_end);
#endif
#ifdef CONFIG_SCSI
memory_start = scsi_dev_init(memory_start,memory_end);
#endif
#ifdef CONFIG_INET
memory_start = net_dev_init(memory_start,memory_end);
#endif
memory_start = inode_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)
if (wp_works_ok < 0 && address == TASK_SIZE && (error_code & PAGE_PRESENT)) {
wp_works_ok = 1;
pg0[0] = PAGE_SHARED;
invalidate();
printk("This processor honours the WP bit even when in supervisor mode. Good.\n");
return;
}
......
......@@ -55,7 +55,6 @@ static inline int mprotect_fixup_all(struct vm_area_struct * vma,
{
vma->vm_flags = newflags;
vma->vm_page_prot = prot;
merge_segments(current->mm->mmap);
return 0;
}
......@@ -79,7 +78,6 @@ static inline int mprotect_fixup_start(struct vm_area_struct * vma,
if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n);
insert_vm_struct(current, n);
merge_segments(current->mm->mmap);
return 0;
}
......@@ -103,7 +101,6 @@ static inline int mprotect_fixup_end(struct vm_area_struct * vma,
if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n);
insert_vm_struct(current, n);
merge_segments(current->mm->mmap);
return 0;
}
......@@ -139,7 +136,6 @@ static inline int mprotect_fixup_middle(struct vm_area_struct * vma,
}
insert_vm_struct(current, left);
insert_vm_struct(current, right);
merge_segments(current->mm->mmap);
return 0;
}
......@@ -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)
{
unsigned long end, tmp;
struct vm_area_struct * vma;
struct vm_area_struct * vma, * next;
int error;
if (start & ~PAGE_MASK)
return -EINVAL;
......@@ -201,27 +198,33 @@ asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot)
return -EFAULT;
for ( ; ; ) {
int error;
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));
if ((newflags & ~(newflags >> 4)) & 0xf)
return -EACCES;
if ((newflags & ~(newflags >> 4)) & 0xf) {
error = -EACCES;
break;
}
if (vma->vm_end >= end)
return mprotect_fixup(vma, start, end, newflags);
if (vma->vm_end >= end) {
error = mprotect_fixup(vma, start, end, newflags);
break;
}
tmp = vma->vm_end;
next = vma->vm_next;
error = mprotect_fixup(vma, start, tmp, newflags);
if (error)
return error;
break;
start = tmp;
if (vma->vm_end <= start) {
vma = vma->vm_next;
if (vma && vma->vm_start < start)
vma = vma->vm_next;
if (!vma || vma->vm_start != start)
return -EFAULT;
vma = next;
if (!vma || vma->vm_start != start) {
error = -EFAULT;
break;
}
}
merge_segments(current->mm->mmap);
return error;
}
......@@ -151,6 +151,8 @@ int ip_chk_addr(unsigned long addr)
return IS_BROADCAST;
}
}
if(IN_MULTICAST(addr))
return IS_MULTICAST;
return 0; /* no match at all */
}
......
......@@ -26,6 +26,7 @@
* Ulrich Kunitz : Fixed ICMP timestamp reply
* A.N.Kuznetsov : Multihoming fixes.
* Laco Rusnak : Multihoming fixes.
* Alan Cox : Tightened up icmp_send().
*
*
*
......@@ -100,13 +101,37 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, struct device *dev)
struct icmphdr *icmph;
int len;
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.
*/
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
*/
......@@ -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.
*/
{ unsigned long our_addr = dev->pa_addr;
our_addr = dev->pa_addr;
if (iph->daddr != our_addr && ip_chk_addr(iph->daddr) == IS_MYADDR)
our_addr = iph->daddr;
offset = ip_build_header(skb, our_addr, iph->saddr,
&ndev, IPPROTO_ICMP, NULL, len,
skb_in->ip_hdr->tos,255);
}
if (offset < 0)
{
icmp_statistics.IcmpOutErrors++;
......
......@@ -1485,17 +1485,19 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
/*
* Remember if the frame is fragmented.
*/
if (iph->frag_off & 0x0020)
is_frag|=1;
/*
* Last fragment ?
*/
if (ntohs(iph->frag_off) & 0x1fff)
is_frag|=2;
if(iph->frag_off)
{
if (iph->frag_off & 0x0020)
is_frag|=1;
/*
* Last fragment ?
*/
if (ntohs(iph->frag_off) & 0x1fff)
is_frag|=2;
}
/*
* 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)
* 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);
return 0;
......@@ -1613,7 +1615,7 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
if (!flag)
{
if (brd != IS_BROADCAST)
if (brd != IS_BROADCAST && brd!=IS_MULTICAST)
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
kfree_skb(skb, FREE_WRITE);
}
......
......@@ -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)
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 */
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);
}
......
......@@ -125,7 +125,7 @@ int raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
/* 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++;
skb->sk=NULL;
......@@ -133,10 +133,7 @@ int raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
return(0);
}
sk->rmem_alloc += skb->mem_len;
ip_statistics.IpInDelivers++;
skb_queue_tail(&sk->receive_queue,skb);
sk->data_ready(sk,skb->len);
release_sock(sk);
return(0);
}
......@@ -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)
return -EACCES;
sk->inuse = 1;
skb = NULL;
while (skb == NULL)
{
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=sock_alloc_send_skb(sk, len+sk->prot->max_header, noblock, &err);
if(skb==NULL)
return err;
skb->sk = sk;
skb->free = 1;
skb->localroute = sk->localroute | (flags&MSG_DONTROUTE);
......
......@@ -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)
{
......
......@@ -271,7 +271,10 @@ extern unsigned long sock_rspace(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_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 */
extern struct sock *timer_base;
......
......@@ -47,7 +47,7 @@
* 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 : 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
* Michael O'Reilly : ack < copied bug fix.
* Johannes Stille : Misc tcp fixes (not all in yet).
......@@ -94,6 +94,13 @@
* accept() and async I/O.
* Alan Cox : Relaxed the rules on tcp_sendto().
* 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:
......@@ -1413,75 +1420,49 @@ static void cleanup_rbuf(struct sock *sk)
static int tcp_read_urg(struct sock * sk, int nonblock,
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)
return -EINVAL;
if (sk->err)
{
if (sk->urginline || !sk->urg_data || sk->urg_data == URG_READ)
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)
{
int tmp = -sk->err;
sk->err = 0;
return tmp;
}
if (sk->state == TCP_CLOSE || sk->done)
{
if (!sk->done) {
sk->done = 1;
return 0;
}
return -ENOTCONN;
}
int tmp = -sk->err;
sk->err = 0;
return tmp;
}
if (sk->shutdown & RCV_SHUTDOWN)
{
if (sk->state == TCP_CLOSE || sk->done)
{
if (!sk->done) {
sk->done = 1;
return 0;
}
return -ENOTCONN;
}
/*
* Fixed the recv(..., MSG_OOB) behaviour. BSD docs and
* the available implementations agree in this case:
* this call should never block, independent of the
* blocking state of the socket.
* Mike <pall@rz.uni-karlsruhe.de>
*/
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
if (sk->shutdown & RCV_SHUTDOWN)
{
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
* the available implementations agree in this case:
* this call should never block, independent of the
* blocking state of the socket.
* Mike <pall@rz.uni-karlsruhe.de>
*/
return -EAGAIN;
}
......@@ -1959,6 +1940,15 @@ static inline unsigned long default_mask(unsigned long dst)
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.
* It should make sure we haven't already responded.
......@@ -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,
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 tcphdr *t1;
......@@ -2058,7 +2048,7 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
newsk->copied_seq = skb->h.th->seq;
newsk->state = TCP_SYN_RECV;
newsk->timeout = 0;
newsk->write_seq = jiffies * SEQ_TICK - seq_offset;
newsk->write_seq = seq;
newsk->window_seq = newsk->write_seq;
newsk->rcv_ack_seq = newsk->write_seq;
newsk->urg_data = 0;
......@@ -3516,6 +3506,7 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
struct device *dev=NULL;
unsigned char *ptr;
int tmp;
int atype;
struct tcphdr *t1;
struct rtable *rt;
......@@ -3539,18 +3530,9 @@ 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
*/
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;
}
/*
* 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->daddr = usin->sin_addr.s_addr;
sk->write_seq = jiffies * SEQ_TICK - seq_offset;
......@@ -3971,6 +3953,11 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
case TCP_FIN_WAIT1:
case TCP_FIN_WAIT2:
case TCP_TIME_WAIT:
/*
* is it a good packet?
*/
if (!tcp_sequence(sk, th, len, opt, saddr,dev))
{
kfree_skb(skb, FREE_READ);
......@@ -4005,6 +3992,8 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
}
if (th->syn)
{
long seq=sk->write_seq;
int st=sk->state;
tcp_statistics.TcpEstabResets++;
sk->err = ECONNRESET;
tcp_set_state(sk,TCP_CLOSE);
......@@ -4013,11 +4002,45 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
if (!sk->dead) {
sk->state_change(sk);
}
kfree_skb(skb, FREE_READ);
release_sock(sk);
return(0);
}
/*
* 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);
release_sock(sk);
return(0);
}
}
if (th->ack && !tcp_ack(sk, th, saddr, len)) {
kfree_skb(skb, FREE_READ);
release_sock(sk);
......@@ -4045,7 +4068,8 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
release_sock(sk);
return(0);
case TCP_CLOSE:
if (sk->dead || sk->daddr) {
kfree_skb(skb, FREE_READ);
......@@ -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
* 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);
return(0);
}
......@@ -4129,6 +4153,25 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
{
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);
}
kfree_skb(skb, FREE_READ);
......@@ -4405,7 +4448,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, int *o
val=sk->user_mss;
break;
case TCP_NODELAY:
val=sk->nonagle; /* Until Johannes stuff is in */
val=sk->nonagle;
break;
default:
return(-ENOPROTOOPT);
......
......@@ -261,11 +261,11 @@ static int udp_send(struct sock *sk, struct sockaddr_in *sin,
*/
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)
return(-ENOBUFS);
return tmp;
skb->sk = NULL; /* to avoid changing sk->saddr */
skb->free = 1;
......@@ -619,8 +619,10 @@ int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
/*
* Charge it to the socket, dropping if the queue is full.
*/
skb->len = len - sizeof(*uh);
if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf)
if (sock_queue_rcv_skb(sk,skb)<0)
{
udp_statistics.UdpInErrors++;
ip_statistics.IpInDiscards++;
......@@ -630,20 +632,7 @@ int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
release_sock(sk);
return(0);
}
sk->rmem_alloc += skb->mem_len;
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);
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