]> git.neil.brown.name Git - history.git/commitdiff
Import 1.3.43 1.3.43
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:10:23 +0000 (15:10 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:10:23 +0000 (15:10 -0500)
67 files changed:
CREDITS
Documentation/devices.tex
Documentation/devices.txt
Documentation/unicode.txt
Makefile
arch/alpha/kernel/process.c
arch/alpha/kernel/traps.c
arch/alpha/mm/fault.c
arch/i386/boot/compressed/misc.c
arch/i386/kernel/entry.S
arch/i386/kernel/process.c
arch/i386/kernel/setup.c
arch/i386/kernel/traps.c
arch/i386/mm/fault.c
drivers/block/README.ide
drivers/block/cmd640.c [new file with mode: 0644]
drivers/block/floppy.c
drivers/block/ide.c
drivers/block/ide.h
drivers/block/ll_rw_blk.c
drivers/block/triton.c
drivers/block/umc8672.c [new file with mode: 0644]
drivers/cdrom/mcd.c
drivers/cdrom/mcdx.c
drivers/cdrom/sbpcd.c
drivers/char/busmouse.c
drivers/char/console.c
drivers/char/console_struct.h
drivers/char/tga.c
drivers/char/tpqic02.c
drivers/char/tty_io.c
drivers/char/vga.c
drivers/scsi/scsi.c
drivers/scsi/seagate.c
drivers/scsi/sg.c
fs/binfmt_elf.c
fs/exec.c
fs/filesystems.c
fs/nfs/nfsroot.c
fs/proc/array.c
include/asm-alpha/mman.h
include/asm-alpha/page.h
include/asm-alpha/resource.h
include/asm-i386/mman.h
include/asm-i386/page.h
include/asm-i386/resource.h
include/asm-i386/unistd.h
include/linux/busmouse.h
include/linux/cdrom.h
include/linux/debugreg.h
include/linux/kernel_stat.h
include/linux/ldt.h
include/linux/mcdx.h
include/linux/mm.h
include/linux/sbpcd.h
include/linux/sched.h
include/linux/tty.h
init/main.c
init/version.c
ipc/shm.c
kernel/fork.c
kernel/sched.c
mm/Makefile
mm/mlock.c [new file with mode: 0644]
mm/mmap.c
mm/swap.c
net/ipv4/arp.c

diff --git a/CREDITS b/CREDITS
index b3fa273ec86eb25ab190c95d77684100788cd4a1..a22c6c25079a4a76dbbad0170e2b6c63a7263533 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -593,6 +593,15 @@ S: 25 McMillan Street
 S: Victoria Park 6100
 S: Australia
 
+N: Martin Mares
+E: mj@k332.feld.cvut.cz
+D: BIOS video mode handling code
+D: Miscellaneous kernel fixes
+D: MOXA C-218 serial board driver
+S: Kankovskeho 1241
+S: 182 00 Praha 8
+S: Czech Republic 
+
 N: John A. Martin
 E: jam@acm.org
 D: FSSTND contributor
index ab0e1ebe12a854f2c669bbe61b5084df0cfc5daf..b93c6e124abb75ef38d32b05bd375831c109192a 100644 (file)
@@ -41,8 +41,8 @@ foo \kill}%
  {\end{tabbing}}
 %
 \title{{\bf Linux Allocated Devices}}
-\author{Maintained by H. Peter Anvin $<$Peter.Anvin@linux.org$>$}
-\date{Last revised: September 20, 1995}
+\author{Maintained by H. Peter Anvin $<$hpa@storm.net$>$}
+\date{Last revised: November 17, 1995}
 \maketitle
 %
 \noindent
@@ -140,9 +140,13 @@ an unreasonable effort.
 \major{  }{}{block}{Fourth IDE hard disk/CD-ROM interface}
 \major{35}{}{char }{tclmidi MIDI driver}
 \major{  }{}{block}{Modular RAM disk}
-\major{36}{}{block}{MCA ESDI hard disk}
-\major{37--223}{}{}{Unallocated}
-\major{224--254}{}{}{Local use}
+\major{36}{}{char }{Netlink support}
+\major{  }{}{block}{MCA ESDI hard disk}
+\major{37}{--41}{}{Unallocated}
+\major{42}{}{}{Demo/sample use}
+\major{43}{--223}{}{Unallocated}
+\major{224}{--239}{}{SEE NOTE}
+\major{240}{--254}{}{Local use}
 \major{255}{}{}{Reserved}
 \end{devicelist}
 
@@ -770,7 +774,11 @@ major number 3).
 \end{devicelist}
 
 \begin{devicelist}
-\major{36}{}{block}{MCA ESDI hard disk}
+\major{36}{}{char }{Netlink support}
+       \minor{0}{/dev/route}{Routing, device updates (kernel to user)}
+       \minor{1}{/dev/skip}{enSKIP security cache control}
+\\
+\major{  }{}{block}{MCA ESDI hard disk}
        \minor{0}{/dev/eda}{First ESDI disk whole disk}
        \minor{64}{/dev/edb}{Second ESDI disk whole disk}
        \minordots
@@ -781,11 +789,40 @@ Partitions are handled the same way as for IDE disks (see major number
 3).
 
 \begin{devicelist}
-\major{37}{--223}{}{Unallocated}
+\major{37}{--41}{}{Unallocated}
+\end{devicelist}
+
+\begin{devicelist}
+\major{42}{}{}{Demo/sample use}
+\end{devicelist}
+
+\noindent
+This number is indended for use in sample code, as well as a general
+``example'' device number.  It should never be used for a device
+driver that is being distributed; either obtain an official number or
+use the local/experimental range.  The sudden addition or removal of a
+driver with this number should not cause ill effects to the system
+(bugs excepted.)
+
+\begin{devicelist}
+\major{43}{--223}{}{Unallocated}
 \end{devicelist}
 
 \begin{devicelist}
-\major{224}{--254}{}{Local/experimental use}
+\major{224}{--239}{}{SEE NOTE}
+\end{devicelist}
+
+\noindent
+This range is currently assigned as part of the local/experimental
+range.  However, because of the Linux way of setting a limit on the
+highest device number in the system, currently set at 63 by default, I
+am considering changing the local/experimental use to 60--63,
+120--127, 240--254.  If you are currently using the range 224--239 and
+such a change would pose a problem for you, please contact
+$<$hpa@storm.net$>$ as soon as possible.
+
+\begin{devicelist}
+\major{240}{--254}{}{Local/experimental use}
 \end{devicelist}
 
 \noindent
@@ -846,6 +883,8 @@ exist, they should have the following uses.
 \vlink{/dev/mouse}{mouse port}{symbolic}{Current mouse device}
 \vlink{/dev/tape}{tape device}{symbolic}{Current tape device}
 \vlink{/dev/cdrom}{CD-ROM device}{symbolic}{Current CD-ROM device}
+\vlink{/dev/cdwriter}{CD-writer}{symbolic}{Current CD-writer device}
+\vlink{/dev/scanner}{scanner device}{symbolic}{Current scanner device}
 \vlink{/dev/modem}{modem port}{symbolic}{Current dialout device}
 \vlink{/dev/root}{root device}{symbolic}{Current root filesystem}
 \vlink{/dev/swap}{swap device}{symbolic}{Current swap device}
@@ -857,6 +896,15 @@ dialin as well as dialout, as it tends to cause lock file problems.
 If it exists, {\file /dev/modem} should point to the appropriate
 dialout (alternate) device.
 
+For SCSI devices, {\file /dev/tape} and {\file /dev/cdrom} should
+point to the ``cooked'' devices ({\file /dev/st*} and {\file
+/dev/sr*}, respectively), whereas {\file /dev/cdwriter} and {\file
+/dev/scanner} should point to the appropriate generic SCSI devices
+({\file /dev/sg*}.)
+
+{\file /dev/mouse} may point to a dialout (alternate) TTY device, a
+hardware mouse device, or a socket for a mouse driver program.
+
 \subsection{Sockets and pipes}
 
 Non-transient sockets or named pipes may exist in {\file /dev}.
@@ -868,3 +916,4 @@ Common entries are:
 \end{nodelist}
 
 \end{document}
+
index 0200ff36f851e63d66e84987983e5a175f3ef9c4..85f143d2f591cea4e6f8ff101831241d8cc30f67 100644 (file)
@@ -522,7 +522,10 @@ an unreasonable effort.
                      ...
                255 = /dev/ram255       256th modular RAM disk
 
- 36 block      MCA ESDI hard disk
+ 36 char       Netlink support
+                 0 = /dev/route        Routing, device updates, kernel to user
+                 1 = /dev/skip         enSKIP security cache control
+    block      MCA ESDI hard disk
                  0 = /dev/eda          First ESDI disk whole disk
                 64 = /dev/edb          Second ESDI disk whole disk
                      ...
@@ -530,9 +533,33 @@ an unreasonable effort.
                Partitions are handled in the same way as IDE disks
                (see major number 3).
 
- 37-223                UNALLOCATED
+ 37-41         UNALLOCATED
 
-224-254                LOCAL USE
+ 42            Demo/sample use
+
+               This number is indended for use in sample code, as
+               well as a general "example" device number.  It
+               should never be used for a device driver that is being
+               distributed; either obtain an official number or use
+               the local/experimental range.  The sudden addition or
+               removal of a driver with this number should not cause
+               ill effects to the system (bugs excepted.)
+
+ 43-223                UNALLOCATED
+
+224-239                SEE NOTE
+
+               This range is currently assigned as part of the
+               local/experimental range.  However, because of the
+               Linux way of setting a limit on the highest device
+               number in the system, currently set at 63 by default,
+               I am considering changing the local/experimental use
+               to 60-63, 120-127, 240-254.  If you are currently
+               using the range 224-239 and such a change would pose a
+               problem for you, please contact <hpa@storm.net> as
+               soon as possible.
+
+240-254                LOCAL USE
                Allocated for local/experimental use
 
                Please note that MAX_CHRDEV and MAX_BLKDEV in
@@ -586,6 +613,8 @@ exist, they should have the following uses.
 /dev/mouse     mouse port      symbolic        Current mouse device
 /dev/tape      tape device     symbolic        Current tape device
 /dev/cdrom     CD-ROM device   symbolic        Current CD-ROM device
+/dev/cdwriter  CD-writer       symbolic        Current CD-writer device
+/dev/scanner   scanner         symbolic        Current scanner device
 /dev/modem     modem port      symbolic        Current dialout device
 /dev/root      root device     symbolic        Current root filesystem
 /dev/swap      swap device     symbolic        Current swap device
@@ -595,6 +624,13 @@ well as dialout, as it tends to cause lock file problems.  If it
 exists, /dev/modem shold point to the appropriate dialout (alternate)
 device.
 
+For SCSI devices, /dev/tape and /dev/cdrom should point to the
+``cooked'' devices (/dev/st* and /dev/sr*, respectively), whereas
+/dev/cdwriter and /dev/scanner should point to the appropriate generic
+SCSI devices (/dev/sg*).
+
+/dev/mouse may point to a dialout (alternate) TTY device, a hardware
+mouse device, or a socket for a mouse driver program.
 
        Sockets and pipes
 
index 2e320526f4b8a078cdf83f407cd369ef51e81449..4a9709e903334867d0887b5ecd469abffbf2454c 100644 (file)
@@ -30,6 +30,9 @@ directly to the loaded font, bypassing the translation table.  The
 user-defined map now defaults to U+F000 to U+F1FF, emulating the
 previous behaviour.
 
+Actual characters assigned in the Corporate Zone
+------------------------------------------------
+
 In addition, the following characters not present in Unicode 1.1.4 (at
 least, I have not found them!) have been defined; these are used by
 the DEC VT graphics map:
@@ -45,5 +48,79 @@ omitted the scan 5 line, since it is also used as a block-graphics
 character, and hence has been coded as U+2500 FORMS LIGHT HORIZONTAL.
 However, I left U+F802 blank should the need arise.  
 
-       H. Peter Anvin <Peter.Anvin@linux.org>
-       Yggdrasil Computing, Inc.
+Klingon language support
+------------------------
+
+Unfortunately, Unicode/ISO 10646 does not allocate code points for the
+language Klingon, probably fearing the potential code point explosion
+if many fictional lanugages were submitted for inclusion.  There are
+also political reasons (the Japanese, for example, are not too happy
+about the whole 16-bit concept to begin with.)  However, with Linux
+being a hacker-driven OS it seems this is a brilliant linguistic hack
+worth supporting.  Hence I have chosen to add it to the list in the
+Linux "Corporate" Zone.
+
+Several glyph forms for the Klingon alphabet has been proposed.
+However, since the set of symbols appear to be consistent throughout,
+with only the actual shapes being different, in keeping with standard
+Unicode practice these differences are considered font variants.
+
+Klingon has an alphabet of 26 characters, a positional numeric writing
+system with 10 digits, and is written left-to-right, top-to-bottom.
+Punctuation appears to be only used in Latin transliteration; it is
+appears customary to write each sentence on its own line, and
+centered.  Space has been reserved for punctuation should it prove
+necessary.
+
+This encoding has been endorsed by the Klingon Language Institute.
+For more information, contact them at:
+
+       http://www.kli.org/
+
+Since the characters in the beginning of the Linux CZ have been more
+of the dingbats/symbols/forms type and this is a language, I have
+located it at the end, on a 16-cell boundary in keeping with standard
+Unicode practice.
+
+U+F8D0 KLINGON LETTER A
+U+F8D1 KLINGON LETTER B
+U+F8D2 KLINGON LETTER CH
+U+F8D3 KLINGON LETTER D
+U+F8D4 KLINGON LETTER E
+U+F8D5 KLINGON LETTER GH
+U+F8D6 KLINGON LETTER H
+U+F8D7 KLINGON LETTER I
+U+F8D8 KLINGON LETTER J
+U+F8D9 KLINGON LETTER L
+U+F8DA KLINGON LETTER M
+U+F8DB KLINGON LETTER N
+U+F8DC KLINGON LETTER NG
+U+F8DD KLINGON LETTER O
+U+F8DE KLINGON LETTER P
+U+F8DF KLINGON LETTER Q
+       - Written <q> in standard Okrand Latin transliteration
+U+F8E0 KLINGON LETTER QH
+       - Written <Q> in standard Okrand Latin transliteration
+U+F8E1 KLINGON LETTER R
+U+F8E2 KLINGON LETTER S
+U+F8E3 KLINGON LETTER T
+U+F8E4 KLINGON LETTER TLH
+U+F8E5 KLINGON LETTER U
+U+F8E6 KLINGON LETTER V
+U+F8E7 KLINGON LETTER W
+U+F8E8 KLINGON LETTER Y
+U+F8E9 KLINGON LETTER GLOTTAL STOP
+
+U+F8F0 KLINGON DIGIT ZERO
+U+F8F1 KLINGON DIGIT ONE
+U+F8F2 KLINGON DIGIT TWO
+U+F8F3 KLINGON DIGIT THREE
+U+F8F4 KLINGON DIGIT FOUR
+U+F8F5 KLINGON DIGIT FIVE
+U+F8F6 KLINGON DIGIT SIX
+U+F8F7 KLINGON DIGIT SEVEN
+U+F8F8 KLINGON DIGIT EIGHT
+U+F8F9 KLINGON DIGIT NINE
+
+
+       H. Peter Anvin <hpa@storm.net>
index 3413150b37d5d7b219d0856ff3bebca8ebb4c08a..62961b1b6ad08470eac777c4277d605775144241 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 42
+SUBLEVEL = 43
 
 ARCH = i386
 
index eb5cf2790a1b60cc751bd16d1def559d3b004286..28b22801988ef9269d0ce10acb352b874efd9760 100644 (file)
@@ -57,8 +57,8 @@ void hard_reset_now(void)
 
 void show_regs(struct pt_regs * regs)
 {
-       printk("\nps: %04lx pc: %016lx\n", regs->ps, regs->pc);
-       printk("rp: %016lx sp: %p\n", regs->r26, regs+1);
+       printk("\nps: %04lx pc: [<%016lx>]\n", regs->ps, regs->pc);
+       printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
        printk(" r0: %016lx  r1: %016lx  r2: %016lx  r3: %016lx\n",
               regs->r0, regs->r1, regs->r2, regs->r3);
        printk(" r4: %016lx  r5: %016lx  r6: %016lx  r7: %016lx\n",
index 75aa2842281fc37cfbd6519607afbfd007b3bf11..d672f33d65e745194ffce7e6c7326942a9ff10ba 100644 (file)
@@ -25,8 +25,8 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err)
                return;
        printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
        sp = (unsigned long) (regs+1);
-       printk("pc = %lx ps = %04lx\n", regs->pc, regs->ps);
-       printk("rp = %lx sp = %lx\n", regs->r26, sp);
+       printk("pc = [<%lx>] ps = %04lx\n", regs->pc, regs->ps);
+       printk("rp = [<%lx>] sp = %lx\n", regs->r26, sp);
        printk("r0=%lx r1=%lx r2=%lx r3=%lx\n",
                regs->r0, regs->r1, regs->r2, regs->r3);
        printk("r8=%lx\n", regs->r8);
index 57f352236dba9f20cf45ba9608460b586f912fef..629f17eeb8ba3aef821c090c36dd60fcd52679bd 100644 (file)
@@ -54,10 +54,8 @@ asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long c
                goto good_area;
        if (!(vma->vm_flags & VM_GROWSDOWN))
                goto bad_area;
-       if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
+       if (expand_stack(vma, address))
                goto bad_area;
-       vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
-       vma->vm_start = (address & PAGE_MASK);
 /*
  * Ok, we have a good vm_area for this memory access, so
  * we can handle it..
index b7a6c0aed45c3d2274b2da519923fca7a9dbe393..5c49c258a610b974611a7bcbf9178e9c615fef66 100644 (file)
@@ -5,13 +5,14 @@
  * adapted for Linux.
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- * puts by Nick Holloway 1993
+ * puts by Nick Holloway 1993, better puts by Martin Mares 1995
  */
 
 #include "gzip.h"
 #include "lzw.h"
 
 #include <asm/segment.h>
+#include <asm/io.h>
 
 /*
  * These are set up by the setup-routine at boot-time:
@@ -24,9 +25,9 @@ struct screen_info {
        unsigned short orig_video_page;
        unsigned char  orig_video_mode;
        unsigned char  orig_video_cols;
-       unsigned short orig_video_ega_ax;
+       unsigned short unused2;
        unsigned short orig_video_ega_bx;
-       unsigned short orig_video_ega_cx;
+       unsigned short unused3;
        unsigned char  orig_video_lines;
        unsigned char  orig_video_isVGA;
 };
@@ -77,6 +78,7 @@ void makecrc(void);
 local int get_method(int);
 
 char *vidmem = (char *)0xb8000;
+int vidport;
 int lines, cols;
 
 static void puts(const char *);
@@ -128,7 +130,7 @@ static void scroll()
 
 static void puts(const char *s)
 {
-       int x,y;
+       int x,y,pos;
        char c;
 
        x = SCREEN_INFO.orig_x;
@@ -155,6 +157,12 @@ static void puts(const char *s)
 
        SCREEN_INFO.orig_x = x;
        SCREEN_INFO.orig_y = y;
+
+       pos = (x + cols * y) * 2;       /* Update cursor position */
+       outb_p(14, vidport);
+       outb_p(0xff & (pos >> 9), vidport+1);
+       outb_p(15, vidport);
+       outb_p(0xff & (pos >> 1), vidport+1);
 }
 
 __ptr_t memset(__ptr_t s, int c, size_t n)
@@ -315,10 +323,13 @@ struct {
 
 void decompress_kernel()
 {
-       if (SCREEN_INFO.orig_video_mode == 7)
+       if (SCREEN_INFO.orig_video_mode == 7) {
                vidmem = (char *) 0xb0000;
-       else
+               vidport = 0x3b4;
+       } else {
                vidmem = (char *) 0xb8000;
+               vidport = 0x3d4;
+       }
 
        lines = SCREEN_INFO.orig_video_lines;
        cols = SCREEN_INFO.orig_video_cols;
index cce198bc91a415ec277b68265c2d2cee4ee372e8..6f1d8cb344d9fbf220c576c80624421c1049d07b 100644 (file)
@@ -343,10 +343,6 @@ ret_from_sys_call:
 #endif
        cmpl SYMBOL_NAME(task),%eax     # task[0] cannot have signals
        je 2f
-       cmpl $0,state(%eax)             # state
-       jne reschedule
-       cmpl $0,counter(%eax)           # counter
-       je reschedule
        movl blocked(%eax),%ecx
        movl %ecx,%ebx                  # save blocked in %ebx for signal handling
        notl %ecx
@@ -660,4 +656,11 @@ ENTRY(sys_call_table)
        .long SYMBOL_NAME(sys_msync)
        .long SYMBOL_NAME(sys_readv)            /* 145 */
        .long SYMBOL_NAME(sys_writev)
-       .space (NR_syscalls-146)*4
+       .long 0
+       .long 0
+       .long 0
+       .long SYMBOL_NAME(sys_mlock)            /* 150 */
+       .long SYMBOL_NAME(sys_munlock)
+       .long SYMBOL_NAME(sys_mlockall)
+       .long SYMBOL_NAME(sys_munlockall)
+       .space (NR_syscalls-154)*4
index 427d9153e21fe720481f0b686404953d09c15053..a5a9a62927afc659497260dbdf3a4ed5b9063576 100644 (file)
@@ -124,7 +124,7 @@ void hard_reset_now(void)
 void show_regs(struct pt_regs * regs)
 {
        printk("\n");
-       printk("EIP: %04x:%08lx",0xffff & regs->cs,regs->eip);
+       printk("EIP: %04x:[<%08lx>]",0xffff & regs->cs,regs->eip);
        if (regs->cs & 3)
                printk(" ESP: %04x:%08lx",0xffff & regs->ss,regs->esp);
        printk(" EFLAGS: %08lx\n",regs->eflags);
index 9c8a19c21c7c2132409a07699070612fb1804b71..1f976e4b8a41072a7b42a02ca2c1423e32966140 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 /*
- * This file handles the architecture-dependent parts of process handling..
+ * This file handles the architecture-dependent parts of initialization
  */
 
 #include <linux/errno.h>
@@ -152,12 +152,39 @@ void setup_arch(char **cmdline_p,
        request_region(0xf0,0x10,"npu");
 }
 
+static const char * i486model(unsigned int nr)
+{
+       static const char *model[] = {
+               "0", "DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4"
+       };
+       if (nr < sizeof(model)/sizeof(char *))
+               return model[nr];
+       return "Unknown";
+}
+
+static const char * i586model(unsigned int nr)
+{
+       static const char *model[] = {
+               "0", "Pentium 60/66","Pentium 75+"
+       };
+       if (nr < sizeof(model)/sizeof(char *))
+               return model[nr];
+       return "Unknown";
+}
+
+static const char * getmodel(int x86, int model)
+{
+       switch (x86) {
+               case 4:
+                       return i486model(model);
+               case 5:
+                       return i586model(model);
+       }
+       return "Unknown";
+}
+
 int get_cpuinfo(char * buffer)
 {
-       static const char *model[2][9]={{"DX","SX","DX/2","4","SX/2","6",
-                               "DX/2-WB","DX/4"},
-                       {"Pentium 60/66","Pentium 75+","3",
-                               "4","5","6","7","8"}};
        char mask[2];
 #ifndef __SMP__        
        mask[0] = x86_mask+'@';
@@ -180,7 +207,7 @@ int get_cpuinfo(char * buffer)
                              "CMPXCHGB8B\t: %s\n"
                              "BogoMips\t: %lu.%02lu\n",
                              x86+'0', 
-                             x86_model ? model[x86-4][x86_model-1] : "Unknown",
+                             getmodel(x86, x86_model),
                              x86_mask ? mask : "Unknown",
                              x86_vendor_id,
                              fdiv_bug ? "yes" : "no",
@@ -207,8 +234,7 @@ int get_cpuinfo(char * buffer)
        bp+=sprintf(bp,"\nmodel\t\t: ");
        for(i=0;i<32;i++)
                if(cpu_present_map&(1<<i))
-                       bp+=sprintf(bp,"%-16s",cpu_data[i].x86_model?
-                                       model[cpu_data[i].x86-4][cpu_data[i].x86_model-1]:"Unknown");
+                       bp+=sprintf(bp,"%-16s",getmodel(cpu_data[i].x86,cpu_data[i].x86_model));
        bp+=sprintf(bp,"\nmask\t\t: ");
        for(i=0;i<32;i++)
                if(cpu_present_map&(1<<i))
index fdcdfedd1d733a68055835c4ac8508e837c8f1a1..bc196c652612671999b692169feb0ca6a4acb920 100644 (file)
@@ -27,7 +27,7 @@
 
 asmlinkage int system_call(void);
 asmlinkage void lcall7(void);
-struct desc_struct default_ldt;
+struct desc_struct default_ldt = { 0, 0 };
 
 static inline void console_verbose(void)
 {
@@ -113,7 +113,7 @@ int kstack_depth_to_print = 24;
        console_verbose();
        printk("%s: %04lx\n", str, err & 0xffff);
        printk("CPU:    %d\n", smp_processor_id());
-       printk("EIP:    %04x:%08lx\nEFLAGS: %08lx\n", 0xffff & regs->cs,regs->eip,regs->eflags);
+       printk("EIP:    %04x:[<%08lx>]\nEFLAGS: %08lx\n", 0xffff & regs->cs,regs->eip,regs->eflags);
        printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
                regs->eax, regs->ebx, regs->ecx, regs->edx);
        printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
@@ -153,7 +153,7 @@ int kstack_depth_to_print = 24;
                    ((addr >= module_start) && (addr <= module_end))) {
                        if (i && ((i % 8) == 0))
                                printk("\n       ");
-                       printk("%08lx ", addr);
+                       printk("[<%08lx>] ", addr);
                        i++;
                }
        }
index d4b38dbfdf688bf13159e8e1eca5b1ef00923ff1..3a3fe9b9a9ba64029fcf878da061b76db60ab973 100644 (file)
@@ -46,8 +46,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                goto good_area;
        if (!(vma->vm_flags & VM_GROWSDOWN))
                goto bad_area;
-       if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
-               goto bad_area;
        if (error_code & 4) {
                /*
                 * accessing the stack below %esp is always a bug.
@@ -58,8 +56,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                if (address + 32 < regs->esp)
                        goto bad_area;
        }
-       vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
-       vma->vm_start = (address & PAGE_MASK);
+       if (expand_stack(vma, address))
+               goto bad_area;
 /*
  * Ok, we have a good vm_area for this memory access, so
  * we can handle it..
index 8250b1f3fe96c693f24993a0e54d8053992aee84..adee5a4b2655dc22b9899ed9de38e8d846b58560 100644 (file)
@@ -34,6 +34,8 @@ NEW!  - support for reliable operation of buggy CMD-640 interfaces
                - PCI support is automatic
                - for VLB, use kernel command line option:   ide0=cmd640_vlb
                - this support also enables the secondary i/f on most cards
+               - experimental interface timing parameter support
+NEW!   - experimental support for UMC 8672 interfaces
 NEW!   - support for secondary interface on the FGI/Holtek HT-6560B VLB i/f
                - use kernel command line option:   ide1=ht6560
 NEW!   - experimental "fast" speed support for QD6580 interfaces
@@ -45,7 +47,10 @@ NEW! - support for removeable devices, including door lock/unlock
 NEW!   - transparent support for DiskManager 6.0x and "Dynamic Disk Overlay"
        - works with Linux fdisk, LILO, loadlin, bootln, etc..
 NEW!   - mostly transparent support for EZ-Drive
-               - LILO is incompatible (also harmless) with EZ-Drive
+NEW!           - to use LILO with EZ, install LILO on the linux partition
+                 rather than on the master boot record, and then mark the
+                 linux partition as "bootable" or "active" using fdisk.
+                 (courtesy of Juha Laiho <jlaiho@ichaos.nullnet.fi>).
 NEW!   - ide-cd.c now compiles separate from ide.c
 NEW!   - Bus-Master DMA support for Intel PCI Triton chipset IDE interfaces
                - for details, see comments at top of triton.c
@@ -466,24 +471,62 @@ Silicon Valley - best day job in the world
 
 ================================================================================
 
- from:       'delman@mipg.upenn.edu'
- subject:    rz1000
+ 1995 Nov 16 at 08:25  EST
+ from:       'dwhysong@dolphin.physics.ucsb.edu' (BNR400)
+
+[I'm cc'ing this to Mark Lord: FYI, I've got at DTC2278S VLB EIDE
+controller with a Connor CFA850A as /dev/hda and a Maxtor 7213A as
+/dev/hdb using Linux 1.2.13 w/patches for assembly strcpy and the kswap
+patches. I'm getting strange behavior and an unstable system when I try to
+use 32 bit VLB data transfer to the interface card. However, hdparm
+reports that the Connor is extremely fast when I can get the 32 bit mode
+enabled using hdparm -c1 /dev/hd(a|b). However, if I don't do hdparm -c1
+on both /dev/hda and /dev/hdb, then when I run "hdparm -t /dev/hda" the
+disk subsystem locks up... the disk LED comes on and stays on, and no
+other programs are able to get disk access (I can switch VC's, but I can't
+get past the username prompt). I thought you should know about this. I'm
+not sure if it's a problem with the support for the DTC cards, or a
+peculiarity with my hardware configuration. I doubt that my hardware
+itself is flaky, though that's always a possibility.]
+
+On Wed, 15 Nov 1995, Michael Faurot wrote:
+
+> > The trick is setting BOTH drives to use the 32 bit interface.
+>
+> Congrats on getting it going.  Those are some great transfer
+> rates.  I noticed you did switch on the unmasking.  Noticed any
+> problems with things under extreme load or with serial transfers?
+
+I've never had any problems which I could trace to interrupt unmasking.
+Of course, my system usually doesn't have a really heavy load, either.
+These numbers seem way too high for a disk with something like 3500 (?)
+RPM.
+
+Sleepy# hdparm -t /dev/hda
+
+/dev/hda:
+ Timing buffer-cache reads:   32 MB in  2.24 seconds =14.29 MB/sec
+ Timing buffered disk reads:  16 MB in  3.63 seconds = 4.41 MB/sec
+ Estimating raw driver speed: 16 MB in  2.51 seconds = 6.37 MB/sec
+
+> Not sure I was much help to you, but I'm glad to hear you got it
+> working--and pretty impressivly at that. :-)
+
+Mmm, well, about that... I've found that my Connor drive (/dev/hda) is
+pretty fast when I have my system configured like this. I'm still not
+sure I trust the "hdparm -t"  results, though. However, when I try
+"hdparm -t /dev/hdb" (/dev/hdb is an older Maxtor 7213A) I have the same
+problem I had before with my disk subsystem locking up.
+
+I've tried just about every possible combination of flags in ide.c and
+hdparm, and I can't get decent performance out of this drive/controller
+combination without some kind of instability creeping in. I'm living with
+the situation now only because /dev/hdb is a DOS-only drive, and I don't
+need it under Linux. However, I don't really like the situation.
+
+-Dave
+dwhysong@physics.ucsb.edu
+
+(Why can't this stuff be simple? Plug the card in, and it works? Every
+hardware manufacturer has to have their own way of doing things...)
 
-Hi Mark! Looks like you managed to get the info from Intel to disable
-the read-ahead feature of the RZ1000. My encounter with
-Zeos (subsidiary of Micron which owns PCTech) has not been as
-successful --- one guy needs to ask his supervisors about NDA, another
-guy thinks that there is too much of a performance hit with read-ahead
-disabled.
-
-Did the following benchmark to see how true the claim is.
-With Linux 1.2.13, average of 10 "hdparm -t" in MB/s:
-
-                       hdparm -c0        hdparm -c1
-read-ahead enabled        4.28              4.25
-read-ahead disabled       3.58              4.30
-
-Maybe -c1 should be the default for the RZ1000, or as a suggestion in
-the README for people with the RZ1000.
-
-Cheers, Delman.
diff --git a/drivers/block/cmd640.c b/drivers/block/cmd640.c
new file mode 100644 (file)
index 0000000..99572dd
--- /dev/null
@@ -0,0 +1,444 @@
+/*
+ *  linux/drivers/block/cmd640.c       Version 0.01  Nov 16, 1995
+ *
+ *  Copyright (C) 1995  Linus Torvalds & author (see below)
+ */
+
+/*
+ *  Principal Author/Maintainer:  abramov@cecmow.enet.dec.com (Igor)
+ *
+ *  This file provides support for the advanced features and bugs
+ *  of IDE interfaces using the CMD Technologies 0640 IDE interface chip.
+ *
+ *  Version 0.01       Initial version, hacked out of ide.c,
+ *                     and #include'd rather than compiled separately.
+ *                     This will get cleaned up in a subsequent release.
+ */
+
+/* Interface to access cmd640x registers */
+static void (*put_cmd640_reg)(int key, int reg_no, int val);
+static byte (*get_cmd640_reg)(int key, int reg_no);
+
+enum { none, vlb, pci1, pci2 };
+static int     bus_type = none;
+static int     cmd640_chip_version;
+static int     cmd640_key;
+static byte    is_cmd640[MAX_HWIFS];
+
+/*
+ * For some unknown reasons pcibios functions which read and write registers
+ * do not work with cmd640. We use direct io instead.
+ */
+
+/* PCI method 1 access */
+
+static void put_cmd640_reg_pci1(int key, int reg_no, int val)
+{
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+       outl_p((reg_no & 0xfc) | key, 0xcf8);
+       outb_p(val, (reg_no & 3) + 0xcfc);
+       restore_flags(flags);
+}
+
+static byte get_cmd640_reg_pci1(int key, int reg_no)
+{
+       byte b;
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+       outl_p((reg_no & 0xfc) | key, 0xcf8);
+       b = inb(0xcfc + (reg_no & 3));
+       restore_flags(flags);
+       return b;
+}
+
+/* PCI method 2 access (from CMD datasheet) */
+
+static void put_cmd640_reg_pci2(int key, int reg_no, int val)
+{
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+       outb_p(0x10, 0xcf8);
+       outb_p(val, key + reg_no);
+       outb_p(0, 0xcf8);
+       restore_flags(flags);
+}
+
+static byte get_cmd640_reg_pci2(int key, int reg_no)
+{
+       byte b;
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+       outb_p(0x10, 0xcf8);
+       b = inb(key + reg_no);
+       outb_p(0, 0xcf8);
+       restore_flags(flags);
+       return b;
+}
+
+/* VLB access */
+
+static void put_cmd640_reg_vlb(int key, int reg_no, int val)
+{
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+       outb(reg_no, key + 8);
+       outb(val, key + 0xc);
+       restore_flags(flags);
+}
+
+static byte get_cmd640_reg_vlb(int key, int reg_no)
+{
+       byte b;
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+       outb(reg_no, key + 8);
+       b = inb(key + 0xc);
+       restore_flags(flags);
+       return b;
+}
+
+/*
+ * Probe for CMD640x -- pci method 1
+ */
+
+static int probe_for_cmd640_pci1(void)
+{
+       long id;
+       int     k;
+
+       for (k = 0x80000000; k <= 0x8000f800; k += 0x800) {
+               outl(k, 0xcf8);
+               id = inl(0xcfc);
+               if (id != 0x06401095)
+                       continue;
+               put_cmd640_reg = put_cmd640_reg_pci1;
+               get_cmd640_reg = get_cmd640_reg_pci1;
+               cmd640_key = k;
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * Probe for CMD640x -- pci method 2
+ */
+
+static int probe_for_cmd640_pci2(void)
+{
+       int i;
+       int v_id;
+       int d_id;
+
+       for (i = 0xc000; i <= 0xcf00; i += 0x100) {
+               outb(0x10, 0xcf8);
+               v_id = inw(i);
+               d_id = inw(i + 2);
+               outb(0, 0xcf8);
+               if (v_id != 0x1095 || d_id != 0x640)
+                       continue;
+               put_cmd640_reg = put_cmd640_reg_pci2;
+               get_cmd640_reg = get_cmd640_reg_pci2;
+               cmd640_key = i;
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * Probe for CMD640x -- vlb
+ */
+
+static int probe_for_cmd640_vlb(void) {
+       byte b;
+
+       outb(0x50, 0x178);
+       b = inb(0x17c);
+       if (b == 0xff || b == 0 || (b & 0x20)) {
+               outb(0x50, 0xc78);
+               b = inb(0x7c);
+               if (b == 0xff || b == 0 || !(b & 0x20))
+                       return 0;
+               cmd640_key = 0x70;
+       } else {
+               cmd640_key = 0x170;
+       }
+       put_cmd640_reg = put_cmd640_reg_vlb;
+       get_cmd640_reg = get_cmd640_reg_vlb;
+       return 1;
+}
+
+/*
+ * Probe for Cmd640x and initialize it if found
+ */
+
+int ide_probe_for_cmd640x(void)
+{
+       int i;
+
+       for (i = 0; i < MAX_HWIFS; i++)
+               is_cmd640[i] = 0;
+
+       if (probe_for_cmd640_pci1()) {
+               bus_type = pci1;
+       } else if (probe_for_cmd640_pci2()) {
+               bus_type = pci2;
+       } else if (cmd640_vlb && probe_for_cmd640_vlb()) {
+               /* May be remove cmd640_vlb at all, and probe in any case */
+               bus_type = vlb;
+       } else {
+               return 0;
+       }
+
+       /*
+        * Undocumented magic. (There is no 0x5b port in specs)
+        */
+
+       put_cmd640_reg(cmd640_key, 0x5b, 0xbd);
+       if (get_cmd640_reg(cmd640_key, 0x5b) != 0xbd) {
+               printk("ide: can't initialize cmd640 -- wrong value in 0x5b\n");
+               return 0;
+       }
+       put_cmd640_reg(cmd640_key, 0x5b, 0);
+
+       /*
+        * Documented magic.
+        */
+
+       cmd640_chip_version = get_cmd640_reg(cmd640_key, 0x50) & 3;
+       if (cmd640_chip_version == 0) {
+               printk ("ide: wrong CMD640 version -- 0\n");
+               return 0;
+       }
+
+       put_cmd640_reg(cmd640_key, 0x51, get_cmd640_reg(cmd640_key, 0x51) | 0xc8);
+       put_cmd640_reg(cmd640_key, 0x57, 0);
+       put_cmd640_reg(cmd640_key, 0x57, get_cmd640_reg(cmd640_key, 0x57) | 0x0c);
+
+       serialized = 1;
+
+       printk("ide: buggy CMD640 interface at ");
+       switch (bus_type) {
+               case vlb :
+                       printk("local bus, port 0x%x", cmd640_key);
+                       break;
+               case pci1:
+                       printk("pci, (0x%x)", cmd640_key);
+                       break;
+               case pci2:
+                       printk("pci,(access method 2) (0x%x)", cmd640_key);
+                       break;
+       }
+
+       is_cmd640[0] = is_cmd640[1] = 1;
+
+       /*
+        * Reset interface timings
+        */
+
+       put_cmd640_reg(cmd640_key, 0x58, 0);
+       put_cmd640_reg(cmd640_key, 0x52, 0);
+
+       printk("\n ... serialized, disabled read-ahead, secondary interface enabled\n");
+
+       return 1;
+}
+
+static int as_clocks(int a) {
+       switch (a & 0xf0) {
+               case 0 :        return 4;
+               case 0x40 :     return 2;
+               case 0x80 :     return 3;
+               case 0xc0 :     return 5;
+               default :       return -1;
+       }
+}
+
+/*
+ * Tuning of drive parameters
+ */
+
+static void cmd640_set_timing(int if_num, int dr_num, int r1, int r2) {
+       int  b_reg;
+       byte b;
+       int  r52;
+
+       b_reg = if_num ? 0x57 : dr_num ? 0x55 : 0x53;
+
+       if (if_num == 0) {
+               put_cmd640_reg(cmd640_key, b_reg, r1);
+               put_cmd640_reg(cmd640_key, b_reg + 1, r2);
+       } else {
+               b = get_cmd640_reg(cmd640_key, b_reg);
+               if ((b&1) == 0) {
+                       put_cmd640_reg(cmd640_key, b_reg, r1);
+               } else {
+                       if (as_clocks(b) < as_clocks(r1))
+                               put_cmd640_reg(cmd640_key, b_reg, r1);
+               }
+               b = get_cmd640_reg(cmd640_key, b_reg + 1);
+               if (b == 0) {
+                       put_cmd640_reg(cmd640_key, b_reg + 1, r2);
+               } else {
+                       r52 = (b&0xf) < (r2&0xf) ? (r2&0xf) : (b&0xf);
+                       r52 |= (b&0xf0) < (r2&0xf0) ? (r2&0xf0) : (b&0xf0);
+                       put_cmd640_reg(cmd640_key, b_reg+1, r52);
+               }
+       }
+
+       b = get_cmd640_reg(cmd640_key, 0x52);
+       if (b == 0) {
+               put_cmd640_reg(cmd640_key, 0x52, r2);
+       } else {
+               r52 = (b&0xf) < (r2&0xf) ? (r2&0xf) : (b&0xf);
+               r52 |= (b&0xf0) < (r2&0xf0) ? (r2&0xf0) : (b&0xf0);
+               put_cmd640_reg(cmd640_key, 0x52, r52);
+       }
+}
+
+static int bus_speed = 33; /* MHz */
+
+struct pio_timing {
+       int     mc_time;        /* Minimal cycle time (ns) */
+       int     av_time;        /* Address valid to DIOR-/DIOW- setup (ns) */
+       int     ds_time;        /* DIOR data setup      (ns) */
+} pio_timings[6] = {
+       { 70,   165,    600 },  /* PIO Mode 0 */
+       { 50,   125,    383 },  /* PIO Mode 1 */
+       { 30,   100,    240 },  /* PIO Mode 2 */
+       { 30,   80,     180 },  /* PIO Mode 3 */
+       { 25,   70,     125 },  /* PIO Mode 4 */
+       { 20,   50,     100 }   /* PIO Mode ? */
+};
+
+struct drive_pio_info {
+       const char      *name;
+       int             pio;
+} drive_pios[] = {
+       { "Maxtor 7131 AT", 1 },
+       { "Maxtor 7171 AT", 1 },
+       { "Maxtor 7213 AT", 1 },
+       { "Maxtor 7245 AT", 1 },
+       { "SAMSUNG SHD-3122A", 1 },
+       { "QUANTUM ELS127A", 0 },
+       { "QUANTUM LPS240A", 0 },
+       { "QUANTUM LPS270A", 3 },
+       { "QUANTUM LPS540A", 3 },
+       { NULL, 0 }
+};
+
+static int known_drive_pio(char* name) {
+       struct drive_pio_info* pi;
+
+       for (pi = drive_pios; pi->name != NULL; pi++) {
+               if (strcmp(pi->name, name) == 0)
+                       return pi->pio;
+       }
+       return -1;
+}
+
+static void cmd640_timings_to_regvals(int mc_time, int av_time, int ds_time,
+                               int clock_time,
+                               int* r1, int* r2)
+{
+       int a, b;
+
+       a = (mc_time + clock_time - 1)/clock_time;
+       if (a <= 2) *r1 = 0x40;
+       else if (a == 3) *r1 = 0x80;
+       else if (a == 4) *r1 = 0;
+       else *r1 = 0xc0;
+
+       a = (av_time + clock_time - 1)/clock_time;
+       if (a < 2)
+               a = 2;
+       b = (ds_time + clock_time - 1)/clock_time - a;
+       if (b < 2)
+               b = 2;
+       if (b > 0x11) {
+               a += b - 0x11;
+               b = 0x11;
+       }
+       if (a > 0xf)
+               a = 0;
+       if (cmd640_chip_version > 1)
+               b -= 1;
+       if (b > 0xf)
+               b = 0;
+       *r2 = (a << 4) | b;
+}
+
+static void set_pio_mode(int if_num, int drv_num, int mode_num) {
+       int p_base;
+       int i;
+
+       p_base = if_num ? 0x170 : 0x1f0;
+       outb(3, p_base + 1);
+       outb(mode_num | 8, p_base + 2);
+       outb((drv_num | 0xa) << 4, p_base + 6);
+       outb(0xef, p_base + 7);
+       for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
+               delay_10ms();
+}
+
+void cmd640_tune_drive(ide_drive_t* drive) {
+       int interface_number;
+       int drive_number;
+       int clock_time; /* ns */
+       int max_pio;
+       int mc_time, av_time, ds_time;
+       struct hd_driveid* id;
+       int r1, r2;
+
+       /*
+        * Determine if drive is under cmd640 control
+        */
+       interface_number = HWIF(drive) - ide_hwifs;
+       if (!is_cmd640[interface_number])
+               return;
+
+       drive_number = drive - HWIF(drive)->drives;
+       clock_time = 1000/bus_speed;
+       id = drive->id;
+       if ((max_pio = known_drive_pio(id->model)) != -1) {
+               mc_time = pio_timings[max_pio].mc_time;
+               av_time = pio_timings[max_pio].av_time;
+               ds_time = pio_timings[max_pio].ds_time;
+       } else {
+               max_pio = id->tPIO;
+               mc_time = pio_timings[max_pio].mc_time;
+               av_time = pio_timings[max_pio].av_time;
+               ds_time = pio_timings[max_pio].ds_time;
+               if (id->field_valid & 2) {
+                       if ((id->capability & 8) && (id->eide_pio_modes & 7)) {
+                               if (id->eide_pio_modes & 4) max_pio = 5;
+                               else if (id->eide_pio_modes & 2) max_pio = 4;
+                               else max_pio = 3;
+                               ds_time = id->eide_pio_iordy;
+                               mc_time = pio_timings[max_pio].mc_time;
+                               av_time = pio_timings[max_pio].av_time;
+                       } else {
+                               ds_time = id->eide_pio;
+                       }
+                       if (ds_time == 0)
+                               ds_time = pio_timings[max_pio].ds_time;
+               }
+       }
+       cmd640_timings_to_regvals(mc_time, av_time, ds_time, clock_time,
+                               &r1, &r2);
+       set_pio_mode(interface_number, drive_number, max_pio);
+       cmd640_set_timing(interface_number, drive_number, r1, r2);
+       printk ("Mode and Timing set to PIO%d (0x%x 0x%x)\n", max_pio, r1, r2);
+}
index 000a55a73545a184ed8bb843d40458c2cf5a97a0..5a2f6bd7cc37b90b94d9a5d7b6940de978cf43a6 100644 (file)
@@ -1089,10 +1089,8 @@ static inline void perpendicular_mode(void)
 {
        unsigned char perp_mode;
 
-       if (!floppy)
-               return;
-       if (floppy->rate & 0x40){
-               switch(raw_cmd->rate){
+       if (raw_cmd->rate & 0x40){
+               switch(raw_cmd->rate & 3){
                        case 0:
                                perp_mode=2;
                                break;
@@ -1222,18 +1220,18 @@ static void fdc_specify(void)
 static int fdc_dtr(void)
 {
        /* If data rate not already set to desired value, set it. */
-       if (raw_cmd->rate == FDCS->dtr)
+       if ((raw_cmd->rate & 3) == FDCS->dtr)
                return 0;
 
        /* Set dtr */
-       fd_outb(raw_cmd->rate, FD_DCR);
+       fd_outb(raw_cmd->rate & 3, FD_DCR);
 
        /* TODO: some FDC/drive combinations (C&T 82C711 with TEAC 1.2MB)
         * need a stabilization period of several milliseconds to be
         * enforced after data rate changes before R/W operations.
         * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
         */
-       FDCS->dtr = raw_cmd->rate;
+       FDCS->dtr = raw_cmd->rate & 3;
        return(wait_for_completion(jiffies+2*HZ/100,
                                   (timeout_fn) floppy_ready));
 } /* fdc_dtr */
@@ -1979,7 +1977,7 @@ static void setup_format_params(int track)
 
        raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
                /*FD_RAW_NEED_DISK |*/ FD_RAW_NEED_SEEK;
-       raw_cmd->rate = floppy->rate & 0x3;
+       raw_cmd->rate = floppy->rate & 0x43;
        raw_cmd->cmd_count = NR_F;
        COMMAND = FM_MODE(floppy,FD_FORMAT);
        DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,format_req.head);
@@ -2385,7 +2383,7 @@ static int make_raw_rw_request(void)
                SIZECODE = 2;
        } else
                SIZECODE = FD_SIZECODE(floppy);
-       raw_cmd->rate = floppy->rate & 3;
+       raw_cmd->rate = floppy->rate & 0x43;
        if ((floppy->rate & FD_2M) &&
            (TRACK || HEAD) &&
            raw_cmd->rate == 2)
@@ -2951,7 +2949,7 @@ static inline int raw_cmd_copyin(int cmd, char *param,
                rcmd = & (ptr->next);
                if (!(ptr->flags & FD_RAW_MORE))
                        return 0;
-               ptr->rate &= 0x03;
+               ptr->rate &= 0x43;
        }
 }
 
index 24057608bf6371c814d3852b5f6bdf931e95430d..0c4e55fd6c829dadba1a9a3fa33a4895eb6fdd73 100644 (file)
@@ -1,11 +1,11 @@
 /*
- *  linux/drivers/block/ide.c  Version 5.17  Nov 3, 1995
+ *  linux/drivers/block/ide.c  Version 5.18  Nov 16, 1995
  *
  *  Copyright (C) 1994, 1995  Linus Torvalds & authors (see below)
  */
 
 /*
- * This is the multiple IDE interface driver, as evolved from hd.c.  
+ * This is the multiple IDE interface driver, as evolved from hd.c.
  * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15).
  * There can be up to two drives per interface, as per the ATA-2 spec.
  *
  * Secondary i/f:  ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64
  * Tertiary i/f:   ide2: major=33; (hde)         minor=0; (hdf)         minor=64
  * Quaternary i/f: ide3: major=34; (hdg)         minor=0; (hdh)         minor=64
- * 
+ *
  * It is easy to extend ide.c to handle more than four interfaces:
  *
  *     Change the MAX_HWIFS constant in ide.h.
- * 
+ *
  *     Define some new major numbers (in major.h), and insert them into
  *     the ide_hwif_to_major table in ide.c.
- * 
+ *
  *     Fill in the extra values for the new interfaces into the two tables
  *     inside ide.c:  default_io_base[]  and  default_irqs[].
- * 
+ *
  *     Create the new request handlers by cloning "do_ide3_request()"
  *     for each new interface, and add them to the switch statement
  *     in the ide_init() function in ide.c.
@@ -56,7 +56,7 @@
  *  Maintained by Mark Lord (mlord@bnr.ca):  ide.c, ide.h, triton.c, hd.c, ..
  *
  *  This was a rewrite of just about everything from hd.c, though some original
- *  code is still sprinkled about.  Think of it as a major evolution, with 
+ *  code is still sprinkled about.  Think of it as a major evolution, with
  *  inspiration from lots of linux users, esp.  hamish@zot.apana.org.au
  *
  *  Version 1.0 ALPHA  initial code, primary i/f working okay
  *                     remove "Huh?" from cmd640 code
  *                     added qd6580 interface speed select from Colten Edwards
  *  Version 5.17       kludge around bug in BIOS32 on Intel triton motherboards
+ *  Version 5.18       new CMD640 code, moved to cmd640.c, #include'd for now
+ *                     new UMC8672 code, moved to umc8672.c, #include'd for now
+ *                     disallow turning on DMA when h/w not capable of DMA
  *
  *  Driver compile-time options are in ide.h
  *
  *  To do, in likely order of completion:
+ *     - make cmd640.c and umc8672.c compile separately from ide.c
  *     - add ALI M1443/1445 chipset support from derekn@vw.ece.cmu.edu
- *     - add Promise Caching controller support from peterd@pnd-pc.demon.co.uk
  *     - add ioctls to get/set interface timings on various interfaces
+ *     - add Promise Caching controller support from peterd@pnd-pc.demon.co.uk
  *     - modify kernel to obtain BIOS geometry for drives on 2nd/3rd/4th i/f
- *     - improved CMD support:  handed this off to someone else
  *     - find someone to work on IDE *tape drive* support
  */
 
 
 #include "ide.h"
 
+#ifdef SUPPORT_CMD640
+void cmd640_tune_drive(ide_drive_t *);
+static int cmd640_vlb = 0;
+#endif
+
        ide_hwif_t      ide_hwifs[MAX_HWIFS];           /* hwif info */
 static ide_hwgroup_t   *irq_to_hwgroup [16];
-static const byte      ide_hwif_to_major[MAX_HWIFS]   = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
+static const byte      ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
 
 static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168};
 static const byte      default_irqs[MAX_HWIFS]     = {14, 15, 11, 10};
@@ -999,7 +1007,7 @@ static void write_intr (ide_drive_t *drive)
 
 /*
  * multwrite() transfers a block of one or more sectors of data to a drive
- * as part of a disk multwrite operation.  
+ * as part of a disk multwrite operation.
  */
 static void multwrite (ide_drive_t *drive)
 {
@@ -1232,7 +1240,7 @@ static inline void do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned
        if (drive->select.b.lba) {
 #ifdef DEBUG
                printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n",
-                       drive->name, (rq->cmd==READ)?"read":"writ", 
+                       drive->name, (rq->cmd==READ)?"read":"writ",
                        block, rq->nr_sectors, (unsigned long) rq->buffer);
 #endif
                OUT_BYTE(block,io_base+IDE_SECTOR_OFFSET);
@@ -1495,7 +1503,7 @@ static void timer_expiry (unsigned long data)
                printk("%s: marginal timeout\n", drive->name);
        } else {                                 /* drive not responding */
                hwgroup->handler = NULL;
-               if (hwgroup->hwif->dmaproc) 
+               if (hwgroup->hwif->dmaproc)
                        (void) hwgroup->hwif->dmaproc (ide_dma_abort, drive);
                if (!ide_error(drive, "irq timeout", GET_STAT()))
                        do_hwgroup_request (hwgroup);
@@ -1522,7 +1530,7 @@ static void timer_expiry (unsigned long data)
  * In reality, this is a non-issue.  The new command is not sent unless the
  * drive is ready to accept one, in which case we know the drive is not
  * trying to interrupt us.  And ide_set_handler() is always invoked before
- * completing the issuance of any new drive command, so we will not be 
+ * completing the issuance of any new drive command, so we will not be
  * accidently invoked as a result of any valid command completion interrupt.
  *
  */
@@ -1806,24 +1814,24 @@ static int ide_ioctl (struct inode *inode, struct file *file,
                case BLKRAGET:
                        return write_fs_long(arg, read_ahead[MAJOR(inode->i_rdev)]);
 
-               case BLKGETSIZE:   /* Return device size */
+               case BLKGETSIZE:   /* Return device size */
                        return write_fs_long(arg, drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects);
                case BLKRRPART: /* Re-read partition tables */
                        return revalidate_disk(inode->i_rdev);
 
-                case HDIO_GET_KEEPSETTINGS:
+               case HDIO_GET_KEEPSETTINGS:
                        return write_fs_long(arg, drive->keep_settings);
 
-                case HDIO_GET_UNMASKINTR:
+               case HDIO_GET_UNMASKINTR:
                        return write_fs_long(arg, drive->unmask);
 
-                case HDIO_GET_DMA:
+               case HDIO_GET_DMA:
                        return write_fs_long(arg, drive->using_dma);
 
-                case HDIO_GET_CHIPSET:
+               case HDIO_GET_CHIPSET:
                        return write_fs_long(arg, drive->chipset);
 
-                case HDIO_GET_MULTCOUNT:
+               case HDIO_GET_MULTCOUNT:
                        return write_fs_long(arg, drive->mult_count);
 
                case HDIO_GET_IDENTITY:
@@ -1858,6 +1866,10 @@ static int ide_ioctl (struct inode *inode, struct file *file,
                        cli();
                        switch (cmd) {
                                case HDIO_SET_DMA:
+                                       if (!(HWIF(drive)->dmaproc)) {
+                                               restore_flags(flags);
+                                               return -EPERM;
+                                       }
                                        drive->using_dma = arg;
                                        break;
                                case HDIO_SET_KEEPSETTINGS:
@@ -2046,7 +2058,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
                drive->present = 1;
                drive->cyl     = drive->bios_cyl  = id->cyls;
                drive->head    = drive->bios_head = id->heads;
-               drive->sect    = drive->bios_sect = id->sectors; 
+               drive->sect    = drive->bios_sect = id->sectors;
        }
        /* Handle logical geometry translation by the drive */
        if ((id->field_valid & 1) && id->cur_cyls && id->cur_heads
@@ -2055,7 +2067,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
                /*
                 * Extract the physical drive geometry for our use.
                 * Note that we purposely do *not* update the bios info.
-                * This way, programs that use it (like fdisk) will 
+                * This way, programs that use it (like fdisk) will
                 * still have the same logical view as the BIOS does,
                 * which keeps the partition table from being screwed.
                 *
@@ -2079,7 +2091,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
        if ((!drive->head || drive->head > 16) && id->heads && id->heads <= 16) {
                drive->cyl  = id->cyls;
                drive->head = id->heads;
-               drive->sect = id->sectors; 
+               drive->sect = id->sectors;
        }
        /* Correct the number of cyls if the bios value is too small */
        if (drive->sect == drive->bios_sect && drive->head == drive->bios_head) {
@@ -2107,6 +2119,9 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
                        printk(", DMA");
        }
        printk("\n");
+#ifdef SUPPORT_CMD640
+       cmd640_tune_drive(drive);       /* but can we tune a fish? */
+#endif
 }
 
 /*
@@ -2336,8 +2351,8 @@ static void probe_for_drives (ide_hwif_t *hwif)
  * The code enables the secondary IDE controller and the PIO4 (3?) timings on
  * the primary (EIDE). You may probably have to enable the 32-bit support to
  * get the full speed. You better get the disk interrupts disabled ( hdparm -u0
- * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my 
- * filesystem  corrupted with -u1, but under heavy disk load only :-)  
+ * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my
+ * filesystem  corrupted with -u1, but under heavy disk load only :-)
  *
  * From: mlord@bnr.ca -- this chipset is now forced to use the "serialize" feature,
  * which hopefully will make it more reliable to use.. maybe it has the same bugs
@@ -2417,59 +2432,13 @@ static void init_qd6580 (void)
 }
 #endif /* SUPPORT_QD6580 */
 
-#if SUPPORT_CMD640
-/*
- * ??? fixme: 
- */
-byte read_cmd640_vlb (byte port, byte reg)
-{
-       byte val;
-
-       unsigned long flags;
-       save_flags(flags);
-       cli();
-       outw(reg, port);
-       val = inb(port+4);
-       restore_flags(flags);
-       return val;
-}
-
-void write_cmd640_vlb (byte port, byte reg, byte val)
-{
-       unsigned long flags;
-       save_flags(flags);
-       cli();
-       outw(reg, port);
-       outw(val, port+4);
-       restore_flags(flags);
-}
-
-void init_cmd640_vlb (void)
-{
-       byte reg;
-       unsigned short port = 0x178;
-
-       serialized = 1;
-       printk("ide: buggy CMD640 interface: serialized, ");
-       reg = read_cmd640_vlb(port, 0x50);
-       if (reg == 0xff || (reg & 0x90) != 0x90) {
-#if TRY_CMD640_VLB_AT_0x78
-               port = 0x78;
-               reg = read_cmd640_vlb(port, 0x50);
-               if (reg == 0xff || (reg & 0x90) != 0x90)
+#ifdef SUPPORT_UMC8672
+#include "umc8672.c"   /* until we tidy up the interface some more */
 #endif
-               {
-                       disallow_unmask = 1;
-                       printk("(probe failed) disabled unmasking\n");
-                       return;
-               }
-       }
-       write_cmd640_vlb(port, 0x51, read_cmd640_vlb(port, 0x51)|0xc8);
-       write_cmd640_vlb(port, 0x57, read_cmd640_vlb(port, 0x57)|0x0c);
-       printk("disabled read-ahead, enabled secondary\n");
 
-}
-#endif /* SUPPORT_CMD640 */
+#ifdef SUPPORT_CMD640
+#include "cmd640.c"    /* until we tidy up the interface some more */
+#endif
 
 /*
  * stridx() returns the offset of c within s,
@@ -2488,7 +2457,7 @@ static int stridx (const char *s, char c)
  * 2. if the remainder matches one of the supplied keywords,
  *     the index (1 based) of the keyword is negated and returned.
  * 3. if the remainder is a series of no more than max_vals numbers
- *     separated by commas, the numbers are saved in vals[] and a 
+ *     separated by commas, the numbers are saved in vals[] and a
  *     count of how many were saved is returned.  Base10 is assumed,
  *     and base16 is allowed when prefixed with "0x".
  * 4. otherwise, zero is returned.
@@ -2511,7 +2480,7 @@ static int match_parm (char *s, const char *keywords[], int vals[], int max_vals
                /*
                 * Look for a series of no more than "max_vals"
                 * numeric values separated by commas, in base10,
-                * or base16 when prefixed with "0x".  
+                * or base16 when prefixed with "0x".
                 * Return a count of how many were found.
                 */
                for (n = 0; (i = stridx(decimal, *s)) >= 0;) {
@@ -2621,11 +2590,18 @@ void ide_setup (char *s)
         * Look for interface options:  "idex="
         */
        if (s[0] == 'i' && s[1] == 'd' && s[2] == 'e' && s[3] >= '0' && s[3] <= max_hwif) {
-               const char *ide_words[] = {"noprobe", "serialize", "dtc2278", "ht6560b", "cmd640_vlb", "qd6580", NULL};
+               const char *ide_words[] = {"noprobe", "serialize", "dtc2278", "ht6560b",
+                                       "cmd640_vlb", "qd6580", "umc8672", NULL};
                hw = s[3] - '0';
                hwif = &ide_hwifs[hw];
 
                switch (match_parm(&s[4], ide_words, vals, 3)) {
+#if SUPPORT_UMC8672
+                       case -7: /* "umc8672" */
+                               if (hw != 0) goto bad_hwif;
+                               init_umc8672();
+                               goto done;
+#endif /* SUPPORT_UMC8672 */
 #if SUPPORT_QD6580
                        case -6: /* "qd6580" */
                                if (hw != 0) goto bad_hwif;
@@ -2635,8 +2611,7 @@ void ide_setup (char *s)
 #if SUPPORT_CMD640
                        case -5: /* "cmd640_vlb" */
                                if (hw > 1) goto bad_hwif;
-                               init_cmd640_vlb();
-                               goto do_serialize; /* not necessary once we implement the above */
+                               cmd640_vlb = 1;
                                break;
 #endif /* SUPPORT_CMD640 */
 #if SUPPORT_HT6560B
@@ -2709,7 +2684,7 @@ int ide_xlate_1024 (kdev_t i_rdev, int offset, const char *msg)
 
        drive->cyl  = drive->bios_cyl  = drive->id->cyls;
        drive->head = drive->bios_head = drive->id->heads;
-       drive->sect = drive->bios_sect = drive->id->sectors; 
+       drive->sect = drive->bios_sect = drive->id->sectors;
        drive->special.b.set_geometry = 1;
 
        tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63;
@@ -2745,7 +2720,7 @@ int ide_xlate_1024 (kdev_t i_rdev, int offset, const char *msg)
  * drives in the system -- the ones reflected as drive 1 or 2.  The first
  * drive is stored in the high nibble of CMOS byte 0x12, the second in the low
  * nibble.  This will be either a 4 bit drive type or 0xf indicating use byte
- * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.  A non-zero value 
+ * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.  A non-zero value
  * means we have an AT controller hard disk for that drive.
  *
  * Of course, there is no guarantee that either drive is actually on the
@@ -2905,45 +2880,6 @@ void init_rz1000 (byte bus, byte fn)
 }
 #endif /* SUPPORT_RZ1000 */
 
-#if SUPPORT_CMD640
-void init_cmd640 (byte bus, byte fn)
-{
-       int rc;
-       unsigned char reg;
-
-       serialized = 1;
-       printk("ide: buggy CMD640 interface: ");
-
-#if 0  /* funny.. the cmd640b I tried this on claimed to not be enabled.. */
-       unsigned short sreg;
-       if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &sreg))) {
-               ide_pci_access_error (rc);
-       } else if (!(sreg & 1)) {
-               printk("not enabled\n");
-       } else {
-
-       /*
-        * The first part is undocumented magic from the DOS driver.
-        * According to the datasheet, there is no port 0x5b on the cmd640.
-        */
-       (void) pcibios_write_config_byte(bus, fn, 0x5b, 0xbd);
-       if (pcibios_write_config_byte(bus, fn, 0x5b, 0xbd) != 0xbd)
-               printk("init_cmd640: huh? 0x5b read back wrong\n");
-       (void) pcibios_write_config_byte(bus, fn, 0x5b, 0);
-#endif /* 0 */
-       /*
-        * The rest is from the cmd640b datasheet.
-        */
-       if ((rc = pcibios_read_config_byte(bus, fn, 0x51, &reg))
-        || (rc =  pcibios_write_config_byte(bus, fn, 0x51, reg | 0xc0)) /* 0xc8 to enable 2nd i/f */
-        || (rc =  pcibios_read_config_byte(bus, fn, 0x57, &reg))
-        || (rc =  pcibios_write_config_byte(bus, fn, 0x57, reg | 0x0c)))
-               buggy_interface_fallback (rc);
-       else
-               printk("serialized, disabled read-ahead\n");
-}
-#endif /* SUPPORT_CMD640 */
-
 typedef void (ide_pci_init_proc_t)(byte, byte);
 
 /*
@@ -2966,7 +2902,7 @@ static void ide_probe_pci (unsigned short vendor, unsigned short device, ide_pci
 
 /*
  * ide_init_pci() finds/initializes "known" PCI IDE interfaces
- * 
+ *
  * This routine should ideally be using pcibios_find_class() to find
  * all IDE interfaces, but that function causes some systems to "go weird".
  */
@@ -2975,9 +2911,6 @@ static void ide_init_pci (void)
 #if SUPPORT_RZ1000
        ide_probe_pci (PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, &init_rz1000, 0);
 #endif
-#if SUPPORT_CMD640
-       ide_probe_pci (PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640, &init_cmd640, 0);
-#endif
 #ifdef CONFIG_BLK_DEV_TRITON
        /*
         * Apparently the BIOS32 services on Intel motherboards are buggy,
@@ -3008,6 +2941,9 @@ int ide_init (void)
        if (pcibios_present())
                ide_init_pci ();
 #endif /* CONFIG_PCI */
+#ifdef SUPPORT_CMD640
+       ide_probe_for_cmd640x();
+#endif
 
        /*
         * Probe for drives in the usual way.. CMOS/BIOS, then poke at ports
index bcfa18cbc64359b204f70e961e0cb852837a5f58..0c0f200815d6c222e01a6f94dd8f3a5477ee290f 100644 (file)
@@ -40,6 +40,9 @@
 #ifndef SUPPORT_CMD640                 /* 1 to support CMD640 chipset */
 #define SUPPORT_CMD640         1       /* 0 to reduce kernel size */
 #endif
+#ifndef SUPPORT_UMC8672                        /* 1 to support UMC8672 chipset */
+#define SUPPORT_UMC8672                1       /* 0 to reduce kernel size */
+#endif
 #ifndef SUPPORT_HT6560B                        /* 1 to support HT6560B chipset */
 #define SUPPORT_HT6560B                1       /* 0 to reduce kernel size */
 #endif
index 6b5a4813e5a108fd380e21f26531384fb4420ca0..cdac6b69584a52c0034a999e95716f34b1d8267b 100644 (file)
@@ -229,6 +229,19 @@ void set_device_ro(kdev_t dev,int flag)
        else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
 }
 
+static inline void drive_stat_acct(int cmd, unsigned long nr_sectors, short disk_index)
+{
+       kstat.dk_drive[disk_index]++;
+       if (cmd == READ || cmd == READA) {
+               kstat.dk_drive_rio[disk_index]++;
+               kstat.dk_drive_rblk[disk_index] += nr_sectors;
+       }
+       else if (cmd == WRITE || cmd == WRITEA) {
+               kstat.dk_drive_wio[disk_index]++;
+               kstat.dk_drive_wblk[disk_index] += nr_sectors;
+       }
+}
+
 /*
  * add-request adds a request to the linked list.
  * It disables interrupts so that it can muck with the
@@ -243,16 +256,16 @@ static void add_request(struct blk_dev_struct * dev, struct request * req)
                case SCSI_DISK_MAJOR:
                        disk_index = (MINOR(req->rq_dev) & 0x0070) >> 4;
                        if (disk_index < 4)
-                               kstat.dk_drive[disk_index]++;
+                               drive_stat_acct(req->cmd, req->nr_sectors, disk_index);
                        break;
                case IDE0_MAJOR:        /* same as HD_MAJOR */
                case XT_DISK_MAJOR:
                        disk_index = (MINOR(req->rq_dev) & 0x0040) >> 6;
-                       kstat.dk_drive[disk_index]++;
+                       drive_stat_acct(req->cmd, req->nr_sectors, disk_index);
                        break;
                case IDE1_MAJOR:
                        disk_index = ((MINOR(req->rq_dev) & 0x0040) >> 6) + 2;
-                       kstat.dk_drive[disk_index]++;
+                       drive_stat_acct(req->cmd, req->nr_sectors, disk_index);
                default:
                        break;
        }
index 972baf1a831a803a2c0cb069c69fef6d05a40a6b..fa179509eeb3d40a84ddecbb7a9aae4a690046a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/triton.c       Version 1.02  Oct 13, 1995
+ *  linux/drivers/block/triton.c       Version 1.03  Nov 16, 1995
  *
  *  Copyright (c) 1995  Mark Lord
  *  May be copied or modified under the terms of the GNU General Public License
  *       the observation that WRITEs work most of the time, depending on
  *       cache-buffer occupancy, but multi-sector reads seldom work.
  *
- * Drives like the AC31000H could likely be made to work if all DMA were done
- * one sector at a time, but that would likely negate any advantage over PIO.
+ * Testing was done with a Gigabyte GA-586 ATE system and the following drive:
+ * (Uwe Bonnes - bon@elektron.ikp.physik.th-darmstadt.de)
+ *
+ *   Western Digital AC31600H (1.6Gig w/128kB buffer), DMA mode2, PIO mode4.
+ *     - much better than its 1Gig cousin, this drive is reported to work
+ *       very well with DMA (7.3MB/sec).
  *
  * If you have any drive models to add, email your results to:  mlord@bnr.ca
  * Keep an eye on /var/adm/messages for "DMA disabled" messages.
diff --git a/drivers/block/umc8672.c b/drivers/block/umc8672.c
new file mode 100644 (file)
index 0000000..be79305
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ *  linux/drivers/block/umc8672.c      Version 0.01  Nov 16, 1995
+ *
+ *  Copyright (C) 1995  Linus Torvalds & author (see below)
+ */
+
+/*
+ *  Principal Author/Maintainer:  PODIEN@hml2.atlas.de (Wolfram Podien)
+ *
+ *  This file provides support for the advanced features
+ *  of the UMC 8672 IDE interface.
+ *
+ *  Version 0.01       Initial version, hacked out of ide.c,
+ *                     and #include'd rather than compiled separately.
+ *                     This will get cleaned up in a subsequent release.
+ */
+
+/*
+ * VLB Controller Support from 
+ * Wolfram Podien
+ * Rohoefe 3
+ * D28832 Achim
+ * Germany
+ *
+ * To enable UMC8672 support there must a lilo line like
+ * append="hd=umc8672"...
+ * To set the speed according to the abilities of the hardware there must be a
+ * line like
+ * #define UMC_DRIVE0 11
+ * in the beginning of the driver, which sets the speed of drive 0 to 11 (there
+ * are some lines present). 0 - 11 are allowed speed values. These values are
+ * the results from the DOS speed test programm supplied from UMC. 11 is the 
+ * highest speed (about PIO mode 3)
+ */
+
+/*
+ * The speeds will eventually become selectable using hdparm via ioctl's,
+ * but for now they are coded here:
+ */
+#define UMC_DRIVE0      11              /* DOS messured drive Speeds */
+#define UMC_DRIVE1      11              /* 0 - 11 allowed */
+#define UMC_DRIVE2      11              /* 11 = Highest Speed */
+#define UMC_DRIVE3      11              /* In case of crash reduce speed */
+
+void out_umc (char port,char wert)
+{
+       outb_p (port,0x108);
+       outb_p (wert,0x109);
+}
+
+byte in_umc (char port)
+{
+       outb_p (port,0x108);
+       return inb_p (0x109);
+}
+
+void init_umc8672(void)
+{
+       int i,tmp;
+       int speed [4];
+/*      0    1    2    3    4    5    6    7    8    9    10   11      */
+       char speedtab [3][12] = {
+       {0xf ,0xb ,0x2 ,0x2 ,0x2 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 },
+       {0x3 ,0x2 ,0x2 ,0x2 ,0x2 ,0x2 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 },
+       {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}};
+
+       cli ();
+       outb_p (0x5A,0x108); /* enable umc */
+       if (in_umc (0xd5) != 0xa0)
+       {
+               sti ();
+               printk ("UMC8672 not found\n");
+               return;  
+       }
+       speed[0] = UMC_DRIVE0;
+       speed[1] = UMC_DRIVE1;
+       speed[2] = UMC_DRIVE2;
+       speed[3] = UMC_DRIVE3;
+       for (i = 0;i < 4;i++)
+       {
+               if ((speed[i] < 0) || (speed[i] > 11))
+               {
+                       sti ();
+                       printk ("UMC 8672 drive speed out of range. Drive %d Speed %d\n",
+                               i, speed[i]);
+                       printk ("UMC support aborted\n");
+                       return; 
+               }
+       }
+       out_umc (0xd7,(speedtab[0][speed[2]] | (speedtab[0][speed[3]]<<4)));
+       out_umc (0xd6,(speedtab[0][speed[0]] | (speedtab[0][speed[1]]<<4)));
+       tmp = 0;
+       for (i = 3; i >= 0; i--)
+       {
+               tmp = (tmp << 2) | speedtab[1][speed[i]];
+       }
+       out_umc (0xdc,tmp);
+       for (i = 0;i < 4; i++)
+       {
+               out_umc (0xd0+i,speedtab[2][speed[i]]);
+               out_umc (0xd8+i,speedtab[2][speed[i]]);
+       }
+       outb_p (0xa5,0x108); /* disable umc */
+       sti ();
+       printk ("Speeds for UMC8672 \n");
+       for (i = 0;i < 4;i++)
+                printk ("Drive %d speed %d\n",i,speed[i]);
+}
index 8207cf810f3a7a56888a1b58cb1e88626479e2e2..9f6c632380c3fcf75631b8a422b4ac0b9c8f2258 100644 (file)
 
 */
 
-
 #include <linux/module.h>
 
-#ifdef MODULE
-#define mcd_init init_module
-#endif
-
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
@@ -88,6 +83,7 @@
 
 #define MAJOR_NR MITSUMI_CDROM_MAJOR
 #include <linux/blk.h>
+
 #define mcd_port mcd    /* for compatible parameter passing with "insmod" */
 #include <linux/mcd.h>
 
@@ -132,15 +128,10 @@ static int mcdPresent = 0;
 #endif
 /* #define DOUBLE_QUICK_ONLY */
 
-#if LINUX_VERSION_CODE < 66338
-    #define CURRENT_VALID \
-    (CURRENT && MAJOR(CURRENT -> dev) == MAJOR_NR && CURRENT -> cmd == READ \
-    && CURRENT -> sector != -1)
-#else
-    #define CURRENT_VALID \
-    (CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
-    && CURRENT -> sector != -1)
-#endif
+#define CURRENT_VALID \
+(CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
+&& CURRENT -> sector != -1)
+
 #define MFL_STATUSorDATA (MFL_STATUS | MFL_DATA)
 #define MCD_BUF_SIZ 16
 static volatile int mcd_transfer_is_active;
@@ -213,11 +204,7 @@ void mcd_setup(char *str, int *ints)
 
  
 static int
-#if LINUX_VERSION_CODE < 66338
-check_mcd_change(dev_t full_dev)
-#else
 check_mcd_change(kdev_t full_dev)
-#endif
 {
    int retval, target;
 
@@ -1173,8 +1160,7 @@ static struct file_operations mcd_fops = {
  * Test for presence of drive and initialize it.  Called at boot time.
  */
 
-int
-mcd_init(void)
+int mcd_init(void)
 {
        int count;
        unsigned char result[3];
@@ -1619,6 +1605,11 @@ Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
 }
 
 #ifdef MODULE
+int init_module(void)
+{
+       return mcd_init();
+}
+
 void cleanup_module(void)
 { if (MOD_IN_USE)
      { printk("mcd module in use - can't remove it.\n");
index 915649805343bf6a322c189cd5a625d048e320f1..1f1ef0f0c35109a28743fbca54e186ede8895fed 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * The Mitsumi CDROM interface
  * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.3
+ * VERSION: 1.5
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #if RCS
 static const char *mcdx_c_version
-               = "mcdx.c,v 1.17 1995/11/06 01:07:57 heiko Exp";
+               = "mcdx.c,v 1.19 1995/11/20 17:06:25 heiko Exp";
 #endif
 
+#include <linux/version.h>
 #include <linux/module.h>
 
 #include <linux/errno.h>
@@ -55,19 +56,6 @@ static const char *mcdx_c_version
 
 
 #include <linux/major.h>
-
-/* old kernel (doesn't know about MCDX) */
-#ifndef MITSUMI_X_CDROM_MAJOR
-#define MITSUMI_X_CDROM_MAJOR 20
-#define DEVICE_NAME "mcdx"
-
-/* #define DEVICE_INTR do_mcdx */
-#define DEVICE_REQUEST do_mcdx_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-#endif
-
 #define MAJOR_NR MITSUMI_X_CDROM_MAJOR
 #include <linux/blk.h>
 
@@ -191,18 +179,9 @@ struct s_drive_stuff {
        changed elsewhere. */
 
 /* declared in blk.h */
-#if LINUX_VERSION_CODE < 66338
-unsigned long mcdx_init(unsigned long mem_start, unsigned long mem_end);
-#else
 int mcdx_init(void);
-#endif
 void do_mcdx_request(void);
-
-#if LINUX_VERSION_CODE < 66338
-int check_mcdx_media_change(dev_t);
-#else
 int check_mcdx_media_change(kdev_t);
-#endif
 
 /* already declared in init/main */
 void mcdx_setup(char *, int *);
@@ -561,36 +540,20 @@ void do_mcdx_request()
 
        TRACE((REQUEST, "do_request()\n"));
 
-#if LINUX_VERSION_CODE < 66338
-       if ((CURRENT == NULL) || (CURRENT->dev < 0))  {
-#else
        if ((CURRENT == NULL) || (CURRENT->rq_status == RQ_INACTIVE))  {
-#endif
                TRACE((REQUEST, "do_request() done\n"));
                return;
        }
 
-#if LINUX_VERSION_CODE < 66338
-    stuffp = mcdx_stuffp[MINOR(CURRENT->dev)];
-#else
     stuffp = mcdx_stuffp[MINOR(CURRENT->rq_dev)];
-#endif
        TRACE((REQUEST, "do_request() stuffp = %p\n", stuffp));
 
     INIT_REQUEST;
-#if LINUX_VERSION_CODE < 66338
-    dev = MINOR(CURRENT->dev);
-#else
     dev = MINOR(CURRENT->rq_dev);
-#endif
 
        if ((dev < 0) || (dev >= MCDX_NDRIVES) || (!stuffp->present)) {
-#if LINUX_VERSION_CODE < 66338
-               WARN(("do_request(): bad device: 0x%04x\n", CURRENT->dev));
-#else
                WARN(("do_request(): bad device: %s\n", 
             kdevname(CURRENT->rq_dev)));
-#endif
                end_request(0);
                goto again;
     }
@@ -817,24 +780,15 @@ mcdx_close(struct inode *ip, struct file *fp)
     return;
 }
 
-#if LINUX_VERSION_CODE < 66338
-int check_mcdx_media_change(dev_t full_dev)
-#else
 int check_mcdx_media_change(kdev_t full_dev)
-#endif
 /*     Return: 1 if media changed since last call to 
                          this function
                        0 else
        Setting flag to 0 resets the changed state. */
 
 {
-#if LINUX_VERSION_CODE < 66338
-    INFO(("check_mcdx_media_change called for device %x\n",
-         full_dev));
-#else
     INFO(("check_mcdx_media_change called for device %s\n",
          kdevname(full_dev)));
-#endif
     return 0;
 }
 
@@ -1021,11 +975,7 @@ int init_module(void)
        int i;
        int drives = 0;
 
-#if LINUX_VERSION_CODE < 66338
-       mcdx_init(0, 0);
-#else
        mcdx_init();
-#endif
        for (i = 0; i < MCDX_NDRIVES; i++)  {
                if (mcdx_stuffp[i]) {
                TRACE((INIT, "init_module() drive %d stuff @ %p\n",
@@ -1097,18 +1047,14 @@ void warn(const char* fmt, ...)
 }
 
 
-#if LINUX_VERSION_CODE < 66338
-unsigned long mcdx_init(unsigned long mem_start, unsigned long mem_end)
-#else
 int mcdx_init(void)
-#endif
 {
        int drive;
 
-       WARN(("Version 1.3 "
-                       "mcdx.c,v 1.17 1995/11/06 01:07:57 heiko Exp\n"));
-       INFO((": Version 1.3 "
-                       "mcdx.c,v 1.17 1995/11/06 01:07:57 heiko Exp\n"));
+       WARN(("Version 1.5 "
+                       "mcdx.c,v 1.19 1995/11/20 17:06:25 heiko Exp\n"));
+       INFO((": Version 1.5 "
+                       "mcdx.c,v 1.19 1995/11/20 17:06:25 heiko Exp\n"));
 
        /* zero the pointer array */
        for (drive = 0; drive < MCDX_NDRIVES; drive++)
@@ -1124,18 +1070,12 @@ int mcdx_init(void)
                
                TRACE((INIT, "init() try drive %d\n", drive));
 
-#if defined(MODULE) || LINUX_VERSION_CODE > 66338
         TRACE((INIT, "kmalloc space for stuffpt's\n"));
                TRACE((MALLOC, "init() malloc %d bytes\n", size));
                if (!(stuffp = kmalloc(size, GFP_KERNEL))) {
                        WARN(("init() malloc failed\n"));
                        break; 
                }
-#else
-        TRACE((INIT, "adjust mem_start\n"));
-        stuffp = (struct s_drive_stuff *) mem_start;
-        mem_start += size;
-#endif
 
                TRACE((INIT, "init() got %d bytes for drive stuff @ %p\n", sizeof(*stuffp), stuffp));
 
@@ -1267,11 +1207,7 @@ int mcdx_init(void)
                TRACE((INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp));
        }
 
-#if MODULE || LINUX_VERSION_CODE > 66338
        return 0;
-#else
-       return mem_start;
-#endif
 }
 
 
index bbe54f6dedf4982db4f16cc1fdbe229b0abf8f83..097c5592c764d0861c1d810500695cb26f0778a5 100644 (file)
  *            Not for Sanyo drives (but sjcd is there...).
  *            Not for any other Funai drives than E2550UA (="CD200" with "F").
  *
- *  NOTE:     This is release 3.9.
+ *  NOTE:     This is release 4.0
+ *
+ *   Copyright (C) 1993, 1994, 1995  Eberhard Moenkeberg <emoenke@gwdg.de>
+ *
+ *                  If you change this software, you should mail a .diff
+ *                  file with some description lines to emoenke@gwdg.de.
+ *                  I want to know about it.
+ *
+ *                  If you are the editor of a Linux CD, you should
+ *                  enable sbpcd.c within your boot floppy kernel and
+ *                  send me one of your CDs for free.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2, or (at your option)
+ *   any later version.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   (for example /usr/src/linux/COPYING); if not, write to the Free
+ *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  VERSION HISTORY
  *
  *       Now Corey, Heiko, Ken, Leo, Vadim/Eric & Werner are invited to copy
  *       the config_spea() routine into their drivers. ;-)
  *
+ *  4.0  No "big step" - normal version increment.
+ *       Adapted the benefits from 1.3.33.
+ *       Fiddled with CDROMREADAUDIO flaws.
+ *       Avoid ReadCapacity command with CD200 drives (the MKE 1.01 version
+ *       seems not to support it).
+ *       Fulfilled "read audio" for CD200 drives, with help of Pete Heist
+ *       (heistp@rpi.edu).
  *
  *  TODO
  *
  *     the "push" towards load-free wait loops, and for the extensive mail
  *     thread which brought additional hints and bug fixes.
  *
- *   Copyright (C) 1993, 1994, 1995  Eberhard Moenkeberg <emoenke@gwdg.de>
- *
- *                  If you change this software, you should mail a .diff
- *                  file with some description lines to emoenke@gwdg.de.
- *                  I want to know about it.
- *
- *                  If you are the editor of a Linux CD, you should
- *                  enable sbpcd.c within your boot floppy kernel and
- *                  send me one of your CDs for free.
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2, or (at your option)
- *   any later version.
- *
- *   You should have received a copy of the GNU General Public License
- *   (for example /usr/src/linux/COPYING); if not, write to the Free
- *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 #ifndef SBPCD_ISSUE
 
 #include <linux/blk.h>
 
-#define VERSION "v3.9 Eberhard Moenkeberg <emoenke@gwdg.de>"
+#define VERSION "v4.0 Eberhard Moenkeberg <emoenke@gwdg.de>"
 
 /*==========================================================================*/
 /*
@@ -468,6 +475,7 @@ static int sbpcd_debug = (1<<DBG_INF);
 static int sbpcd_debug = ((1<<DBG_INF) |
                          (1<<DBG_TOC) |
                          (1<<DBG_MUL) |
+                         (1<<DBG_AUD) |
                          (1<<DBG_UPC));
 #endif DISTRIBUTION
 
@@ -522,9 +530,9 @@ static struct wait_queue *sbp_waitq = NULL;
 #define SBP_BUFFER_FRAMES 8 /* driver's own read_ahead, data mode */
 /*==========================================================================*/
 
-static u_char family0[]="MATSHITA"; /* MKE CR-52x */
-static u_char family1[]="CR-56";    /* MKE CR-56x */
-static u_char family2[]="CD200";    /* MKE CD200 */
+static u_char family0[]="MATSHITA"; /* MKE CR-521, CR-522, CR-523 */
+static u_char family1[]="CR-56";    /* MKE CR-562, CR-563 */
+static u_char family2[]="CD200";    /* MKE CD200, Funai CD200F */
 static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */
 static u_char familyT[]="CD-55";    /* TEAC CD-55A */
 
@@ -756,17 +764,6 @@ static void mark_timeout_audio(u_long i)
  */
 static void sbp_sleep(u_int time)
 {
-#ifndef MODULE
-       if (current == task[0]) 
-       {
-               del_timer(&delay_timer);
-               delay_timer.expires=jiffies+time;
-               timed_out_delay=0;
-               add_timer(&delay_timer);
-               while (!timed_out_delay) ;
-               return;
-       }
-#endif MODULE
        sti();
        current->state = TASK_INTERRUPTIBLE;
        current->timeout = jiffies + time;
@@ -904,25 +901,14 @@ static void flush_status(void)
 {
        int i;
        
-#ifdef MODULE
        sbp_sleep(15*HZ/10);
        for (i=maxtim_data;i!=0;i--) inb(CDi_status);
-#else
-       if (current == task[0])
-               for (i=maxtim02;i!=0;i--) inb(CDi_status);
-       else 
-       {
-               sbp_sleep(15*HZ/10);
-               for (i=maxtim_data;i!=0;i--) inb(CDi_status);
-       }
-#endif MODULE
 }
 /*==========================================================================*/
 static int CDi_stat_loop(void)
 {
        int i,j;
        
-#ifdef MODULE
        for(timeout = jiffies + 10*HZ, i=maxtim_data; timeout > jiffies; )
        {
                for ( ;i!=0;i--)
@@ -935,29 +921,6 @@ static int CDi_stat_loop(void)
                sbp_sleep(1);
                i = 1;
        }
-#else
-       if (current == task[0])
-               for(i=maxtim16;i!=0;i--)
-               {
-                       j=inb(CDi_status);
-                       if (!(j&s_not_data_ready)) return (j);
-                       if (!(j&s_not_result_ready)) return (j);
-                       if (fam0L_drive) if (j&s_attention) return (j);
-               }
-       else
-               for(timeout = jiffies + 10*HZ, i=maxtim_data; timeout > jiffies; )
-               {
-                       for ( ;i!=0;i--)
-                       {
-                               j=inb(CDi_status);
-                               if (!(j&s_not_data_ready)) return (j);
-                               if (!(j&s_not_result_ready)) return (j);
-                               if (fam0L_drive) if (j&s_attention) return (j);
-                       }
-                       sbp_sleep(1);
-                       i = 1;
-               }
-#endif MODULE
        msg(DBG_LCS,"CDi_stat_loop failed\n");
        return (-1);
 }
@@ -998,43 +961,21 @@ static int ResponseInfo(void)
        int i,j,st=0;
        u_long timeout;
        
-#ifdef MODULE
-       if (0)
-#else
-       if (current == task[0])
-#endif MODULE
-               for (i=0;i<response_count;i++)
+       for (i=0,timeout=jiffies+HZ;i<response_count;i++) 
+       {
+               for (j=maxtim_data; ; )
                {
-                       for (j=maxtim_8;j!=0;j--)
+                       for ( ;j!=0;j-- )
                        {
                                st=inb(CDi_status);
                                if (!(st&s_not_result_ready)) break;
                        }
-                       if (j==0) 
-                       {
-                               msg(DBG_SEQ,"ResponseInfo: not_result_ready (got %d of %d bytes).\n", i, response_count);
-                               break;
-                       }
-                       infobuf[i]=inb(CDi_info);
-               }
-       else 
-       {
-               for (i=0,timeout=jiffies+HZ;i<response_count;i++) 
-               {
-                       for (j=maxtim_data; ; )
-                       {
-                               for ( ;j!=0;j-- )
-                               {
-                                       st=inb(CDi_status);
-                                       if (!(st&s_not_result_ready)) break;
-                               }
-                               if ((j!=0)||(timeout<=jiffies)) break;
-                               sbp_sleep(1);
-                               j = 1;
-                       }
-                       if (timeout<=jiffies) break;
-                       infobuf[i]=inb(CDi_info);
+                       if ((j!=0)||(timeout<=jiffies)) break;
+                       sbp_sleep(1);
+                       j = 1;
                }
+               if (timeout<=jiffies) break;
+               infobuf[i]=inb(CDi_info);
        }
 #if 000
        while (!(inb(CDi_status)&s_not_result_ready))
@@ -1156,40 +1097,22 @@ static int ResponseStatus(void)
        
        msg(DBG_STA,"doing ResponseStatus...\n");
        if (famT_drive) return (get_state_T());
-#ifdef MODULE
-       if (0)
-#else
-       if (current == task[0])
-#endif MODULE
+       if (flags_cmd_out & f_respo3) timeout = jiffies;
+       else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
+       else timeout = jiffies + 4*HZ;
+       j=maxtim_8;
+       do
        {
-               if (flags_cmd_out & f_respo3) j = maxtim_8;
-               else if (flags_cmd_out&f_respo2) j=maxtim16;
-               else j=maxtim04;
-               for (;j!=0;j--)
-               {
+               for ( ;j!=0;j--)
+               { 
                        i=inb(CDi_status);
                        if (!(i&s_not_result_ready)) break;
                }
+               if ((j!=0)||(timeout<jiffies)) break;
+               sbp_sleep(1);
+               j = 1;
        }
-       else
-       {
-               if (flags_cmd_out & f_respo3) timeout = jiffies;
-               else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
-               else timeout = jiffies + 4*HZ;
-               j=maxtim_8;
-               do
-               {
-                       for ( ;j!=0;j--)
-                       { 
-                               i=inb(CDi_status);
-                               if (!(i&s_not_result_ready)) break;
-                       }
-                       if ((j!=0)||(timeout<jiffies)) break;
-                       sbp_sleep(1);
-                       j = 1;
-               }
-               while (1);
-       }
+       while (1);
        if (j==0) 
        {
                if ((flags_cmd_out & f_respo3) == 0)
@@ -1200,15 +1123,8 @@ static int ResponseStatus(void)
        i=inb(CDi_info);
        msg(DBG_STA,"ResponseStatus: response %02X.\n", i);
        EvaluateStatus(i);
-#if 0
-       if (fam0_drive)
-#endif
-               msg(DBG_STA,"status_bits=%02X, i=%02X\n",D_S[d].status_bits,i);
-#if 1
+       msg(DBG_STA,"status_bits=%02X, i=%02X\n",D_S[d].status_bits,i);
        return (D_S[d].status_bits);
-#else
-       return (i);
-#endif 0
 }
 /*==========================================================================*/
 static void cc_ReadStatus(void)
@@ -2463,6 +2379,7 @@ static int cc_ReadCapacity(void)
 {
        int i, j;
        
+       if (fam2_drive) return (0); /* some firmware lacks this command */
        if (famL_drive) return (0); /* some firmware lacks this command */
        if (famT_drive) return (0); /* done with cc_ReadTocDescr() */
        D_S[d].diskstate_flags &= ~cd_size_bit;
@@ -2475,12 +2392,14 @@ static int cc_ReadCapacity(void)
                        response_count=5;
                        flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
                }
+#if 00
                else if (fam2_drive)
                {
                        drvcmd[0]=CMD2_CAPACITY;
                        response_count=8;
                        flags_cmd_out=f_putcmd;
                }
+#endif
                else if (fam0_drive)
                {
                        drvcmd[0]=CMD0_CAPACITY;
@@ -2495,7 +2414,9 @@ static int cc_ReadCapacity(void)
        if (j==0) return (i);
        if (fam1_drive) D_S[d].CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET;
        else if (fam0_drive) D_S[d].CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
+#if 00
        else if (fam2_drive) D_S[d].CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
+#endif
        D_S[d].diskstate_flags |= cd_size_bit;
        msg(DBG_000,"cc_ReadCapacity: %d frames.\n", D_S[d].CDsize_frm);
        return (0);
@@ -2589,6 +2510,7 @@ static int cc_ReadTocDescr(void)
                if (i<0) return (i);
                D_S[d].size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
                D_S[d].size_blk=msf2blk(D_S[d].size_msf);
+               D_S[d].CDsize_frm=D_S[d].size_blk+1;
        }
        else if (famT_drive)
        {
@@ -3032,7 +2954,7 @@ static int check_version(void)
        response_count=9;
        flags_cmd_out=f_putcmd;
        i=cmd_out();
-       if (i<0) msg(DBG_INI,"CMD0_READERR returns %d (ok anyway).\n",i);
+       if (i<0) msg(DBG_INI,"CMD0_READ_ERR returns %d (ok anyway).\n",i);
        /* read drive version */
        clr_cmdbuf();
        for (i=0;i<12;i++) infobuf[i]=0;
@@ -3270,9 +3192,15 @@ static int check_version(void)
                }
                else if (fam2_drive)
                {
-                       msg(DBG_INF,"new drive CD200 (%s)detected.\n", D_S[d].firmware_version);
-                       msg(DBG_INF,"CD200 is not fully supported yet - CD200F should work.\n");
-                       if ((j!=1)&&(j!=101)&&(j!=35)) ask_mail(); /* unknown version at time */
+                       if (D_S[d].drive_model[5]=='F')
+                       {
+                               if ((j!=1)&&(j!=35)&&(j!=200)&&(j!=210)) ask_mail(); /* unknown version at time */
+                       }
+                       else
+                       {
+                               msg(DBG_INF,"this CD200 drive is not fully supported yet - only audio will work.\n");
+                               if ((j!=101)&&(j!=35)) ask_mail(); /* unknown version at time */
+                       }
                }
        }
        msg(DBG_LCS,"drive type %02X\n",D_S[d].drv_type);
@@ -4090,10 +4018,7 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
                
        case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
                msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
-#ifdef MODULE
-               if (D_S[d].sbp_audsiz>0)
-                       vfree(D_S[d].aud_buf);
-#endif MODULE
+               if (D_S[d].sbp_audsiz>0) vfree(D_S[d].aud_buf);
                D_S[d].aud_buf=NULL;
                D_S[d].sbp_audsiz=arg;
                if (D_S[d].sbp_audsiz>0)
@@ -4123,7 +4048,6 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
                msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
                if (fam0_drive) return (-EINVAL);
                if (famL_drive) return (-EINVAL);
-               if (fam2_drive) return (-EINVAL);
                if (famT_drive) return (-EINVAL);
                if (D_S[d].aud_buf==NULL) return (-EINVAL);
                i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
@@ -4139,8 +4063,10 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
                else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
                        block=read_audio.addr.lba;
                else return (-EINVAL);
+#if 000
                i=cc_SetSpeed(speed_150,0,0);
                if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
+#endif
                msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
                    block, blk2msf(block));
                msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
@@ -4158,6 +4084,7 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
                                flags_cmd_out |= f_respo3;
                                cc_ReadStatus();
                                if (sbp_status() != 0) break;
+                               if (st_check) cc_ReadError();
                                sbp_sleep(1);    /* wait a bit, try again */
                        }
                        if (status_tries == 0)
@@ -4188,8 +4115,13 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
                                drvcmd[5]=0;
                                drvcmd[6]=read_audio.nframes; /* # of frames */
                        }
-                       else if (fam2_drive) /* CD200: not tested yet */
+                       else if (fam2_drive)
                        {
+                               drvcmd[0]=CMD2_READ_XA2;
+                               lba2msf(block,&drvcmd[1]); /* msf-bin format required */
+                               drvcmd[4]=0;
+                               drvcmd[5]=read_audio.nframes; /* # of frames */
+                               drvcmd[6]=0x11; /* raw mode */
                        }
                        else if (famT_drive) /* CD-55A: not tested yet */
                        {
@@ -5080,7 +5012,8 @@ static int config_spea(void)
 }
 /*==========================================================================*/
 /*
- *  Test for presence of drive and initialize it.  Called at boot time.
+ *  Test for presence of drive and initialize it.
+ *  Called once at boot or load time.
  */
 #ifdef MODULE
 int init_module(void)
@@ -5183,13 +5116,10 @@ int SBPCD_INIT(void)
                D_S[d].sbp_current = 0;       /* Frame being currently read */
                D_S[d].CD_changed=1;
                D_S[d].frame_size=CD_FRAMESIZE;
+               D_S[d].f_eject=0;
 #if EJECT
                if (!fam0_drive) D_S[d].f_eject=1;
-               else D_S[d].f_eject=0;
-#else
-               D_S[d].f_eject=0;
-#endif
-               
+#endif EJECT
                cc_ReadStatus();
                i=ResponseStatus();  /* returns orig. status or p_busy_new */
                if (famT_drive) i=ResponseStatus();  /* returns orig. status or p_busy_new */
@@ -5274,7 +5204,9 @@ int SBPCD_INIT(void)
                        msg(DBG_INF,"data buffer (%d frames) not available.\n",D_S[j].sbp_bufsiz);
                        return -EIO;
                }
+#ifdef MODULE
                msg(DBG_INF,"data buffer size: %d frames.\n",SBP_BUFFER_FRAMES);
+#endif MODULE
                if (D_S[j].sbp_audsiz>0)
                {
                        D_S[j].aud_buf=(u_char *) vmalloc(D_S[j].sbp_audsiz*CD_FRAMESIZE_RAW);
@@ -5288,23 +5220,21 @@ int SBPCD_INIT(void)
        }
        blksize_size[MAJOR_NR]=sbpcd_blocksizes;
        
-#ifdef MODULE
-       return (0);
-#else
  init_done:
+#ifndef MODULE
 #if !(SBPCD_ISSUE-1)
 #ifdef CONFIG_SBPCD2
        sbpcd2_init();
-#endif
+#endif CONFIG_SBPCD2
 #ifdef CONFIG_SBPCD3
        sbpcd3_init();
-#endif
+#endif CONFIG_SBPCD3
 #ifdef CONFIG_SBPCD4
        sbpcd4_init();
-#endif
-#endif
-       return 0;
+#endif CONFIG_SBPCD4
+#endif !(SBPCD_ISSUE-1)
 #endif MODULE
+       return 0;
 }
 /*==========================================================================*/
 #ifdef MODULE
@@ -5328,8 +5258,7 @@ void cleanup_module(void)
        {
                if (D_S[j].drv_id==-1) continue;
                vfree(D_S[j].sbp_buf);
-               if (D_S[j].sbp_audsiz>0)
-                       vfree(D_S[j].aud_buf);
+               if (D_S[j].sbp_audsiz>0) vfree(D_S[j].aud_buf);
        }
        msg(DBG_INF, "%s module released.\n", major_name);
 }
index 37c391b7012bd09fff4f20e2a924975da7e5abad..e612af5e59233ef32896b5e675eaa4ece6c4a14e 100644 (file)
  *   added fasync support
  *
  * Modularised 6-Sep-95 Philip Blundell <pjb27@cam.ac.uk> 
+ *
+ * Replaced dumb busy loop with udelay()  16 Nov 95
+ *   Nathan Laredo <laredo@gnu.ai.mit.edu>
+ *
  */
 
 #include <linux/module.h>
@@ -38,6 +42,7 @@
 #include <linux/mm.h>
 #include <linux/mouse.h>
 #include <linux/random.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/segment.h>
@@ -241,8 +246,7 @@ int bus_mouse_init(void)
 
        outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
        outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
-       for (i = 0; i < 100000; i++)
-               /* busy loop */;
+       udelay(100L);   /* wait for reply from mouse */
        if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
                mouse.present = 0;
                return -EIO;
index a55b52f1be190f4bbc48b4a97c71f7bb9d57c381..c5ce8b0041b0df9529798523392f3d90b3a4492b 100644 (file)
@@ -57,6 +57,9 @@
  * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
  * <poe@daimi.aau.dk>
  *
+ * User-defined bell sound, new setterm control sequences and printk
+ * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
+ *
  */
 
 #define BLANK 0x0020
@@ -134,7 +137,7 @@ extern void vesa_unblank(void);
 extern void compute_shiftstate(void);
 extern void reset_palette(int currcons);
 extern void set_palette(void);
-extern unsigned long con_type_init(unsigned long, char *);
+extern unsigned long con_type_init(unsigned long, const char **);
 extern int set_get_cmap(unsigned char *, int);
 extern int set_get_font(unsigned char *, int, int);
 
@@ -1126,6 +1129,27 @@ static void setterm_command(int currcons)
                        blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
                        poke_blanked_console();
                        break;
+               case 10: /* set bell frequency in Hz */
+                       if (npar >= 1)
+                               bell_pitch = (par[1] < 20 || par[1] > 32767) ?
+                                       0 : 1193180 / par[1];
+                       else
+                               bell_pitch = 0x637;
+                       break;
+               case 11: /* set bell duration in msec */
+                       if (npar >= 1)
+                               bell_duration = (par[1] < 2000) ?
+                                       par[1]*HZ/1000 : 0;
+                       else
+                               bell_duration = HZ/8;
+                       break;
+               case 12: /* bring specified console to the front */
+                       if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
+                               update_screen(par[1]-1);
+                       break;
+               case 13: /* unblank the screen */
+                       unblank_screen();
+                       break;
        }
 }
 
@@ -1286,6 +1310,9 @@ static void reset_terminal(int currcons, int do_clear)
        tab_stop[3]     =
        tab_stop[4]     = 0x01010101;
 
+       bell_pitch = 0x637;
+       bell_duration = HZ/8;
+
        gotoxy(currcons,0,0);
        save_cur(currcons);
        if (do_clear)
@@ -1440,7 +1467,8 @@ static int con_write(struct tty_struct * tty, int from_user,
                 */
                switch (c) {
                        case 7:
-                               kd_mksound(0x637, HZ/8);
+                               if (bell_pitch && bell_duration)
+                                       kd_mksound(bell_pitch, bell_duration);
                                continue;
                        case 8:
                                bs(currcons);
@@ -1816,6 +1844,9 @@ void console_print(const char * b)
                return;  /* console not yet initialized */
        printing = 1;
 
+       if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
+               currcons = kmsg_redirect - 1;
+
        if (!vc_cons_allocated(currcons)) {
                /* impossible */
                printk("console_print: tty %d not allocated ??\n", currcons+1);
@@ -1909,7 +1940,7 @@ static void con_setsize(unsigned long rows, unsigned long cols)
  */
 unsigned long con_init(unsigned long kmem_start)
 {
-       char display_desc[] = "????";
+       const char *display_desc = "????";
        int currcons = 0;
        int orig_x = ORIG_X;
        int orig_y = ORIG_Y;
@@ -1954,7 +1985,7 @@ unsigned long con_init(unsigned long kmem_start)
                timer_active |= 1<<BLANK_TIMER;
        }
 
-       kmem_start = con_type_init(kmem_start, display_desc);
+       kmem_start = con_type_init(kmem_start, &display_desc);
 
        /* Initialize the variables used for scrolling (mostly EGA/VGA) */
 
index cbaf8034fb2601e6e270f688908e6d3db8ad9554..a73836ad4b20b2181e21eb940d5d55426144c4a7 100644 (file)
@@ -62,6 +62,8 @@ struct vc_data {
        unsigned char   vc_G1_charset;
        unsigned char   vc_saved_G0;
        unsigned char   vc_saved_G1;
+       unsigned int    vc_bell_pitch;          /* Console bell pitch */
+       unsigned int    vc_bell_duration;       /* Console bell duration */
        /* additional information is in vt_kern.h */
 };
 
@@ -132,6 +134,8 @@ extern struct vc vc_cons [MAX_NR_CONSOLES];
 #define        halfcolor       (vc_cons[currcons].d->vc_halfcolor)
 #define tab_stop       (vc_cons[currcons].d->vc_tab_stop)
 #define palette                (vc_cons[currcons].d->vc_palette)
+#define bell_pitch     (vc_cons[currcons].d->vc_bell_pitch)
+#define bell_duration  (vc_cons[currcons].d->vc_bell_duration)
 
 #define vcmode         (vt_cons[currcons]->vc_mode)
 #define structsize     (sizeof(struct vc_data) + sizeof(struct vt_struct))
index d4b6d87b4844d8cf990c43bf7b2dc4c35c956773..d43e40cd06d8faa3e257ac07303a52005b4e0a11 100644 (file)
@@ -301,7 +301,7 @@ set_cursor(int currcons)
 }
 
 unsigned long
-con_type_init(unsigned long kmem_start, char *display_desc)
+con_type_init(unsigned long kmem_start, const char **display_desc)
 {
         can_do_color = 1;
 
@@ -314,7 +314,7 @@ con_type_init(unsigned long kmem_start, char *display_desc)
 
         video_type = VIDEO_TYPE_TGAC;
 
-        strcpy(display_desc,"TGA");
+        *display_desc = "TGA";
 
        return kmem_start;
 }
@@ -830,17 +830,20 @@ tga_blitc(unsigned int charattr, unsigned long addr)
 
     for ( j = 0; j < TGA_F_HEIGHT_PADDED; j++ ) {
       if (j < TGA_F_HEIGHT) {
-       rowbits = *font_row++;
-       data = fontmask_bits[(rowbits>>4)&0xf];
-       data = (data & fgmask) | (~data & bgmask);
-       writel(data, dst);
-       data = fontmask_bits[rowbits&0xf];
-       data = (data & fgmask) | (~data & bgmask);
-       writel(data, (dst+1));
+       rowbits = font_row[j];
       } else {
-       writel(bgmask, dst);
-       writel(bgmask, (dst+1));
+       /* dup the last n rows only if char > 0x7f */
+       if (c & 0x80)
+         rowbits = font_row[j-(TGA_F_HEIGHT_PADDED-TGA_F_HEIGHT)];
+       else
+         rowbits = 0;
       }
+      data = fontmask_bits[(rowbits>>4)&0xf];
+      data = (data & fgmask) | (~data & bgmask);
+      writel(data, dst);
+      data = fontmask_bits[rowbits&0xf];
+      data = (data & fgmask) | (~data & bgmask);
+      writel(data, (dst+1));
       dst += stride;
     }
   } else { /* 24-plane */
@@ -854,18 +857,20 @@ tga_blitc(unsigned int charattr, unsigned long addr)
 
     for ( i = 0; i < TGA_F_HEIGHT_PADDED; i++ ) {
       if (i < TGA_F_HEIGHT) {
-       rowbits = *font_row++;
-       data = 1 << (TGA_F_WIDTH - 1);
-       for (j = 0; j < TGA_F_WIDTH; j++, data >>= 1) {
-         if (rowbits & data)
-           writel(fgmask, (dst+j));
-         else
-           writel(bgmask, (dst+j));
-       }
+       rowbits = font_row[i];
       } else {
-       for (j = 0; j < TGA_F_WIDTH; j++) {
+       /* dup the last n rows only if char > 0x7f */
+       if (c & 0x80)
+         rowbits = font_row[i-(TGA_F_HEIGHT_PADDED-TGA_F_HEIGHT)];
+       else
+         rowbits = 0;
+      }
+      data = 1 << (TGA_F_WIDTH - 1);
+      for (j = 0; j < TGA_F_WIDTH; j++, data >>= 1) {
+       if (rowbits & data)
+         writel(fgmask, (dst+j));
+       else
          writel(bgmask, (dst+j));
-       }
       }
       dst += stride;
     }
index 69d41816bcc02865875bd207462a7ade527c694b..ce4b8747fac47f8846d935b85e3e19c9ca21d799 100644 (file)
 #include <asm/io.h>
 #include <asm/segment.h>
 
+/* We really shouldn't be using this define.. */
+#define IOCCMD_MASK 0x0000ffff
+
 /* check existence of required configuration parameters */
 #if !defined(QIC02_CMD_PORT) || \
     !defined(QIC02_TAPE_IRQ) || \
index 15bf4054082983de4fa76d0959a6cadacd9b8806..7e49393a6ec3683a171c36e7e4503e9567d486fc 100644 (file)
@@ -38,6 +38,9 @@
  *
  * Reorganized FASYNC support so mouse code can share it.
  *     -- ctm@ardi.com, 9Sep95
+ *
+ * New TIOCLINUX variants added.
+ *     -- mj@k332.feld.cvut.cz, 19-Nov-95
  */
 
 #include <linux/config.h>
@@ -84,12 +87,14 @@ struct tty_ldisc ldiscs[NR_LDISCS]; /* line disc dispatch table     */
 
 /*
  * fg_console is the current virtual console,
- * last_console is the last used one
+ * last_console is the last used one,
+ * kmsg_redirect is the console for kernel messages,
  * redirect is the pseudo-tty that console output
  * is redirected to if asked by TIOCCONS.
  */
 int fg_console = 0;
 int last_console = 0;
+int kmsg_redirect = 0;
 struct tty_struct * redirect = NULL;
 struct wait_queue * keypress_wait = NULL;
 
@@ -1542,6 +1547,17 @@ static int tty_ioctl(struct inode * inode, struct file * file,
                                case 10:
                                        set_vesa_blanking(arg);
                                        return 0;
+                               case 11:        /* set kmsg redirect */
+                                       if (!suser())
+                                               return -EPERM;
+                                       retval = verify_area(VERIFY_READ,
+                                               (void *) arg+1, 1);
+                                       if (retval)
+                                               return retval;
+                                       kmsg_redirect = get_user((char *)arg+1);
+                                       return 0;
+                               case 12:        /* get fg_console */
+                                       return fg_console;
                                default: 
                                        return -EINVAL;
                        }
index ce2dc9108601751a53f767026d18664b0f254198..be204dc2e105ef3d1f83212f769daeffb2527876 100644 (file)
@@ -133,7 +133,7 @@ set_cursor(int currcons)
 }
 
 unsigned long
-con_type_init(unsigned long kmem_start, char *display_desc)
+con_type_init(unsigned long kmem_start, const char **display_desc)
 {
        if (ORIG_VIDEO_MODE == 7)       /* Is this a monochrome display? */
        {
@@ -144,14 +144,14 @@ con_type_init(unsigned long kmem_start, char *display_desc)
                {
                        video_type = VIDEO_TYPE_EGAM;
                        video_mem_term = 0xb8000;
-                       strcpy(display_desc, "EGA+");
+                       *display_desc = "EGA+";
                        request_region(0x3b0,16,"ega");
                }
                else
                {
                        video_type = VIDEO_TYPE_MDA;
                        video_mem_term = 0xb2000;
-                       strcpy(display_desc, "*MDA");
+                       *display_desc = "*MDA";
                        request_region(0x3b0,12,"mda");
                        request_region(0x3bf, 1,"mda");
                }
@@ -170,11 +170,11 @@ con_type_init(unsigned long kmem_start, char *display_desc)
 
                        if (!ORIG_VIDEO_ISVGA) {
                                video_type = VIDEO_TYPE_EGAC;
-                               strcpy(display_desc, "EGA");
+                               *display_desc = "EGA";
                                request_region(0x3c0,32,"ega");
                        } else {
                                video_type = VIDEO_TYPE_VGAC;
-                               strcpy(display_desc, "VGA+");
+                               *display_desc = "VGA+";
                                request_region(0x3c0,32,"vga+");
 
 #ifdef VGA_CAN_DO_64KB
@@ -215,7 +215,7 @@ con_type_init(unsigned long kmem_start, char *display_desc)
                {
                        video_type = VIDEO_TYPE_CGA;
                        video_mem_term = 0xba000;
-                       strcpy(display_desc, "*CGA");
+                       *display_desc = "*CGA";
                        request_region(0x3d4,2,"cga");
                }
        }
index 743d12e17806130e985f57147e95d8fc9ff8174f..4cddce55103f1b6bf6872288611e5f96a9197168 100644 (file)
@@ -478,8 +478,6 @@ void scan_scsis (struct Scsi_Host * shpnt, unchar hardcoded,
                        if (((driver_byte(SCpnt->result) & DRIVER_SENSE) ||
                             (status_byte(SCpnt->result) & CHECK_CONDITION)) &&
                            ((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) {
-                           if (SCpnt->sense_buffer[2] &0xe0)
-                               continue; /* No devices here... */
                            if(((SCpnt->sense_buffer[2] & 0xf) != NOT_READY) &&
                               ((SCpnt->sense_buffer[2] & 0xf) != UNIT_ATTENTION))
                                continue;
@@ -2313,7 +2311,7 @@ int scsi_dev_init(void)
     timer_table[SCSI_TIMER].expires = 0;
 
 
-    /* Register the core /proc/scsi entry */
+    /* Register the /proc/scsi/scsi entry */
 #if CONFIG_PROC_FS 
     proc_scsi_register(0, &proc_scsi_scsi);    
 #endif
@@ -3094,6 +3092,12 @@ int init_module(void) {
     timer_table[SCSI_TIMER].expires = 0;
     register_symtab(&scsi_symbol_table);
     scsi_loadable_module_flag = 1;
+
+    /* Register the /proc/scsi/scsi entry */
+#if CONFIG_PROC_FS
+    proc_scsi_register(0, &proc_scsi_scsi);
+#endif
+
     
     dma_sectors = PAGE_SIZE / 512;
     dma_free_sectors= dma_sectors;
@@ -3117,11 +3121,10 @@ int init_module(void) {
 
 void cleanup_module( void) 
 {
-    if (MOD_IN_USE) {
-       printk(KERN_INFO __FILE__ ": module is in use, remove rejected\n");
-       return;
-    }
-    
+#if CONFIG_PROC_FS
+    proc_scsi_unregister(0, PROC_SCSI_SCSI);
+#endif
+
     /* No, we're not here anymore. Don't show the /proc/scsi files. */
     dispatch_scsi_info_ptr = 0L;
 
index 5363e538dfb102dc97dfcc481733658a92f82df3..c8a8d2236f79cd0065fc67e916bebb5269600255 100644 (file)
@@ -46,9 +46,7 @@
  *     transfer rate if handshaking isn't working correctly.
  */
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif
 
 #include <asm/io.h>
 #include <asm/system.h>
index 23b5c9fc2cb321719f0391924727cd438627c54d..af250158164eb45b93c5f8444794c5ddfa9779e8 100644 (file)
@@ -509,7 +509,19 @@ static struct file_operations sg_fops = {
 
 
 static int sg_detect(Scsi_Device * SDp){
-    ++sg_template.dev_noticed;
+
+    switch (SDp->type) {
+       case TYPE_DISK:
+       case TYPE_MOD:
+       case TYPE_ROM:
+       case TYPE_WORM:
+       case TYPE_TAPE: break;
+       default: 
+       printk("Detected scsi generic sg%c at scsi%d, channel %d, id %d, lun %d\n",
+           'a'+sg_template.dev_noticed,
+           SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+    }
+    sg_template.dev_noticed++;
     return 1;
 }
 
index 4722731c8e5796b9878afe78269bff36aec804ac..c910b4619ee033ac7da39e7d8582dbeaeae901ba 100644 (file)
@@ -95,22 +95,13 @@ unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exe
                mpnt->vm_start = PAGE_MASK & (unsigned long) p;
                mpnt->vm_end = TASK_SIZE;
                mpnt->vm_page_prot = PAGE_COPY;
-#ifdef VM_STACK_FLAGS
                mpnt->vm_flags = VM_STACK_FLAGS;
                mpnt->vm_pte = 0;
-#else
-#  ifdef VM_GROWSDOWN
-               mpnt->vm_flags = VM_GROWSDOWN;
-#  endif
-#endif
                mpnt->vm_inode = NULL;
                mpnt->vm_offset = 0;
                mpnt->vm_ops = NULL;
                insert_vm_struct(current, mpnt);
-#ifndef VM_GROWSDOWN
-               current->mm->stk_vma = mpnt;
-#endif
-
+               current->mm->total_vm += (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
        }
        sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
        sp -= exec ? DLINFO_ITEMS*2 : 2;
@@ -792,7 +783,6 @@ do_load_elf_library(int fd){
        k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
        if(k > elf_bss) elf_bss = k;
        
-       SYS(close)(fd);
        if (error != (elf_phdata->p_vaddr & 0xfffff000)) {
                kfree(elf_phdata);
                return error;
index 72fc3f45bbf47b8f76e4d90d2caf20689e6f7480..57b0cf27fff45be5093d64d48d14f260d565612e 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -328,6 +328,7 @@ unsigned long * create_tables(char * p, struct linux_binprm * bprm, int ibcs)
                mpnt->vm_inode = NULL;
                mpnt->vm_pte = 0;
                insert_vm_struct(current, mpnt);
+               current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
        }
        sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
 #ifdef __alpha__
@@ -541,9 +542,12 @@ static void exec_mmap(void)
                        return;
                }
                *mm = *current->mm;
+               mm->def_flags = 0;      /* should future lockings be kept? */
                mm->count = 1;
                mm->mmap = NULL;
                mm->mmap_avl = NULL;
+               mm->total_vm = 0;
+               mm->rss = 0;
                current->mm->count--;
                current->mm = mm;
                new_page_tables(current);
@@ -814,6 +818,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        unsigned long error;
        unsigned long p = bprm->p;
        unsigned long fd_offset;
+       unsigned long rlim;
 
        ex = *((struct exec *) bprm->buf);              /* exec-header */
        if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 
@@ -839,6 +844,16 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        }
 #endif
 
+       /* Check initial limits. This avoids letting people circumvent
+        * size limits imposed on them by creating programs with large
+        * arrays in the data or bss.
+        */
+       rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+       if (rlim >= RLIM_INFINITY)
+               rlim = ~0;
+       if (ex.a_data + ex.a_bss > rlim)
+               return -ENOMEM;
+
        /* OK, This is the point of no return */
        flush_old_exec(bprm);
 
index 3f273e59bbdeb5c9bfb6d265636d76950d263457..bc49c72e5ba7fac216d456fffc2217eb74b40093 100644 (file)
@@ -41,11 +41,6 @@ asmlinkage int sys_setup(void)
 
        device_setup();
 
-#ifdef CONFIG_MINIX_FS
-       register_filesystem(&(struct file_system_type)
-               {minix_read_super, "minix", 1, NULL});
-#endif
-
 #ifdef CONFIG_EXT_FS
        register_filesystem(&(struct file_system_type)
                {ext_read_super, "ext", 1, NULL});
@@ -60,6 +55,12 @@ asmlinkage int sys_setup(void)
        register_filesystem(&(struct file_system_type)
                {xiafs_read_super, "xiafs", 1, NULL});
 #endif
+
+#ifdef CONFIG_MINIX_FS
+       register_filesystem(&(struct file_system_type)
+               {minix_read_super, "minix", 1, NULL});
+#endif
+
 #ifdef CONFIG_UMSDOS_FS
        register_filesystem(&(struct file_system_type)
        {UMSDOS_read_super,     "umsdos",       1, NULL});
index 35b4674ce1bc20761707c20bce552bc45c03af8d..b54bf36e05225135b45fc7ce437295eb96cb79e8 100644 (file)
@@ -349,7 +349,7 @@ static struct nfs_bool_opts
        { NULL,         0,                      0 }};
 
 
-unsigned long get_address (char **str)
+static unsigned long get_address (char **str)
 {
    unsigned long l;
    unsigned int val;
@@ -490,7 +490,7 @@ static void root_nfs_setup(void)
   sin=(struct sockaddr_in *)&server_route.rt_genmask;
   sin->sin_family=AF_INET;
   sin->sin_addr.s_addr= root_dev->pa_mask;
-  server_route.rt_dev[0]=0;
+  server_route.rt_dev=NULL;
   server_route.rt_flags=RTF_HOST|RTF_UP;
   
   /* Now add a route to the server */
index c7f8fde663b744f49897cce154a8022496c967ce..bb8b4bcefc8be93e21ce9b2c7f7bf9ef175334b5 100644 (file)
@@ -198,6 +198,10 @@ static int get_kstat(char * buffer)
        len = sprintf(buffer,
                "cpu  %u %u %u %lu\n"
                "disk %u %u %u %u\n"
+               "disk_rio %u %u %u %u\n"
+               "disk_wio %u %u %u %u\n"
+               "disk_rblk %u %u %u %u\n"
+               "disk_wblk %u %u %u %u\n"
                "page %u %u\n"
                "swap %u %u\n"
                "intr %u",
@@ -205,10 +209,16 @@ static int get_kstat(char * buffer)
                kstat.cpu_nice,
                kstat.cpu_system,
                jiffies - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system),
-               kstat.dk_drive[0],
-               kstat.dk_drive[1],
-               kstat.dk_drive[2],
-               kstat.dk_drive[3],
+               kstat.dk_drive[0], kstat.dk_drive[1],
+               kstat.dk_drive[2], kstat.dk_drive[3],
+               kstat.dk_drive_rio[0], kstat.dk_drive_rio[1],
+               kstat.dk_drive_rio[2], kstat.dk_drive_rio[3],
+               kstat.dk_drive_wio[0], kstat.dk_drive_wio[1],
+               kstat.dk_drive_wio[2], kstat.dk_drive_wio[3],
+               kstat.dk_drive_rblk[0], kstat.dk_drive_rblk[1],
+               kstat.dk_drive_rblk[2], kstat.dk_drive_rblk[3],
+               kstat.dk_drive_wblk[0], kstat.dk_drive_wblk[1],
+               kstat.dk_drive_wblk[2], kstat.dk_drive_wblk[3],
                kstat.pgpgin,
                kstat.pgpgout,
                kstat.pswpin,
index 4db3daf674e9dda04314030369e8cd1b81af0d1e..d6c9ca56d6004da03053294f12ad0a224db581d8 100644 (file)
 #define MAP_GROWSDOWN  0x1000          /* stack-like segment */
 #define MAP_DENYWRITE  0x2000          /* ETXTBSY */
 #define MAP_EXECUTABLE 0x4000          /* mark it as a executable */
+#define MAP_LOCKED     0x8000          /* lock the mapping */
 
 #define MS_ASYNC       1               /* sync memory asynchronously */
 #define MS_SYNC                2               /* synchronous memory sync */
 #define MS_INVALIDATE  4               /* invalidate the caches */
 
+#define MCL_CURRENT     8192           /* lock all currently mapped pages */
+#define MCL_FUTURE     16384           /* lock all additions to address space */
+
 #endif /* __ALPHA_MMAN_H__ */
index 0b9735ccd7a68b51991be2a6e0efa9f82100499a..a9b8dd87277bcf35e8dbde766c2d71cedac5b389 100644 (file)
@@ -72,14 +72,6 @@ __asm__ __volatile__( \
 #define PAGE_OFFSET            0xFFFFFC0000000000
 #define MAP_NR(addr)           ((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT)
 
-typedef struct {
-       unsigned count:24,
-                age:6,
-                dirty:1,
-                reserved:1;
-} mem_map_t;
-
-
 #endif /* __KERNEL__ */
 
 #endif /* _ALPHA_PAGE_H */
index 667353b226a828b31604a6524dabfc288f542eda..96b338fc48be05524ac563ed04ff090394119451 100644 (file)
 #define RLIMIT_NOFILE  6               /* max number of open files */
 #define RLIMIT_AS      7               /* address space limit(?) */
 #define RLIMIT_NPROC   8               /* max number of processes */
+#define RLIMIT_MEMLOCK 9               /* max locked-in-memory address space */
 
-#ifdef notdef
-#define RLIMIT_MEMLOCK 9               /* max locked-in-memory address space*/
-#endif
-
-#define RLIM_NLIMITS   9
+#define RLIM_NLIMITS   10
 
 #ifdef __KERNEL__
 
@@ -34,6 +31,7 @@
     { NR_OPEN,  NR_OPEN},                      /* RLIMIT_NOFILE */     \
     {LONG_MAX, LONG_MAX},                      /* RLIMIT_AS */         \
     {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER},  /* RLIMIT_NPROC */      \
+    {LONG_MAX, LONG_MAX},                      /* RLIMIT_MEMLOCK */    \
 }
 
 #endif /* __KERNEL__ */
index c53596d859370743643f8e0612500ce60a773a3a..4e125ecfd8b5e44b77a0db6015052f65ef3dcfeb 100644 (file)
 #define MAP_GROWSDOWN  0x0100          /* stack-like segment */
 #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
 #define MAP_EXECUTABLE 0x1000          /* mark it as a executable */
+#define MAP_LOCKED     0x2000          /* pages are locked */
 
 #define MS_ASYNC       1               /* sync memory asynchronously */
 #define MS_INVALIDATE  2               /* invalidate the caches */
 #define MS_SYNC                4               /* synchronous memory sync */
 
+#define MCL_CURRENT    1               /* lock all current mappings */
+#define MCL_FUTURE     2               /* lock all future mappings */
+
 #endif /* __I386_MMAN_H__ */
index 9dc925711dada98be78e054e4d268dc17de95648..defbb59226021e9c34f2520fd8d315455f1e5746 100644 (file)
@@ -92,13 +92,6 @@ __asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax")
 #define PAGE_OFFSET            0
 #define MAP_NR(addr)           (((unsigned long)(addr)) >> PAGE_SHIFT)
 
-typedef struct {
-       unsigned count:24,
-                age:6,
-                dirty:1,
-                reserved:1;
-} mem_map_t;
-
 #endif /* __KERNEL__ */
 
 #endif /* _I386_PAGE_H */
index 0b17fe5d8ae7c87534dfd72a641b8ab83ef5a598..83940d16a5ad7adbec2ec8dd21b4c8db0d1ecc0d 100644 (file)
 #define RLIMIT_RSS     5               /* max resident set size */
 #define RLIMIT_NPROC   6               /* max number of processes */
 #define RLIMIT_NOFILE  7               /* max number of open files */
+#define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space */
 
-#ifdef notdef
-#define RLIMIT_MEMLOCK 8               /* max locked-in-memory address space*/
-#endif
-
-#define RLIM_NLIMITS   8
+#define RLIM_NLIMITS   9
 
 #ifdef __KERNEL__
 
-#define INIT_RLIMITS                                                   \
-{                                                                      \
-    {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX},                                \
-    {LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM},                                \
-    {       0, LONG_MAX}, {LONG_MAX, LONG_MAX},                                \
-    {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, {NR_OPEN, NR_OPEN}       \
+#define INIT_RLIMITS                                   \
+{                                                      \
+       { LONG_MAX, LONG_MAX },                         \
+       { LONG_MAX, LONG_MAX },                         \
+       { LONG_MAX, LONG_MAX },                         \
+       { _STK_LIM, _STK_LIM },                         \
+       {        0, LONG_MAX },                         \
+       { LONG_MAX, LONG_MAX },                         \
+       { MAX_TASKS_PER_USER, MAX_TASKS_PER_USER },     \
+       { NR_OPEN, NR_OPEN },                           \
+       { LONG_MAX, LONG_MAX },                         \
 }
 
 #endif /* __KERNEL__ */
index fa08e397482a636d637d0436013020f70c121ea5..644812ab4bd29d0c53d255ad3c78b844476f797e 100644 (file)
 #define __NR_readv             145
 #define __NR_writev            146
 
+#define __NR_mlock             150
+#define __NR_munlock           151
+#define __NR_mlockall          152
+#define __NR_munlockall                153
+
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
 type name(void) \
index b67d12d1cb9b4fa87b63b50df3bf8861f47addf3..7df4ee279fb6ca84ba72cab4d159b28897c14614 100644 (file)
@@ -2,7 +2,7 @@
 #define _LINUX_BUSMOUSE_H
 
 /*
- * linux/include/linux/mouse.h: header file for Logitech Bus Mouse driver
+ * linux/include/linux/busmouse.h: header file for Logitech Bus Mouse driver
  * by James Banks
  *
  * based on information gleamed from various mouse drivers on the net
index 67ae6641b7f6055eb66b689dbe442527c108311e..5811ff0f2a76da489837939deb9cbfd6bf429288 100644 (file)
@@ -20,7 +20,7 @@
 #define CD_HEAD_SIZE         4 /* header (address) bytes per raw data frame */
 #define CD_SUBHEAD_SIZE      8 /* subheader bytes per raw XA data frame */
 #define CD_XA_HEAD        (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */
-#define CD_XA_SYNC_HEAD   (CD_XA_HEAD+12)/* sync bytes + header of XA frame */
+#define CD_XA_SYNC_HEAD   (CD_SYNC_SIZE+CD_XA_HEAD)/* sync bytes + header of XA frame */
 
 #define CD_FRAMESIZE      2048 /* bytes per frame, "cooked" mode */
 #define CD_FRAMESIZE_RAW  2352 /* bytes per frame, "raw" mode */
@@ -258,7 +258,7 @@ struct cdrom_multisession
 #define CDROMSUBCHNL           0x530b  /* (struct cdrom_subchnl) */
 
 #define CDROMREADMODE2         0x530c  /* (struct cdrom_read) */
-                                          /* read type-2 data (not suppt) */
+                                          /* read type-2 data */
 
 #define CDROMREADMODE1         0x530d  /* (struct cdrom_read) */
                                           /* read type-1 data */
@@ -290,13 +290,14 @@ struct cdrom_multisession
  */
 #define CDROMREADRAW           0x5314  /* read data in raw mode */
 #define CDROMREADCOOKED                0x5315  /* read data in cooked mode */
-#define CDROMSEEK              0x5316  /*seek msf address*/
+#define CDROMSEEK              0x5316  /* seek msf address */
   
 /*
  * for playing audio in logical block addressing mode
  */
 #define CDROMPLAYBLK           0x5317  /* (struct cdrom_blk) */
 
+
 /*
  * CD-ROM-specific SCSI command opcodes
  */
index ba93e10c6c4510a335cf5cd06b794b98c942ffbb..d954a54caaa50dab0af92f9a2dae092fe5e34c91 100644 (file)
@@ -21,7 +21,7 @@
 
 /* Now define a bunch of things for manipulating the control register.
    The top two bytes of the control register consist of 4 fields of 4
-   bytes - each field corresponds to one of the four debug registers,
+   bits - each field corresponds to one of the four debug registers,
    and indicates what types of access we trap on, and how large the data
    field is that we are looking at */
 
index 27614973c49816d09d555d8b769eefd7084b4347..1966490a74b032f98c24da78bc5750691865fc35 100644 (file)
 struct kernel_stat {
        unsigned int cpu_user, cpu_nice, cpu_system;
        unsigned int dk_drive[DK_NDRIVE];
+       unsigned int dk_drive_rio[DK_NDRIVE];
+       unsigned int dk_drive_wio[DK_NDRIVE];
+       unsigned int dk_drive_rblk[DK_NDRIVE];
+       unsigned int dk_drive_wblk[DK_NDRIVE];
        unsigned int pgpgin, pgpgout;
        unsigned int pswpin, pswpout;
        unsigned int interrupts[NR_IRQS];
index 83add42485b26e84c2acedd893d6c95d62c355b7..84440bf544fbdb30b5082a9ba0d6bc55af27b1cc 100644 (file)
@@ -26,9 +26,4 @@ struct modify_ldt_ldt_s {
 #define MODIFY_LDT_CONTENTS_STACK      1
 #define MODIFY_LDT_CONTENTS_CODE       2
 
-extern int get_ldt(void *buffer);
-extern int set_ldt_entry(int entry, unsigned long base, unsigned int limit,
-                        int seg_32bit_flag, int contents, int read_only_flag,
-                        int limit_in_pages_flag);
-
 #endif
index 2e85d0fe773c9709e777a62ee07ce6ae555f5319..907ae1b3f91909e4dc71ab1bdab709d94ee9cc4a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Definitions for the Mitsumi CDROM interface
  * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
- * VERSION: 1.3
+ * VERSION: 1.5
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
index 3c4e3c2f9f02c1fd9e7fd57880abfcefd66ef93f..a8d809c2c18fe4e7058217df56cebdbb14257ac3 100644 (file)
@@ -71,12 +71,11 @@ struct vm_area_struct {
 
 #define VM_GROWSDOWN   0x0100  /* general info on the segment */
 #define VM_GROWSUP     0x0200
-#define VM_SHM         0x0400
+#define VM_SHM         0x0400  /* shared memory area, don't swap out */
 #define VM_DENYWRITE   0x0800  /* ETXTBSY on write attempts.. */
 
 #define VM_EXECUTABLE  0x1000
-#define VM_DONTSWAP    0x2000  /* Some vm types have their own
-                                * hard-coded swap mechanism */
+#define VM_LOCKED      0x2000
 
 #define VM_STACK_FLAGS 0x0177
 
@@ -107,27 +106,14 @@ struct vm_operations_struct {
        pte_t (*swapin)(struct vm_area_struct *, unsigned long, unsigned long);
 };
 
+typedef struct {
+       unsigned count:24,
+                age:6,
+                dirty:1,
+                reserved:1;
+} mem_map_t;
+
 extern mem_map_t * mem_map;
-extern unsigned char *age_map;
-
-/* planning stage.. */
-#define P_DIRTY                0x0001
-#define P_LOCKED       0x0002
-#define P_UPTODATE     0x0004
-#define P_RESERVED     0x8000
-
-struct page_info {
-       unsigned short flags;
-       unsigned short count;
-       struct inode * inode;
-       unsigned long offset;
-       struct page_info * next_same_inode;
-       struct page_info * prev_same_inode;
-       struct page_info * next_hash;
-       struct page_info * prev_hash;
-       struct wait_queue *wait;
-};
-/* end of planning stage */
 
 /*
  * Free area management
@@ -244,6 +230,22 @@ extern unsigned long get_unmapped_area(unsigned long, unsigned long);
 
 #define avl_empty      (struct vm_area_struct *) NULL
 
+static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
+{
+       unsigned long grow;
+
+       address &= PAGE_MASK;
+       if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
+               return -ENOMEM;
+       grow = vma->vm_start - address;
+       vma->vm_start = address;
+       vma->vm_offset -= grow;
+       vma->vm_mm->total_vm += grow >> PAGE_SHIFT;
+       if (vma->vm_flags & VM_LOCKED)
+               vma->vm_mm->locked_vm += grow >> PAGE_SHIFT;
+       return 0;
+}
+
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
 static inline struct vm_area_struct * find_vma (struct task_struct * task, unsigned long addr)
 {
index dd9fb38d328edcf72df4c8da45d3df341cb3babe..ee3fcdbb50782c2b500d366e1e8a0c1869993025 100644 (file)
 /* Set this to 0 after you have configured your interface definitions right. */
 #define DISTRIBUTION 1
 
+#if DISTRIBUTION
+#define READ_AUDIO 0
+#else
 /* max. number of audio frames to read with one     */
 /* request (allocates n* 2352 bytes kernel memory!) */
 /* may be freely adjusted, f.e. 75 (= 1 sec.), at   */
 /* runtime by use of the CDROMAUDIOBUFSIZ ioctl.    */
-#define READ_AUDIO 
+#define READ_AUDIO 75
 
 /* tray control: eject tray if no disk is in (0 or 1) */
 #define JUKEBOX 1
 
 /* tray control: eject tray after last use (0 or 1) */
 #define EJECT 1
+#endif DISTRIBUTION
 
 /*==========================================================================*/
 /*==========================================================================*/
@@ -641,6 +645,7 @@ Read XA Parameter:
 
 #define CMD0_READ_XA   0x03
 #define CMD2_READ_XA   0xd4
+#define CMD2_READ_XA2  0xd5
 #define CMDL_READ_XA   CMD0_READ_XA /* really ?? */
 
 #define CMD0_READ_HEAD 0x04
@@ -683,6 +688,7 @@ Read XA Parameter:
 #define CMD2_STATUS    0x00
 #define CMDT_STATUS    CMD2_STATUS
 #define CMDL_STATUS    CMD0_STATUS
+#define CMD2_SEEK_LEADIN 0x00
 
 #define CMD0_READ_ERR  0x82
 #define CMD1_READ_ERR  CMD0_READ_ERR
index 2573a31ad1b64788ba8bad7505e3435aae1a9dcb..ad9d593bee6d4584f279e8cd33bc3e21415977b6 100644 (file)
@@ -85,6 +85,13 @@ extern int nr_running, nr_tasks;
 #define TASK_STOPPED           4
 #define TASK_SWAPPING          5
 
+/*
+ * Scheduling policies
+ */
+#define SCHED_OTHER            0
+#define SCHED_FIFO             1
+#define SCHED_RR               2
+
 #ifndef NULL
 #define NULL ((void *) 0)
 #endif
@@ -129,7 +136,8 @@ struct mm_struct {
        unsigned long start_code, end_code, start_data, end_data;
        unsigned long start_brk, brk, start_stack, start_mmap;
        unsigned long arg_start, arg_end, env_start, env_end;
-       unsigned long rss;
+       unsigned long rss, total_vm, locked_vm;
+       unsigned long def_flags;
        struct vm_area_struct * mmap;
        struct vm_area_struct * mmap_avl;
 };
@@ -140,6 +148,7 @@ struct mm_struct {
                0, 0, 0, 0, \
                0, 0, 0, 0, \
                0, 0, 0, 0, \
+               0, 0, 0, \
                0, \
                &init_mmap, &init_mmap }
 
@@ -184,7 +193,7 @@ struct task_struct {
        struct wait_queue *wait_chldexit;       /* for wait4() */
        unsigned short uid,euid,suid,fsuid;
        unsigned short gid,egid,sgid,fsgid;
-       unsigned long timeout;
+       unsigned long timeout, policy;
        unsigned long it_real_value, it_prof_value, it_virt_value;
        unsigned long it_real_incr, it_prof_incr, it_virt_incr;
        struct timer_list real_timer;
@@ -244,7 +253,7 @@ struct task_struct {
  */
 #define _STK_LIM       (8*1024*1024)
 
-#define DEF_PRIORITY   (15*HZ/100)     /* 150 ms time slices */
+#define DEF_PRIORITY   (20*HZ/100)     /* 200 ms time slices */
 
 /*
  *  INIT_TASK is used to set up the first task table, touch at
@@ -262,7 +271,7 @@ struct task_struct {
 /* suppl grps*/ {NOGROUP,}, \
 /* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \
 /* uid etc */  0,0,0,0,0,0,0,0, \
-/* timeout */  0,0,0,0,0,0,0, \
+/* timeout */  0,SCHED_OTHER,0,0,0,0,0,0, \
 /* timer */    { NULL, NULL, 0, 0, it_real_fn }, \
 /* utime */    0,0,0,0,0, \
 /* flt */      0,0,0,0,0,0, \
index 22f44e07be47cf14122bfaa907691c339417ff4b..e9290ba88245f349cde1ca5078a9a51ae42146e9 100644 (file)
@@ -40,9 +40,9 @@ struct screen_info {
        unsigned short orig_video_page;
        unsigned char  orig_video_mode;
        unsigned char  orig_video_cols;
-       unsigned short orig_video_ega_ax;
+       unsigned short unused2;
        unsigned short orig_video_ega_bx;
-       unsigned short orig_video_ega_cx;
+       unsigned short unused3;
        unsigned char  orig_video_lines;
        unsigned char  orig_video_isVGA;
        unsigned short orig_video_points;
@@ -55,9 +55,7 @@ extern struct screen_info screen_info;
 #define ORIG_VIDEO_PAGE                (screen_info.orig_video_page)
 #define ORIG_VIDEO_MODE                (screen_info.orig_video_mode)
 #define ORIG_VIDEO_COLS        (screen_info.orig_video_cols)
-#define ORIG_VIDEO_EGA_AX      (screen_info.orig_video_ega_ax)
 #define ORIG_VIDEO_EGA_BX      (screen_info.orig_video_ega_bx)
-#define ORIG_VIDEO_EGA_CX      (screen_info.orig_video_ega_cx)
 #define ORIG_VIDEO_LINES       (screen_info.orig_video_lines)
 #define ORIG_VIDEO_ISVGA       (screen_info.orig_video_isVGA)
 #define ORIG_VIDEO_POINTS       (screen_info.orig_video_points)
@@ -272,6 +270,7 @@ extern struct termios tty_std_termios;
 extern struct tty_struct * redirect;
 extern struct tty_ldisc ldiscs[];
 extern int fg_console;
+extern int kmsg_redirect;
 extern struct wait_queue * keypress_wait;
 
 extern unsigned long con_init(unsigned long);
index 8ef1fb3a55005ab032bfd471b51eacf85dc9c27b..4c299c1ecacdb9420ab9eb6b6b58b91a83b3a6d0 100644 (file)
@@ -120,6 +120,7 @@ int rows, cols;
 
 int ramdisk_size;
 int root_mountflags = MS_RDONLY;
+char *execute_command = 0;
 
 #ifdef CONFIG_ROOT_NFS
 char nfs_root_name[256] = { 0, };
@@ -421,6 +422,11 @@ static void parse_options(char *line)
                        console_loglevel = 10;
                        continue;
                }
+               if (!strncmp(line,"init=",5)) {
+                       line += 5;
+                       execute_command = line;
+                       continue;
+               }
                if (checksetup(line))
                        continue;
                /*
@@ -651,17 +657,22 @@ static int init(void * unused)
        (void) dup(0);
        (void) dup(0);
 
-       execve("/etc/init",argv_init,envp_init);
-       execve("/bin/init",argv_init,envp_init);
-       execve("/sbin/init",argv_init,envp_init);
-       /* if this fails, fall through to original stuff */
+       if (!execute_command) {
+               execve("/etc/init",argv_init,envp_init);
+               execve("/bin/init",argv_init,envp_init);
+               execve("/sbin/init",argv_init,envp_init);
+               /* if this fails, fall through to original stuff */
+
+               pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD);
+               if (pid>0)
+                       while (pid != wait(&i))
+                               /* nothing */;
+               }
 
-       pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD);
-       if (pid>0)
-               while (pid != wait(&i))
-                       /* nothing */;
        while (1) {
-               pid = kernel_thread(do_shell, "/bin/sh", SIGCHLD);
+               pid = kernel_thread(do_shell,
+                       execute_command ? execute_command : "/bin/sh",
+                       SIGCHLD);
                if (pid < 0) {
                        printf("Fork failed in init\n\r");
                        continue;
index 065a5114691c6c328646a9a9493c56b2dede8448..0196fdff70bfabb89797b941fb4ffbbdcedb868a 100644 (file)
 #ifdef CONFIG_BOGUS
 #endif
 
+#define version(a) Version_ ## a
+#define version_string(a) version(a)
+
+int version_string(LINUX_VERSION_CODE) = 0;
+
 struct new_utsname system_utsname = {
        UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION,
        UTS_MACHINE, UTS_DOMAINNAME
index c360f3d2d18a7a071cf989a3e46e9d3c7ab9ba12..d8406e6559608a8883c58ea9d7e8172103801557 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -425,6 +425,7 @@ static int shm_map (struct vm_area_struct *shmd)
        do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
 
        /* add new mapping */
+       current->mm->total_vm += (shmd->vm_end - shmd->vm_start) >> PAGE_SHIFT;
        insert_vm_struct(current, shmd);
        merge_segments(current, shmd->vm_start, shmd->vm_end);
 
@@ -516,7 +517,7 @@ asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
        shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE;
        shmd->vm_mm = current->mm;
        shmd->vm_page_prot = (shmflg & SHM_RDONLY) ? PAGE_READONLY : PAGE_SHARED;
-       shmd->vm_flags = VM_SHM | VM_MAYSHARE | VM_SHARED | VM_DONTSWAP
+       shmd->vm_flags = VM_SHM | VM_MAYSHARE | VM_SHARED
                         | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC
                         | ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE);
        shmd->vm_next_share = shmd->vm_prev_share = NULL;
index 9388432d7dcfdd58433c7a1d96a169bcc699d92b..91710258ca0521eb2187e42bcee4208d55491ec6 100644 (file)
@@ -88,6 +88,7 @@ static inline int dup_mmap(struct mm_struct * mm)
                        return -ENOMEM;
                }
                *tmp = *mpnt;
+               tmp->vm_flags &= ~VM_LOCKED;
                tmp->vm_mm = mm;
                tmp->vm_next = NULL;
                if (tmp->vm_inode) {
@@ -122,6 +123,7 @@ static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
                return -1;
        *tsk->mm = *current->mm;
        tsk->mm->count = 1;
+       tsk->mm->def_flags = 0;
        tsk->min_flt = tsk->maj_flt = 0;
        tsk->cmin_flt = tsk->cmaj_flt = 0;
        tsk->nswap = tsk->cnswap = 0;
index 76267f157604b0a9bf4ea9df2bfb4cee63b89a81..66f7cb20fa309a6972054f367d0813c08b6a680f 100644 (file)
@@ -106,9 +106,9 @@ static inline void add_to_runqueue(struct task_struct * p)
        if (p->counter > current->counter + 3)
                need_resched = 1;
        nr_running++;
-       (p->next_run = init_task.next_run)->prev_run = p;
-       p->prev_run = &init_task;
-       init_task.next_run = p;
+       (p->prev_run = init_task.prev_run)->next_run = p;
+       p->next_run = &init_task;
+       init_task.prev_run = p;
 }
 
 static inline void del_from_runqueue(struct task_struct * p)
@@ -137,6 +137,18 @@ static inline void del_from_runqueue(struct task_struct * p)
        p->prev_run = NULL;
 }
 
+static inline void move_last_runqueue(struct task_struct * p)
+{
+       struct task_struct *next = p->next_run;
+       struct task_struct *prev = p->prev_run;
+
+       next->prev_run = prev;
+       prev->next_run = next;
+       (p->prev_run = init_task.prev_run)->next_run = p;
+       p->next_run = &init_task;
+       init_task.prev_run = p;
+}
+
 /*
  * Wake up a process. Put it on the run-queue if it's not
  * already there.  The "current" process is always on the
@@ -188,6 +200,14 @@ static inline int goodness(struct task_struct * p, int this_cpu)
                return -1000;
 #endif
 
+       /*
+        * Realtime process, select the first one on the
+        * runqueue (taking priorities within processes
+        * into account).
+        */
+       if (p->policy != SCHED_OTHER)
+               return 1000 + p->priority;
+
        /*
         * Give the process a first-approximation goodness value
         * according to the number of clock-ticks it has left.
@@ -197,7 +217,7 @@ static inline int goodness(struct task_struct * p, int this_cpu)
         */
        weight = p->counter;
        if (weight) {
-
+                       
 #ifdef __SMP__
                /* Give a largish advantage to the same processor...   */
                /* (this is equivalent to penalizing other processors) */
@@ -241,6 +261,11 @@ asmlinkage void schedule(void)
 
        need_resched = 0;
        cli();
+       /* move an exhausted RR process to be last.. */
+       if (!current->counter && current->policy == SCHED_RR) {
+               current->counter = current->priority;
+               move_last_runqueue(current);
+       }
        switch (current->state) {
                case TASK_INTERRUPTIBLE:
                        if (current->signal & ~current->blocked)
index b6a2304f0672cc46d4a02a2dc0df0611d4ec20f8..5c305d81b00301599c5dc955b894880b5646628f 100644 (file)
@@ -8,6 +8,7 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-O_OBJS  := memory.o swap.o mmap.o filemap.o mprotect.o kmalloc.o vmalloc.o
+O_OBJS  := memory.o swap.o mmap.o filemap.o mprotect.o mlock.o \
+           kmalloc.o vmalloc.o
 
 include $(TOPDIR)/Rules.make
diff --git a/mm/mlock.c b/mm/mlock.c
new file mode 100644 (file)
index 0000000..2879b95
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ *     linux/mm/mlock.c
+ *
+ *  (C) Copyright 1995 Linus Torvalds
+ */
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/shm.h>
+#include <linux/errno.h>
+#include <linux/mman.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+static inline int mlock_fixup_all(struct vm_area_struct * vma, int newflags)
+{
+       vma->vm_flags = newflags;
+       return 0;
+}
+
+static inline int mlock_fixup_start(struct vm_area_struct * vma,
+       unsigned long end, int newflags)
+{
+       struct vm_area_struct * n;
+
+       n = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+       if (!n)
+               return -EAGAIN;
+       *n = *vma;
+       vma->vm_start = end;
+       n->vm_end = end;
+       vma->vm_offset += vma->vm_start - n->vm_start;
+       n->vm_flags = newflags;
+       if (n->vm_inode)
+               n->vm_inode->i_count++;
+       if (n->vm_ops && n->vm_ops->open)
+               n->vm_ops->open(n);
+       insert_vm_struct(current, n);
+       return 0;
+}
+
+static inline int mlock_fixup_end(struct vm_area_struct * vma,
+       unsigned long start, int newflags)
+{
+       struct vm_area_struct * n;
+
+       n = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+       if (!n)
+               return -EAGAIN;
+       *n = *vma;
+       vma->vm_end = start;
+       n->vm_start = start;
+       n->vm_offset += n->vm_start - vma->vm_start;
+       n->vm_flags = newflags;
+       if (n->vm_inode)
+               n->vm_inode->i_count++;
+       if (n->vm_ops && n->vm_ops->open)
+               n->vm_ops->open(n);
+       insert_vm_struct(current, n);
+       return 0;
+}
+
+static inline int mlock_fixup_middle(struct vm_area_struct * vma,
+       unsigned long start, unsigned long end, int newflags)
+{
+       struct vm_area_struct * left, * right;
+
+       left = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+       if (!left)
+               return -EAGAIN;
+       right = (struct vm_area_struct *) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+       if (!right) {
+               kfree(left);
+               return -EAGAIN;
+       }
+       *left = *vma;
+       *right = *vma;
+       left->vm_end = start;
+       vma->vm_start = start;
+       vma->vm_end = end;
+       right->vm_start = end;
+       vma->vm_offset += vma->vm_start - left->vm_start;
+       right->vm_offset += right->vm_start - left->vm_start;
+       vma->vm_flags = newflags;
+       if (vma->vm_inode)
+               vma->vm_inode->i_count += 2;
+       if (vma->vm_ops && vma->vm_ops->open) {
+               vma->vm_ops->open(left);
+               vma->vm_ops->open(right);
+       }
+       insert_vm_struct(current, left);
+       insert_vm_struct(current, right);
+       return 0;
+}
+
+static int mlock_fixup(struct vm_area_struct * vma, 
+       unsigned long start, unsigned long end, unsigned int newflags)
+{
+       int pages, retval;
+
+       if (newflags == vma->vm_flags)
+               return 0;
+
+       /* keep track of amount of locked VM */
+       pages = (end - start) >> PAGE_SHIFT;
+       if (!(newflags & VM_LOCKED))
+               pages = -pages;
+       vma->vm_mm->locked_vm += pages;
+
+       if (start == vma->vm_start) {
+               if (end == vma->vm_end)
+                       retval = mlock_fixup_all(vma, newflags);
+               else
+                       retval = mlock_fixup_start(vma, end, newflags);
+       } else {
+               if (end == vma->vm_end)
+                       retval = mlock_fixup_end(vma, start, newflags);
+               else
+                       retval = mlock_fixup_middle(vma, start, end, newflags);
+       }
+       if (!retval && (newflags & VM_LOCKED)) {
+               while (start < end) {
+                       char c = get_user((char *) start);
+                       __asm__ __volatile__("": :"r" (c));
+                       start += PAGE_SIZE;
+               }
+       }
+       return retval;
+}
+
+static int do_mlock(unsigned long start, size_t len, int on)
+{
+       unsigned long nstart, end, tmp;
+       struct vm_area_struct * vma, * next;
+       int error;
+
+       if (!suser())
+               return -EPERM;
+       len = (len + ~PAGE_MASK) & PAGE_MASK;
+       end = start + len;
+       if (end < start)
+               return -EINVAL;
+       if (end == start)
+               return 0;
+       vma = find_vma(current, start);
+       if (!vma || vma->vm_start > start)
+               return -ENOMEM;
+
+       for (nstart = start ; ; ) {
+               unsigned int newflags;
+
+               /* Here we know that  vma->vm_start <= nstart < vma->vm_end. */
+
+               newflags = vma->vm_flags | VM_LOCKED;
+               if (!on)
+                       newflags &= ~VM_LOCKED;
+
+               if (vma->vm_end >= end) {
+                       error = mlock_fixup(vma, nstart, end, newflags);
+                       break;
+               }
+
+               tmp = vma->vm_end;
+               next = vma->vm_next;
+               error = mlock_fixup(vma, nstart, tmp, newflags);
+               if (error)
+                       break;
+               nstart = tmp;
+               vma = next;
+               if (!vma || vma->vm_start != nstart) {
+                       error = -ENOMEM;
+                       break;
+               }
+       }
+       merge_segments(current, start, end);
+       return error;
+}
+
+asmlinkage int sys_mlock(unsigned long start, size_t len)
+{
+       unsigned long locked;
+       unsigned long lock_limit;
+
+       len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK;
+       start &= PAGE_MASK;
+
+       locked = len >> PAGE_SHIFT;
+       locked += current->mm->locked_vm;
+
+       lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+       lock_limit >>= PAGE_SHIFT;
+
+       /* check against resource limits */
+       if (locked > lock_limit)
+               return -ENOMEM;
+
+       /* we may lock at most half of physical memory... */
+       /* (this check is pretty bogus, but doesn't hurt) */
+       if (locked > MAP_NR(high_memory)/2)
+               return -ENOMEM;
+
+       return do_mlock(start, len, 1);
+}
+
+asmlinkage int sys_munlock(unsigned long start, size_t len)
+{
+       len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK;
+       start &= PAGE_MASK;
+       return do_mlock(start, len, 0);
+}
+
+static int do_mlockall(int flags)
+{
+       int error;
+       unsigned int def_flags;
+       struct vm_area_struct * vma;
+
+       if (!suser())
+               return -EPERM;
+
+       def_flags = 0;
+       if (flags & MCL_FUTURE)
+               def_flags = VM_LOCKED;
+       current->mm->def_flags = def_flags;
+
+       error = 0;
+       for (vma = current->mm->mmap; vma ; vma = vma->vm_next) {
+               unsigned int newflags;
+
+               newflags = vma->vm_flags | VM_LOCKED;
+               if (!(flags & MCL_CURRENT))
+                       newflags &= ~VM_LOCKED;
+               error = mlock_fixup(vma, vma->vm_start, vma->vm_end, newflags);
+               if (error)
+                       break;
+       }
+       merge_segments(current, 0, TASK_SIZE);
+       return error;
+}
+
+asmlinkage int sys_mlockall(int flags)
+{
+       unsigned long lock_limit;
+
+       if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE)))
+               return -EINVAL;
+
+       lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+       lock_limit >>= PAGE_SHIFT;
+
+       if (current->mm->total_vm > lock_limit)
+               return -ENOMEM;
+
+       /* we may lock at most half of physical memory... */
+       /* (this check is pretty bogus, but doesn't hurt) */
+       if (current->mm->total_vm > MAP_NR(high_memory)/2)
+               return -ENOMEM;
+
+       return do_mlockall(flags);
+}
+
+asmlinkage int sys_munlockall(void)
+{
+       return do_mlockall(0);
+}
index c7605b1aab6a27a767ee7e585f2ad729902b6a22..c88eb5f881e04279ba6f525c9e149892a88d9e42 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -66,6 +66,14 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
        if (off + len < off)
                return -EINVAL;
 
+       /* mlock MCL_FUTURE? */
+       if (current->mm->def_flags & VM_LOCKED) {
+               unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
+               locked += len;
+               if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+                       return -EAGAIN;
+       }
+
        /*
         * do simple checking here so the lower-level routines won't have
         * to. we assume access permissions have been handled by the open
@@ -127,6 +135,7 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
        vma->vm_end = addr + len;
        vma->vm_flags = prot & (VM_READ | VM_WRITE | VM_EXEC);
        vma->vm_flags |= flags & (VM_GROWSDOWN | VM_DENYWRITE | VM_EXECUTABLE);
+       vma->vm_flags |= current->mm->def_flags;
 
        if (file) {
                if (file->f_mode & 1)
@@ -167,6 +176,17 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
        }
        insert_vm_struct(current, vma);
        merge_segments(current, vma->vm_start, vma->vm_end);
+       current->mm->total_vm += len >> PAGE_SHIFT;
+       if (vma->vm_flags & VM_LOCKED) {
+               unsigned long start = vma->vm_start;
+               unsigned long end = vma->vm_end;
+               current->mm->locked_vm += len >> PAGE_SHIFT;
+               while (start < end) {
+                       char c = get_user((char *) start);
+                       __asm__ __volatile__("": :"r" (c));
+                       start += PAGE_SIZE;
+               }
+       }
        return addr;
 }
 
@@ -604,6 +624,9 @@ static void unmap_fixup(struct vm_area_struct *area,
                       area->vm_start, area->vm_end, addr, end);
                return;
        }
+       area->vm_mm->total_vm -= len >> PAGE_SHIFT;
+       if (area->vm_flags & VM_LOCKED)
+               area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
 
        /* Unmapping the whole area */
        if (addr == area->vm_start && end == area->vm_end) {
@@ -747,6 +770,9 @@ void exit_mmap(struct mm_struct * mm)
        mpnt = mm->mmap;
        mm->mmap = NULL;
        mm->mmap_avl = NULL;
+       mm->rss = 0;
+       mm->total_vm = 0;
+       mm->locked_vm = 0;
        while (mpnt) {
                struct vm_area_struct * next = mpnt->vm_next;
                if (mpnt->vm_ops) {
index 637485d45e68a063696d03ede20071b7b62ff85f..0c437c6b3af72281cfc4874f2c1765c9f08e18ce 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -566,15 +566,10 @@ static int swap_out_vma(struct task_struct * tsk, struct vm_area_struct * vma,
        unsigned long end;
 
        /* Don't swap out areas like shared memory which have their
-           own separate swapping mechanism. */
-       if (vma->vm_flags & VM_SHM)
+           own separate swapping mechanism or areas which are locked down */
+       if (vma->vm_flags & (VM_SHM | VM_LOCKED))
                return 0;
 
-       /* Don't swap out areas like shared memory which have their
-           own separate swapping mechanism. */
-       if (vma->vm_flags & VM_DONTSWAP)
-               return 0;
-       
        end = vma->vm_end;
        while (start < end) {
                int result = swap_out_pgd(tsk, vma, pgdir, start, end, limit);
index 9414f0772338489054850fa2fcdd9dc13e2ae76f..da8cd3beec99fe8b99160111cd76d0e6bfc8feb4 100644 (file)
  *             Craig Schlenter :       Don't modify permanent entry 
  *                                     during arp_rcv.
  *             Russ Nelson     :       Tidied up a few bits.
+ *             Alexey Kuznetsov:       Major changes to caching and behaviour,
+ *                                     eg intelligent arp probing and generation
+ *                                     of host down events.
+ *             Alan Cox        :       Missing unlock in device events.
  */
 
 /* RFC1122 Status:
 #include <linux/if_arp.h>
 #include <linux/in.h>
 #include <linux/mm.h>
-#include <asm/system.h>
-#include <asm/segment.h>
-#include <stdarg.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/trdevice.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/stat.h>
+
 #include <net/ip.h>
+#include <net/icmp.h>
 #include <net/route.h>
 #include <net/protocol.h>
 #include <net/tcp.h>
-#include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/arp.h>
 #ifdef CONFIG_AX25
 #include <net/netrom.h>
 #endif
 #endif
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
 
+#include <asm/system.h>
+#include <asm/segment.h>
+
+#include <stdarg.h>
 
 /*
  *     This structure defines the ARP mapping cache. As long as we make changes
@@ -600,6 +607,7 @@ int arp_device_event(struct notifier_block *this, unsigned long event, void *ptr
                                pentry = &entry->next;  /* go to next entry */
                }
        }
+       arp_unlock();
        return NOTIFY_DONE;
 }
 
@@ -1179,6 +1187,7 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev,
                                 */
                                else
                                {
+#if 0                          
                                        /*
                                         * FIXME: ICMP HOST UNREACHABLE should be
                                         *        sent in this situation. --ANK
@@ -1188,6 +1197,9 @@ int arp_find(unsigned char *haddr, u32 paddr, struct device *dev,
                                                skb->sk->err = EHOSTDOWN;
                                                skb->sk->error_report(skb->sk);
                                        }
+#else
+                                       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
+#endif                                                                         
                                        dev_kfree_skb(skb, FREE_WRITE);
                                }
                        }