]> git.neil.brown.name Git - history.git/commitdiff
Import 1.1.65 1.1.65
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:44 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:44 +0000 (15:09 -0500)
50 files changed:
CREDITS
Makefile
drivers/block/cdu31a.c
drivers/block/floppy.c
drivers/char/ChangeLog
drivers/char/keyboard.c
drivers/char/serial.c
drivers/net/3c503.c
drivers/net/at1700.c
drivers/net/ewrk3.h
drivers/net/lance.c
drivers/net/skeleton.c
drivers/net/slip.c
drivers/scsi/ChangeLog
drivers/scsi/README.aha274x
drivers/scsi/README.st
drivers/scsi/aha274x.seq
drivers/scsi/eata.c
drivers/scsi/eata.h
drivers/sound/.blurb
fs/Makefile
fs/binfmt_elf.c
fs/exec.c
fs/isofs/rock.c
fs/msdos/file.c
fs/msdos/inode.c
fs/namei.c
fs/nfs/symlink.c
fs/umsdos/inode.c
fs/umsdos/namei.c
include/asm-alpha/bitops.h
include/asm-alpha/io.h [new file with mode: 0644]
include/asm-alpha/string.h [new file with mode: 0644]
include/asm-alpha/system.h
include/linux/ioctl.h
include/linux/kd.h
include/linux/netdevice.h
include/linux/termios.h
init/main.c
mm/memory.c
mm/mprotect.c
net/inet/devinet.c
net/inet/icmp.c
net/inet/ip.c
net/inet/ipx.c
net/inet/raw.c
net/inet/sock.c
net/inet/sock.h
net/inet/tcp.c
net/inet/udp.c

diff --git a/CREDITS b/CREDITS
index b76d822bec1b560724e7e57fd7d59ca269197178..77b5748fa3ef210cab553787d88f0b8de3404741 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -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
index 61851b165f5863c9200c62700131d35b2a0b2431..1adbf9b5b559d4286130c502e6b92aa12dcb12d0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 64
+SUBLEVEL = 65
 
 ARCH = i386
 
index 2f3a259ccaad9348205e1ba7448ecd8d133ea0c0..fd2794a84ee7d0f21b9559781a9b9f6bc5d1de23 100644 (file)
@@ -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.
  *
index b50b14eee6bd087e9f5ef5ef17e3f150af8abf7b..b5f6c91d0634cf23471b4f0f2c05f24128bf078e 100644 (file)
@@ -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)
index 677d1cfc50d9346c17802ee3ba72bd990863c163..78f1fb332afe323c01aa26a399d7ba3eaa1ad7c9 100644 (file)
@@ -1,3 +1,8 @@
+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)
 
index eeb0fc4b9093d62bbf5850b4bc6550fbcd226c07..fac55feb87dca18da030bbe36037e8f553cf7e14 100644 (file)
@@ -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)
index 8e406496f32cb0d94e0185e7db9b13c0ec3eebd2..bd983057c3bef31b09aab088b32dd66526fbe65c 100644 (file)
@@ -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;
index 703b8288e256344cc4efbdf340079503fb33732f..b034e15b4c7ee2d82e85ff1445c6480e5694e4d9 100644 (file)
@@ -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));
 
index 7a2f6bd182406956f3c28e96d8706991cf15092b..ebadd917cf1d649705fac7b1de1b252fbc2f9ed2 100644 (file)
@@ -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:
index 7625a0c6cf67e005af54a7fec5b39a8bf6dace07..941d6bbbccbacc9aebdd5f8222b8f70aa44b9826 100644 (file)
 #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 */
index 7be5877f2edff6e841d6cb5adbd82bb3f00879ad..d366d5f1089195412c54dbb069b82b8f986862de 100644 (file)
@@ -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)
 {
index 490e1c83c2045aee38e64f0ba46fcf5a694ef15e..8eb32c722f52d3c9f38c1f28762f95a1eb0a68bb 100644 (file)
@@ -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));
 
index 3b2a2c914f7af99888f4711effd759190a2a324f..61bc7f35b685a7c4bdae329129098af8b421063e 100644 (file)
@@ -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 */
index 644cd90029a90927d48dabb46d3bc39949decb96..2d5e8e9d33865d776f5b7f8a5f1c01fb94f42ad4 100644 (file)
@@ -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.
 
index ff977c067daca0bb79dfea2aa0941914fcdd4809..a6cb8c5ea27921f60a5aaae54e0ce874578b9e1b 100644 (file)
@@ -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
index b63b4c0f2521dc1174220ee0064dfe4973248aed..3d14837ae97929917b621f0111e89be533fa45a1 100644 (file)
@@ -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.
index c6210b8edb01fb37e75ff3f272db41f6e43550e6..c8a2417829351f191fb1eb1eb0f42499b7dc9083 100644 (file)
@@ -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
index eed97a30668023efd8c00fdfe71e8e7cd2f85446..95ed18a446a3220e0f84a969591ce060d76fbe1b 100644 (file)
@@ -1,6 +1,10 @@
 /*
  *      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), 
index 4c5ba2bdbd5e9824b8d468ab0a78d16934d83ff2..164e437da9aba09ac91afe3aeb0bec765a456c42 100644 (file)
@@ -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 *));
index 165e01ac8b9a6cd23b2bec20d0d67131a6030aa8..aac91a8d51b93c4b39c430ef42fbe8292230ccc1 100644 (file)
@@ -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
index a2c60fcafc6e47d4a97d615a3b08d829255de1a5..78dd720ce94133533adfbc71b012aef2b33c1cb0 100644 (file)
@@ -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
 
index 03ecf30e5b981bcde7824df9c66c102b6dc18ca8..c2dc5cbca422583f32f5f90d7b9d528741f3d9b5 100644 (file)
@@ -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 */
 
index 2901e1577e396b9f8b7711ce87b0ea9858c7dc9e..cefa26fc177efba3bca928153bdac0e0a990baad 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -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);
index c1ef5fad9cd4d85a38558ad0f675a22b9ff014a4..686c1d91091bc17030398f45b67ce70a7576f8c7 100644 (file)
@@ -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;
index 9c6a557d92f36902979bc3b41449b8b5d99a4924..fb41fff21d7d04301061c2056945b69d91e68a4b 100644 (file)
@@ -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;
 }
index c2f4ae35f2bac256ad3d34bf6f1f1d509fa7e7ef..e0577fbef723308ed20dbbc789b448dd94a242b8 100644 (file)
@@ -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;
        }
 }
 
index 3c4a2f781645a5d514224993731c7e8d82562e4a..f5f8b5c14d69511b450c9a343ec697ce1384ffc1 100644 (file)
@@ -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;
index ffa40b8e1f390b99521b4be3ab11da0e41319941..4cbe631c630a0ccff15d896d237aa22cb1dd33f0 100644 (file)
@@ -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);
index b0f5ef16bee30d1bcfa33e4ad157351bcb6ed129..b09726f3a659391ed381df0c48b63ab0d3788e3d 100644 (file)
@@ -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;
index f03e60cf38061e1ba5ee2ebc78fc0723f55895f1..567039e144f7fcbc760d1741ff188a13d1635289 100644 (file)
@@ -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 */
index 8fb3fb095fad2bb725bc7a48396f6c510e56f46b..987a026e3e69464d2d12e4a588bdb89290e3f580 100644 (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
diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h
new file mode 100644 (file)
index 0000000..969fc96
--- /dev/null
@@ -0,0 +1,179 @@
+#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
diff --git a/include/asm-alpha/string.h b/include/asm-alpha/string.h
new file mode 100644 (file)
index 0000000..e90d550
--- /dev/null
@@ -0,0 +1,19 @@
+#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
index 02957a25250c7c3dd65b28e45b24da89b78bb4e9..a726d13247bb8ab41dde9ec09fde26fed20ed387 100644 (file)
@@ -1,6 +1,22 @@
 #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
  */
 #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
  */
 #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" \
index 3766667966c705e08ec9556ffeb842af63c8ff9e..e76bdb6e079f555b518e1202746a84eec392a475 100644 (file)
@@ -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 
index 2893380f0433f9f44a12d692639ac6c663ad7053..3a343fd32e3a6c185bef2e7d3b012d70be8b3683 100644 (file)
@@ -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 */
index a11a93b6f8bfabce390856228e6cc716237a99d2..f0473be80963cd3efd2d99a6cd52cfb8801d3c31 100644 (file)
@@ -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.
index 64b4f3a49c0019ec831f21ee99765e9a49c4c22f..c06864acdba58f221e5606f23a852faaf0b90c6e 100644 (file)
@@ -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 */
 
 
index e63c8b0a2a6b7d3a711f0ab27cc1cbcec8571f7e..a13414748c313c61eb8ef2fa8b7f8eee88b72c73 100644 (file)
@@ -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);
index 8a2fd66895458fac343ce986c7c44a760043d06b..dcccc7f19717de24584625caf625810c21ac668c 100644 (file)
@@ -1042,6 +1042,7 @@ bad_area:
        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;
        }
index b68686ce332de76551f9deb3cef810dcd3de1972..99252183b14e105cdf5c44d1acafda6320dd9a56 100644 (file)
@@ -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;
 }
index be9bf3c8e175eb5e372d1f8b8be0598e5c6e8230..ff830956042bf1b34cc924545dc8af81c1a07c70 100644 (file)
@@ -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 */
 }
 
index 3f7dac676919d5d54fb879be3dfb0545ef638b85..ad2ac801b1e9ad2b7a866eadb5becabde1efad8a 100644 (file)
@@ -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++;
index 6771be20b643e12453cf039f8203140cb1852945..bb1bee640b6ea37aae609a56573cdef8d439927f 100644 (file)
@@ -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);
        }
index 9dd5ec87457d55174d8b6f47e3d8bbbf6e3a536a..1d41acc1693a70fdde88e7e102b3575fdf89e863 100644 (file)
@@ -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);
 }
 
index a7d94d8b53e1badfb38e1bcc38a9687fcfa0779f..b79c1da3c6c21378a9ba188a5a0947a94f1f846f 100644 (file)
@@ -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);
index 27a51871560b80e2fe3d8f40c55799b9f22becf4..e406aa6715615f233980324f79b10a98edbf0561 100644 (file)
@@ -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)
 {
index 8f33c06bd230a99ad25ae8644ad9c1ee6f05205e..07b036fd5be6af9506b28f87840b6434c86d809a 100644 (file)
@@ -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;
index f99819914f1e9d68e285fbd99fa6fd0f80651e1b..432c4c8ddc0d7f001901aeb11d3f399b0cad0781 100644 (file)
@@ -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).
  *                                     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);
index 67650bf5ea829679064841468b186136a1045030..6e739e70353c75c088c7067355a15549cc56a4a7 100644 (file)
@@ -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);
 }