]> git.neil.brown.name Git - history.git/commitdiff
Import 2.0.9 2.0.9
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:11:12 +0000 (15:11 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:11:12 +0000 (15:11 -0500)
35 files changed:
CREDITS
Documentation/Changes
Documentation/filesystems/affs.txt
Documentation/ide.txt
Makefile
arch/alpha/defconfig
arch/i386/Makefile
drivers/block/Config.in
drivers/block/ali14xx.c
drivers/block/cmd640.c
drivers/block/dtc2278.c
drivers/block/genhd.c
drivers/block/ide.c
drivers/block/ide.h
drivers/block/triton.c
drivers/cdrom/mcdx.c
drivers/char/keyboard.c
drivers/char/mem.c
drivers/char/psaux.c
drivers/char/tty_io.c
drivers/scsi/ChangeLog.ncr53c8xx
drivers/scsi/ncr53c8xx.c
drivers/scsi/ncr53c8xx.h
drivers/scsi/scsi.c
drivers/sound/dmabuf.c
drivers/sound/pss.c
fs/affs/inode.c
fs/inode.c
fs/isofs/dir.c
fs/isofs/inode.c
include/asm-m68k/ide.h
include/linux/affs_fs_sb.h
ipc/shm.c
mm/filemap.c
mm/memory.c

diff --git a/CREDITS b/CREDITS
index 6cfc586cc6aed04333b34e8630dda8cc2d95d208..7abf7b6d420930a572b5b9ef3bb011e4acfe7741 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1004,9 +1004,10 @@ S: Germany
 
 N: David C. Niemi
 E: niemi@erols.com
-D: Mtools/VFAT/floppy work, benchmarking, random kernel dilettante
+D: Assistant maintainer of Mtools, fdutils, and floppy driver
+D: Administrator of WAUUG Linux Server, http://linux.wauug.org
 S: 2364 Old Trail Drive
-S: Reston, Virginia 22091
+S: Reston, Virginia 20191
 S: USA
 
 N: Michael O'Reilly
@@ -1449,7 +1450,7 @@ S: Fargo, ND  58122
 S: USA
 
 N: Hans-Joachim Widmaier
-E: jbhr@sofal.tynet.sub.org
+E: hjw@zvw.de
 D: AFFS rewrite
 S: Eichenweg 16
 S: 73650 Winterbach
index 621efab2f62cd1c6452abb267ce1994233959b80..266e3dc4daf53e219927c7853102bb1ea5568105 100644 (file)
@@ -22,7 +22,11 @@ prefer a HTML-ized shopping list.
 documento, consultad la traduccion de Alfredo Sanjuan en
 http://slug.ctv.es/~alfredo/Cambios.html.
 
-Last updated: July 13, 1996.
+   Akik magyarul szeretnenek olvasni az uj kernellel kapcsolatos
+valtozasokrol, az alabbi cimen megtalaljak Nyitrai Tamas forditasat:
+http://www.datanet.hu/generations/linux/newkernel.html.
+
+Last updated: July 21, 1996.
 Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
 
 Current Releases
@@ -40,7 +44,9 @@ Current Releases
 - Gpm                   1.09
 - SysVinit              2.64
 - Util-linux            2.5
+- Mount                  2.5k
 - Net-tools              1.32-alpha
+- Kbd                    0.91
 
 Upgrade notes
 *************
@@ -225,6 +231,15 @@ Kbd
    For those of you needing non-ASCII character/font support, you should
 upgrade to ftp.funet.fi:/pub/OS/Linux/PEOPLE/Linus/kbd-0.91.tar.gz.
 
+Mount
+=====
+
+   The mount util is distributed as part of util-linux, which is
+currently at release 2.5.  Some may find, especially when using the
+loop or xiafs file system, NFS, or automounting, that they need to
+upgrade to the latest release of mount, available from
+ftp://ftp.win.tue.nl/pub/linux/util/mount-2.5k.tar.gz.
+
 Console
 =======
 
@@ -318,7 +333,7 @@ ftp://louie.udel.edu/pub/ntp/xntp3.5f.tar.Z.
 Sound driver
 ============
 
-   The sound driver was upgraded in the 1.3.x kernels, breaking vplay.
+   The sound driver was upgraded in the 2.0.x kernels, breaking vplay.
 To fix this problem, get a new version of the sndkit from
 ftp://ftp.best.com/pub/front/tasd/snd-util-3.5.tar.gz.  Some users
 report that various other sound utils (cdd2wav-sbpcd, for example) need
@@ -352,7 +367,7 @@ Loop device
 file as a file system, which can allow for all sorts of cool things
 like encrypted file systems and such.  To use it, you'll need a
 modified version of mount from
-ftp://ftp.win.tue.nl/pub/linux/util/mount-2.5X.tar.gz; preliminary work
+ftp://ftp.win.tue.nl/pub/linux/util/mount-2.5k.tar.gz; preliminary work
 on encrypted file system support can be found in
 ftp.funet.fi:/pub/OS/Linux/BETA/loop/des.1.tar.gz.
 
@@ -463,7 +478,9 @@ groff
 pages due to changes in groff.  If your man pages display <AD> for -
 when present at the end of a line, try setting an appropriate value
 (many have reported success with "latin1", for example) for the
-environmental variable LESSCHARSET.
+environmental variable LESSCHARSET.  Another, and probably better,
+solution is to edit the file /usr/lib/man.config and change all
+`-Tlatin1' options to `-Tascii'.
 
 How to know the version of the installed programs
 *************************************************
index f561b5c8724025d666e6486e807150e00c34d163..c5d329ec60271b7d54fb37db6f7609cac9ba9121 100644 (file)
@@ -1,26 +1,28 @@
 Amiga filesystems Overview
 ==========================
 
-Not all varieties of the Amiga filesystems are supported.  The Amiga
-currently knows 6 different filesystems:
+Not all varieties of the Amiga filesystems are supported for reading and
+writing. The Amiga currently knows 6 different filesystems:
 
 DOS\0          The old or original filesystem, not really suited for
                hard disks and normally not used on them, either.
+               Supported read/write.
 
-DOS\1          The original Fast File System. Supported.
+DOS\1          The original Fast File System. Supported read/write.
 
 DOS\2          The old "international" filesystem. International means that
                a bug has been fixed so that accented ("international") letters
                in file names are case-insensitive, as they ought to be.
+               Supported read/write.
 
-DOS\3          The "international" Fast File System.  Supported.
+DOS\3          The "international" Fast File System.  Supported read/write.
 
 DOS\4          The original filesystem with directory cache. The directory
                cache speeds up directory accesses on floppies considerably,
                but slows down file creation/deletion. Doesn't make much
-               sense on hard disks. Not supported.
+               sense on hard disks. Supported read only.
 
-DOS\5          The Fast File System with directory cache. Not supported.
+DOS\5          The Fast File System with directory cache. Supported read only.
 
 All of the above filesystems allow block sizes from 512 to 32K bytes.
 Supported block sizes are: 512, 1024, 2048 and 4096 bytes. Larger blocks
@@ -47,9 +49,6 @@ setuid[=uid]  This sets the owner of all files and directories in the file
 
 setgid[=gid]   Same as above, but for gid.
 
-use_mp         The uid and gid are taken from the now covered mount point
-               instead of the current user or value defined.
-
 mode=mode      Sets the mode flags to the given (octal) value, regardless
                of the original permissions. Directories will get an x
                permission, if the corresponding r bit is set.
@@ -72,6 +71,13 @@ quiet                The file system will not return an error for disallowed
 verbose                The volume name, file system type and block size will
                be written to the syslog.
 
+prefix=path    Path will be prefixed to every absolute path name of
+               symbolic links on an AFFS partition. Default = /
+
+volume=name    When symbolic links with an absolute path are created
+               on an AFFS partition, volume will be prepended as the
+               volume name. Default = "" (empty string).
+
 Handling of the Users/Groups and protection flags
 =================================================
 
@@ -109,9 +115,33 @@ The Linux rwxrwxrwx file mode is handled as follows:
 Newly created files and directories will get the user and group id
 of the current user and a mode according to the umask.
 
-Command line example
-====================
-    mount  Archive/Amiga/Workbench3.1.adf /mnt -t affs -o loop,size=1760
+Symbolic links
+==============
+
+Although the Amiga and Linux file systems resemble each other, there
+are some, not always subtle, differences. One of them becomes apparent
+with symbolic links. While Linux has a file system with exactly one
+root directory, the Amiga has a seperate root directory for each
+file system (i. e. partition, floppy disk, ...). With the Amiga,
+these entities are called "volumes". They have symbolic names which
+can be used to access them. Thus, symbolic links can point to a
+different volume. AFFS turns the volume name into a directory name
+and prepends the prefix path (see prefix option) to it.
+
+Example:
+You mount all your Amiga partitions under /amiga/<volume> (where
+<volume> is the name of the volume), and you give the option
+"prefix=/amiga/" when mounting all your AFFS partitions. (They
+might be "User", "WB" and "Graphics", the mount points /amiga/User,
+/amiga/WB and /amiga/Graphics). A symbolic link referring to
+"User:sc/include/dos/dos.h" will be followed to
+"/amiga/User/sc/include/dos/dos.h".
+
+Examples
+========
+
+Command line
+    mount  Archive/Amiga/Workbench3.1.adf /mnt -t affs -o loop,reserved=4
     mount  /dev/sda3 /Amiga -t affs
 
 /etc/fstab example
@@ -151,7 +181,7 @@ Until then, you should do
     ln -s /bin/true /etc/fs/mkfs.affs
 
 It's not possible to read floppy disks with a normal PC or workstation
-due to an incompatibility to the Amiga floppy controller.
+due to an incompatibility with the Amiga floppy controller.
 
 If you are interested in an Amiga Emulator for Linux, look at
 
index f4e6e2d9931a1d0f13f07d2a8c195da58ce0a34a..177a5f8d1b8094ef5446acfe9cabeb1be340db76 100644 (file)
@@ -107,7 +107,7 @@ IRQ numbers being used by the interfaces (normally IRQ14 & IRQ15).
 Interfaces beyond the first two are not normally probed for, but may be
 specified using kernel "command line" options.  For example,
 
-       ide3=0x168,0x36e,10     /* ioports 0x1e8-0x1ef,0x3f0, irq 11 */
+       ide3=0x168,0x36e,10     /* ioports 0x168-0x16f,0x36e, irq 11 */
 
 Normally the irq number need not be specified, as ide.c will probe for it:
 
@@ -120,6 +120,9 @@ The standard port, and irq values are these:
        ide2=0x1e8,0x3ee,11
        ide3=0x168,0x36e,10
 
+Note that the first parameter reserves 8 contiguous ioports, whereas the
+second value denotes a single ioport. If in doubt, do a 'cat /proc/ioports'.
+
 In all probability the device uses these ports and irqs if it is attached
 to the appropriate ide channel.  Pass the parameter for the correct ide
 channel to the kernel, as explained above.
index 6636f57e855b26e21a7e103552ac0ad0e66f8fb8..e1837ebb1a40cc2d56980a5ab70c42298b42eebf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 0
-SUBLEVEL = 8
+SUBLEVEL = 9
 
 ARCH = i386
 
index a62299b3e524f22ec8afe55905e112597ccb8601..aa455f95a457d006c4deb4f131ff838f94a6eea1 100644 (file)
@@ -62,6 +62,7 @@ CONFIG_BLK_DEV_FD=y
 CONFIG_BLK_DEV_RAM=y
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_HD is not set
 
 #
 # Networking options
index c26c10c1d250aa1a3e4fea9fea6f41a92655253c..e5bb0e11c17501f5c92fae6d3b14eb3e9608afbe 100644 (file)
@@ -40,7 +40,7 @@ CPP=$(CC) -E -D__ELF__
 OBJDUMP=$(CROSS_COMPILE)objdump
 OBJDUMP_FLAGS=-k -q 
 ENCAPS=$(CROSS_COMPILE)encaps
-OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment
+OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -R .stab -R .stabstr
 ZLDFLAGS=-e startup_32 
 LDFLAGS=-e stext
 ZIMAGE_OFFSET=0x1000
index fb673fbfd2bba8f636c2463f6d5c31bd8024e353..2db84516199ea05e3758d5b047b1130783d8b07f 100644 (file)
@@ -16,13 +16,13 @@ else
   bool '   Support removable IDE interfaces (PCMCIA)' CONFIG_BLK_DEV_IDE_PCMCIA
   bool '   CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640
   if [ "$CONFIG_PCI" = "y" ]; then
-    bool '   Intel 430FX (Triton) chipset DMA support' CONFIG_BLK_DEV_TRITON
     bool '   RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000
+    bool '   Intel 82371 PIIX (Triton I/II) DMA support' CONFIG_BLK_DEV_TRITON
   fi
   bool '   Other IDE chipset support' CONFIG_IDE_CHIPSETS
   if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
     comment 'Note: most of these also require special kernel boot parameters'
-    bool '      ALI M1439/M1445 support' CONFIG_BLK_DEV_ALI14XX
+    bool '      ALI M14xx       support' CONFIG_BLK_DEV_ALI14XX
     bool '      DTC-2278        support' CONFIG_BLK_DEV_DTC2278
     bool '      Holtek HT6560B  support' CONFIG_BLK_DEV_HT6560B
     if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -50,6 +50,8 @@ tristate 'XT harddisk support' CONFIG_BLK_DEV_XD
 
 if [ "$CONFIG_BLK_DEV_HD_IDE" = "y" -o "$CONFIG_BLK_DEV_HD_ONLY" = "y" ]; then
   define_bool CONFIG_BLK_DEV_HD y
+else
+  define_bool CONFIG_BLK_DEV_HD n
 fi
 
 endmenu
index 717d717790edaeee9840b66da4411b53dde1d9ef..4a591fda95b3608d0a2712b929151b2354d5f7ad 100644 (file)
@@ -7,6 +7,8 @@
 /*
  * ALI M14xx chipset EIDE controller
  *
+ * Works for ALI M1439/1443/1445/1487/1489 chipsets.
+ *
  * Adapted from code developed by derekn@vw.ece.cmu.edu.  -ml
  * Derek's notes follow:
  *
  *
  * Derek Noonburg  (derekn@ece.cmu.edu)
  * 95-sep-26
+ *
+ * Update 96-jul-13:
+ *
+ * I've since upgraded to two disks and a CD-ROM, with no trouble, and
+ * I've also heard from several others who have used it successfully.
+ * This driver appears to work with both the 1443/1445 and the 1487/1489
+ * chipsets.  I've added support for PIO mode 4 for the 1487.  This
+ * seems to work just fine on the 1443 also, although I'm not sure it's
+ * advertised as supporting mode 4.  (I've been running a WDC AC21200 in
+ * mode 4 for a while now with no trouble.)  -Derek
  */
 
 #undef REALLY_SLOW_IO           /* most systems can safely undef this */
@@ -45,8 +57,8 @@
  * from 25 to 50.  Setting this too *low* will make the EIDE
  * controller unable to communicate with the disks.
  *
- * I suggest using a default of 50, since it should work ok with any
- * system.  (Low values cause problems because it multiplies by bus speed
+ * The value is 50 by default -- this should work ok with any system.
+ * (Low values cause problems because it multiplies by bus speed
  * to get cycles, and thus gets a too-small cycle count and tries to
  * access the disks too fast.  I tried this once under DOS and it locked
  * up the system.)     -- derekn@vw.ece.cmu.edu
@@ -71,11 +83,13 @@ static RegInitializer initData[] = {
 };
 
 /* default timing parameters for each PIO mode */
-static struct { int time1, time2; } timeTab[4] = {
+#define ALI_MAX_PIO 4
+static struct { int time1, time2; } timeTab[ALI_MAX_PIO+1] = {
        {600, 165},     /* PIO 0 */
        {383, 125},     /* PIO 1 */
        {240, 100},     /* PIO 2 */
-       {180,  80}      /* PIO 3 */
+       {180,  80},     /* PIO 3 */
+       {120,  70}      /* PIO 4 */
 };
 
 /* timing parameter registers for each drive */
@@ -127,20 +141,20 @@ static void ali14xx_tune_drive (ide_drive_t *drive, byte pio)
 
        if (pio == 255)
                pio = ide_get_best_pio_mode(drive);
-       if (pio > 3)
-               pio = 3;
+       if (pio > ALI_MAX_PIO)
+               pio = ALI_MAX_PIO;
 
        /* calculate timing, according to PIO mode */
        time1 = timeTab[pio].time1;
        time2 = timeTab[pio].time2;
-       if (pio == 3) {
+       if (pio >= 3) {
                time1a = (id->capability & 0x08) ? id->eide_pio_iordy : id->eide_pio;
                if (time1a != 0 && time1a < time1)
                        time1 = time1a;
        }
        param3 = param1 = (time2 * ALI_14xx_BUS_SPEED + 999) / 1000;
        param4 = param2 = (time1 * ALI_14xx_BUS_SPEED + 999) / 1000 - param1;
-       if (pio != 3) {
+       if (pio < 3) {
                param3 += 8;
                param4 += 8;
        }
index 5647f0575b7eb3a4cee458400552d2c5b4186de9..a24f4e0dcd19af60c0de9298c1fc9f35b0ec5d82 100644 (file)
@@ -1,15 +1,26 @@
 /*
- *  linux/drivers/block/cmd640.c       Version 0.09  Mar 19, 1996
+ *  linux/drivers/block/cmd640.c       Version 0.12  Jul 22, 1996
  *
  *  Copyright (C) 1995-1996  Linus Torvalds & authors (see below)
  */
 
 /*
- *  Principal Author/Maintainer:  abramov@cecmow.enet.dec.com (Igor Abramov)
+ *  Original author:   abramov@cecmow.enet.dec.com (Igor Abramov)
+ *
+ *  Maintained by:     s0033las@sun10.vsz.bme.hu (Laszlo Peter)
+ *                     mlord@pobox.com (Mark Lord)
  *
  *  This file provides support for the advanced features and bugs
  *  of IDE interfaces using the CMD Technologies 0640 IDE interface chip.
  *
+ *  These chips are basically fucked by design, and getting this driver
+ *  to work on every motherboard design that uses this screwed chip seems
+ *  bloody well impossible.  However, we're still trying.
+ *
+ *  We think version 0.12 should work for most folks.
+ *  User feedback is essential.
+ *
+ *
  *  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.
@@ -23,8 +34,8 @@
  *                     with read ahead mode. Separate function for setting
  *                     readahead is added, possibly it will be called some
  *                     day from ioctl processing code.
- *  
- *  Version 0.04       Now configs/compiles separate from ide.c  -ml 
+ *
+ *  Version 0.04       Now configs/compiles separate from ide.c  -ml
  *
  *  Version 0.05       Major rewrite of interface timing code.
  *                     Added new function cmd640_set_mode to set PIO mode
@@ -33,9 +44,9 @@
  *  Version 0.06       More code cleanup. Readahead is enabled only for
  *                     detected hard drives, not included in readahead
  *                     black list.
- * 
+ *
  *  Version 0.07       Changed to more conservative drive tuning policy.
- *                     Unknown drives, which report PIO < 4 are set to 
+ *                     Unknown drives, which report PIO < 4 are set to
  *                     (reported_PIO - 1) if it is supported, or to PIO0.
  *                     List of known drives extended by info provided by
  *                     CMD at their ftp site.
  *
  *  Version 0.09       Try to be smarter about 2nd port enabling.  -ml
  *  Version 0.10       Be nice and don't reset 2nd port.  -ml
- *                     
+ *  Version 0.11       Try to handle more wierd situations.  -ml
+ *
+ *  Version 0.12       Lots of bug fixes from Laszlo Peter
+ *                     irq unmasking disabled for reliability.  -lp
+ *                     try to be even smarter about the second port.  -lp
+ *                     tidy up source code formatting.  -ml
  */
 
 #undef REALLY_SLOW_IO          /* most systems can safely undef this */
@@ -61,6 +77,8 @@
 #include "ide.h"
 #include "ide_modes.h"
 
+#define PARANOID_ABOUT_CMD640  1       /* used to tag superstitious code */
+
 int cmd640_vlb = 0;
 
 /*
@@ -109,8 +127,8 @@ int cmd640_vlb = 0;
 static ide_tuneproc_t cmd640_tune_drive;
 
 /* Interface to access cmd640x registers */
-static void (*put_cmd640_reg)(int reg_no, int val);
-       byte (*get_cmd640_reg)(int reg_no);
+void (*put_cmd640_reg)(int reg_no, int val);
+byte (*get_cmd640_reg)(int reg_no);
 
 enum { none, vlb, pci1, pci2 };
 static int     bus_type = none;
@@ -119,8 +137,9 @@ static int  cmd640_key;
 static int     bus_speed; /* MHz */
 
 /*
- * For some unknown reasons pcibios functions which read and write registers
- * do not always work with cmd640. We use direct IO instead.
+ * The CMD640x chip does not support DWORD config write cycles, but some
+ * of the BIOSes use them to implement the config services.
+ * We use direct IO instead.
  */
 
 /* PCI method 1 access */
@@ -302,18 +321,17 @@ static void cmd640_reset_controller(int iface_no)
  *  Returns 1 if an IDE interface/drive exists at 0x170,
  *  Returns 0 otherwise.
  */
-int secondary_port_responding (void)
+static int secondary_port_responding (void)
 {
        /*
         * Test for hardware at 0x170 (secondary IDE port).
-        * Leave the enable-bit alone if something responds.
         */
-       outb_p(0x0a,0x176);             /* select drive0 */
-       udelay(1);
-       if (inb_p(0x176) == 0xff) {
-               outb_p(0x0b,0x176);     /* select drive1 */
-               udelay(1);
-               if (inb_p(0x176) == 0xff)
+       outb_p(0xa0, 0x170 + IDE_SELECT_OFFSET);        /* select drive0 */
+       udelay(100);
+       if (inb_p(0x170 + IDE_SELECT_OFFSET) != 0xa0) {
+               outb_p(0xb0, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */
+               udelay(100);
+               if (inb_p(0x170 + IDE_SELECT_OFFSET) != 0xb0)
                        return 0;       /* nothing is there */
        }
        return 1;                       /* something is there */
@@ -325,8 +343,9 @@ int secondary_port_responding (void)
 
 int ide_probe_for_cmd640x(void)
 {
-       int  second_port_toggled = 0;
-        byte b;
+       int second_port_toggled = 0;
+       int second_port_cmd640 = 0;
+       byte b;
 
        if (probe_for_cmd640_pci1()) {
                bus_type = pci1;
@@ -339,10 +358,12 @@ int ide_probe_for_cmd640x(void)
                return 0;
        }
 
+#ifdef PARANOID_ABOUT_CMD640
        ide_hwifs[0].serialized = 1;    /* ensure this *always* gets set */
        ide_hwifs[1].serialized = 1;    /* ensure this *always* gets set */
+#endif
 
-#if 0  
+#if 0
        /* Dump initial state of chip registers */
        for (b = 0; b != 0xff; b++) {
                printk(" %2x%c", get_cmd640_reg(b),
@@ -374,33 +395,55 @@ int ide_probe_for_cmd640x(void)
        /*
         * Setup the most conservative timings for all drives,
         */
+
+       put_cmd640_reg(CMDTIM, 0);
+
        put_cmd640_reg(ARTTIM0, 0xc0);
        put_cmd640_reg(ARTTIM1, 0xc0);
-       put_cmd640_reg(ARTTIM23, 0xcc); /* 0xc0? */
+       put_cmd640_reg(ARTTIM23, 0xcc); /* disable read-ahead for drives 2&3 */
+
+       put_cmd640_reg(DRWTIM0, 0);
+       put_cmd640_reg(DRWTIM1, 0);
+       put_cmd640_reg(DRWTIM23, 0);
 
        /*
         * Set the maximum allowed bus speed (it is safest until we
         *                                    find how to detect bus speed)
         * Normally PCI bus runs at 33MHz, but often works overclocked to 40
         */
-       bus_speed = (bus_type == vlb) ? 50 : 40; 
+       bus_speed = (bus_type == vlb) ? 50 : 40;
 
-        /*
+       /*
         * Setup Control Register
         */
-       b = get_cmd640_reg(CNTRL);      
-
-       if (!secondary_port_responding()) {
-               b ^= CNTRL_ENA_2ND;     /* toggle the bit */
-               second_port_toggled = 1;
-       }
+       b = get_cmd640_reg(CNTRL);
 
        /*
         * Disable readahead for drives at primary interface
         */
        b |= (CNTRL_DIS_RA0 | CNTRL_DIS_RA1);
+       put_cmd640_reg(CNTRL, b);
+
+       if (!ide_hwifs[1].noprobe) {
+
+               if (secondary_port_responding()) {
+
+                       if ((b & CNTRL_ENA_2ND) || (bus_type == vlb))
+                               second_port_cmd640 = 1;
+
+               } else if (!(b & CNTRL_ENA_2ND) && (bus_type != vlb)) {
 
-        put_cmd640_reg(CNTRL, b);
+                       second_port_toggled = 1;
+                       put_cmd640_reg(CNTRL, b | CNTRL_ENA_2ND); /* Enable second interface */
+
+                       if (secondary_port_responding())
+                               second_port_cmd640 = 1;
+                       else {
+                               second_port_toggled = 0;
+                               put_cmd640_reg(CNTRL, b); /* Disable second interface */
+                       }
+               }
+       }
 
        /*
         * Note that we assume that the first interface is at 0x1f0,
@@ -408,6 +451,8 @@ int ide_probe_for_cmd640x(void)
         */
        ide_hwifs[0].chipset = ide_cmd640;
        ide_hwifs[0].tuneproc = &cmd640_tune_drive;
+       ide_hwifs[0].no_unmask = 1;
+
        if (ide_hwifs[0].drives[0].autotune == 0)
                ide_hwifs[0].drives[0].autotune = 1;
        if (ide_hwifs[0].drives[1].autotune == 0)
@@ -416,27 +461,29 @@ int ide_probe_for_cmd640x(void)
        /*
         * Initialize 2nd IDE port, if required
         */
-       if (secondary_port_responding()) {
+       if (second_port_cmd640) {
+
+#ifndef PARANOID_ABOUT_CMD640
+               ide_hwifs[0].serialized = 1;
+               ide_hwifs[1].serialized = 1;
+#endif
+
                ide_hwifs[1].chipset = ide_cmd640;
                ide_hwifs[1].tuneproc = &cmd640_tune_drive;
+               ide_hwifs[1].no_unmask = 1;
+
                if (ide_hwifs[1].drives[0].autotune == 0)
                        ide_hwifs[1].drives[0].autotune = 1;
                if (ide_hwifs[1].drives[1].autotune == 0)
                        ide_hwifs[1].drives[1].autotune = 1;
-               /* disable read-ahead for drives 2 & 3 */
-               put_cmd640_reg(ARTTIM23, (DIS_RA2 | DIS_RA3));
 
-               if (second_port_toggled) {
-                       /* reset PIO timings for drives 2 & 3 */
-                       put_cmd640_reg(DRWTIM23, 0);
-               }
 #if 0
                /* reset the secondary interface */
                cmd640_reset_controller(1);
 #endif
        }
 
-       printk("ide: buggy CMD640%c interface on ", 
+       printk("ide: buggy CMD640%c interface on ",
               'A' - 1 + cmd640_chip_version);
        switch (bus_type) {
                case vlb :
@@ -450,15 +497,12 @@ int ide_probe_for_cmd640x(void)
                        break;
        }
 
-#if 0
-       /* reset PIO timings for drives 1 & 2 */
-       put_cmd640_reg(CMDTIM, 0);
-#endif /* 0 */
-
        /*
         * Tell everyone what we did to their system
         */
-       printk("; serialized, secondary port %s\n", second_port_toggled ? "toggled" : "untouched");
+       printk(":%s serialized, second port %s\n",
+               second_port_cmd640 ? "" : " not",
+               second_port_toggled ? "toggled" : "untouched");
        return 1;
 }
 
@@ -470,7 +514,7 @@ int cmd640_off(void) {
        if (bus_type == none || a == 1)
                return 0;
        a = 1;
-       b = get_cmd640_reg(CNTRL);      
+       b = get_cmd640_reg(CNTRL);
        b &= ~CNTRL_ENA_2ND;
        put_cmd640_reg(CNTRL, b);
        return 1;
@@ -482,35 +526,48 @@ int cmd640_off(void) {
  *  in the future it could be called from ioctl
  */
 
-static void set_readahead_mode(int mode, int if_num, int dr_num)
+static void set_readahead_mode(ide_drive_t* drive, int mode)
 {
-       static int masks[2][2] = 
-               { 
-                       {CNTRL_DIS_RA0, CNTRL_DIS_RA1}, 
+       static int masks[2][2] =
+               {
+                       {CNTRL_DIS_RA0, CNTRL_DIS_RA1},
                        {DIS_RA2,       DIS_RA3}
                };
-
-       int port = (if_num == 0) ? CNTRL : ARTTIM23;
-       int mask = masks[if_num][dr_num];
        byte b;
 
+       int interface_number = HWIF(drive)->index;
+       int drive_number = drive->select.b.unit;
+
+       int port = (interface_number == 0) ? CNTRL : ARTTIM23;
+       int mask = masks[interface_number][drive_number];
+
        b = get_cmd640_reg(port);
+
+       /*
+        * I don't know why it is necessary, but without this my machine
+        * locks up, if bus_speed is not correct. And it even allows me
+        * to use 32 bit transfers on the primary port (hdparm -c1).
+        */
+       if ((interface_number == 0) && mode)
+               b|=0x27;
+
        if (mode)
                b &= ~mask;     /* Enable readahead for specific drive */
        else
                b |= mask;      /* Disable readahead for specific drive */
+
        put_cmd640_reg(port, b);
-}              
+}
 
-static struct readahead_black_list {
+static const struct readahead_black_list {
        const char*     name;
-       int             mode;   
+       int             mode;
 } drives_ra[] = {
-        { "QUANTUM LIGHTNING 540A", 0 },
-        { "ST3655A",   0 },
-        { "SAMSUNG",   0 },    /* Be conservative */
-       { NULL, 0 }
-};     
+       { "QUANTUM LIGHTNING 540A", 0 },
+       { "ST3655A",    0 },
+       { "SAMSUNG",    0 },    /* Be conservative */
+       { NULL,         0 }
+};
 
 static int strmatch(const char* pattern, const char* name) {
        char c1, c2;
@@ -534,7 +591,7 @@ static int known_drive_readahead(char* name) {
                        return drives_ra[i].mode;
                }
        }
-        return -1;
+       return -1;
 }
 
 static int arttim[4]  = {2, 2, 2, 2};  /* Address setup count (in clocks) */
@@ -542,7 +599,7 @@ static int a_count[4] = {1, 1, 1, 1};       /* Active count   (encoded) */
 static int r_count[4] = {1, 1, 1, 1};  /* Recovery count (encoded) */
 
 /*
- * Convert address setup count from number of clocks 
+ * Convert address setup count from number of clocks
  * to representation used by controller
  */
 
@@ -575,6 +632,7 @@ static void cmd640_set_timing(int if_num, int dr_num)
 {
        int     b_reg;
        int     ac, rc, at;
+       byte b;
 
        /*
         * Set address setup count and drive read/write timing registers.
@@ -588,22 +646,28 @@ static void cmd640_set_timing(int if_num, int dr_num)
                at = arttim[dr_num];
                ac = a_count[dr_num];
                rc = r_count[dr_num];
+               b = pack_arttim(at);
        } else {
                b_reg = ARTTIM23;
                at = max(arttim[2], arttim[3]);
                ac = max(a_count[2], a_count[3]);
                rc = max(r_count[2], r_count[3]);
+
+               /*
+                * Protect the readahead bits
+                */
+               b = pack_arttim(at) | (get_cmd640_reg(ARTTIM23) & (DIS_RA2 | DIS_RA3));
        }
 
-       put_cmd640_reg(b_reg, pack_arttim(at));
+       put_cmd640_reg(b_reg, b);
        put_cmd640_reg(b_reg + 1, pack_counts(ac, rc));
 
        /*
-        * Update CMDTIM (IDE Command Block Timing Register) 
+        * Update CMDTIM (IDE Command Block Timing Register)
         */
 
-       ac = max4(r_count);
-       rc = max4(a_count);
+       ac = max4(a_count);
+       rc = max4(r_count);
        put_cmd640_reg(CMDTIM, pack_counts(ac, rc));
 }
 
@@ -611,17 +675,17 @@ static void cmd640_set_timing(int if_num, int dr_num)
  * Standard timings for PIO modes
  */
 
-static 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) */
+static const struct pio_timing {
+       int     mc_time;        /* Address setup (ns) min */
+       int     av_time;        /* Active pulse (ns) min */
+       int     ds_time;        /* Cycle time (ns) min = Active pulse + Recovery pulse */
 } 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  -- should be 120, not 125 */
-       { 20,   50,     100 }   /* PIO Mode ? (nonstandard) */
+       { 30,   80,     180 },  /* PIO Mode 3 w/IORDY */
+       { 25,   70,     125 },  /* PIO Mode 4 w/IORDY -- should be 120, not 125 */
+       { 20,   50,     100 }   /* PIO Mode 5 w/IORDY (nonstandard) */
 };
 
 static void cmd640_timings_to_clocks(int mc_time, int av_time, int ds_time,
@@ -657,11 +721,13 @@ static void set_pio_mode(int if_num, int drv_num, int mode_num) {
        int i;
 
        p_base = if_num ? 0x170 : 0x1f0;
-       outb_p(3, p_base + 1);
-       outb_p(mode_num | 8, p_base + 2);
-       outb_p((drv_num | 0xa) << 4, p_base + 6);
-       outb_p(0xef, p_base + 7);
-       for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
+
+       outb_p(3, p_base + IDE_FEATURE_OFFSET);
+       outb_p(mode_num | 0x08, p_base + IDE_NSECTOR_OFFSET);
+       outb_p((drv_num | 0x0a) << 4, p_base + IDE_SELECT_OFFSET);
+       outb_p(WIN_SETFEATURES, p_base + IDE_COMMAND_OFFSET);
+
+       for (i = 0; (i < 100) && (inb(p_base + IDE_STATUS_OFFSET) & BUSY_STAT); i++)
                udelay(10000);
 }
 
@@ -669,11 +735,13 @@ static void set_pio_mode(int if_num, int drv_num, int mode_num) {
  * Set a specific pio_mode for a drive
  */
 
-static void cmd640_set_mode(ide_drive_t* drive, int pio_mode) {
+static void cmd640_set_mode(ide_drive_t* drive, byte pio_mode, int ds_time) {
        int interface_number;
        int drive_number;
        int clock_time; /* ns */
-       int mc_time, av_time, ds_time;
+       int mc_time, av_time;
+
+       if (pio_mode > 5) return;
 
        interface_number = HWIF(drive)->index;
        drive_number = drive->select.b.unit;
@@ -681,7 +749,7 @@ static void cmd640_set_mode(ide_drive_t* drive, int pio_mode) {
 
        mc_time = pio_timings[pio_mode].mc_time;
        av_time = pio_timings[pio_mode].av_time;
-       ds_time = pio_timings[pio_mode].ds_time;
+       ds_time = (ds_time != 0) ? ds_time : pio_timings[pio_mode].ds_time;
 
        cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
                                interface_number*2 + drive_number);
@@ -691,29 +759,29 @@ static void cmd640_set_mode(ide_drive_t* drive, int pio_mode) {
 
 /*
  * Drive PIO mode "autoconfiguration".
- * Ideally, this code should *always* call cmd640_set_mode(), but it doesn't.
  */
 
 static void cmd640_tune_drive(ide_drive_t *drive, byte pio_mode) {
-       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 ds_time;
        int readahead;  /* there is a global named read_ahead */
+       int overridden;
+       int iordy;
+       struct hd_driveid* id;
 
        if (pio_mode != 255) {
-               cmd640_set_mode(drive, pio_mode);
+               cmd640_set_mode(drive, pio_mode, 0);
                return;
        }
 
-       interface_number = HWIF(drive)->index;
-       drive_number = drive->select.b.unit;
-       clock_time = 1000/bus_speed;
+       overridden = 0;
+       iordy = 0;
        id = drive->id;
+
        if ((max_pio = ide_scan_pio_blacklist(id->model)) != -1) {
                ds_time = pio_timings[max_pio].ds_time;
+               overridden = 1;
+               iordy = (max_pio > 2);
        } else {
                max_pio = id->tPIO;
                ds_time = pio_timings[max_pio].ds_time;
@@ -723,27 +791,28 @@ static void cmd640_tune_drive(ide_drive_t *drive, byte pio_mode) {
                                else if (id->eide_pio_modes & 2) max_pio = 4;
                                else max_pio = 3;
                                ds_time = id->eide_pio_iordy;
+                               iordy = 1;
                        } else {
                                ds_time = id->eide_pio;
                        }
-                       if (ds_time == 0)
+                       if (ds_time == 0) {
                                ds_time = pio_timings[max_pio].ds_time;
+                               iordy = (max_pio > 2);
+                       }
                }
 
                /*
                 * Conservative "downgrade"
                 */
                if (max_pio < 4 && max_pio != 0) {
-                       max_pio -= 1;
-                       ds_time = pio_timings[max_pio].ds_time;         
+                       max_pio--;
+                       overridden = 1;
+                       iordy = (max_pio > 2);
+                       ds_time = pio_timings[max_pio].ds_time;
                }
        }
-       mc_time = pio_timings[max_pio].mc_time;
-       av_time = pio_timings[max_pio].av_time;
-       cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
-                               interface_number*2 + drive_number);
-       set_pio_mode(interface_number, drive_number, max_pio);
-       cmd640_set_timing(interface_number, drive_number);
+
+       cmd640_set_mode(drive, max_pio, ds_time);
 
        /*
         * Disable (or set) readahead mode
@@ -754,10 +823,13 @@ static void cmd640_tune_drive(ide_drive_t *drive, byte pio_mode) {
                readahead = known_drive_readahead(id->model);
                if (readahead == -1)
                        readahead = 1;  /* Mmmm.. probably be 0 ?? */
-               set_readahead_mode(readahead, interface_number, drive_number);
-       }   
+               set_readahead_mode(drive, readahead);
+       }
 
-       printk ("Mode and Timing set to PIO%d, Readahead is %s\n", 
-               max_pio, readahead ? "enabled" : "disabled");
+       printk ("Drive Timing: PIO Mode %d (%dns) %s/IORDY%s, Read-ahead: %s\n",
+               max_pio,
+               ds_time,
+               iordy ? "w" : "wo",
+               overridden ? " (overriding vendor mode)" : "",
+               readahead ? "enabled" : "disabled");
 }
-
index 489a99c5593544f31db9fdc25ffffbe2486152fb..cdad73bd23da7861dd4e72d713a74a54bdc5ac2f 100644 (file)
@@ -41,8 +41,8 @@
  *
  * DTC2278S has only a single IDE interface.
  * DTC2278D has two IDE interfaces and is otherwise identical to the S version.
- * DTC2278E has onboard BIOS, while the others do not.
- * DTC2278EB: "works like a charm" -- Kent Bradford <kent@theory.caltech.edu>
+ * DTC2278E also has serial ports and a printer port
+ * DTC2278EB: has onboard BIOS, and "works like a charm" -- Kent Bradford <kent@theory.caltech.edu>
  *
  * There may be a fourth controller type. The S and D versions use the
  * Winbond chip, and I think the E version does also.
index d663335f16609498994c6e35ea0a49954171064e..467cabdcdb53c1dd9cda73a6d57835fae1f81561 100644 (file)
@@ -551,6 +551,88 @@ static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sec
 
 #endif /* CONFIG_SUN_PARTITION */
 
+#ifdef CONFIG_AMIGA_PARTITION
+#include <asm/byteorder.h>
+#include <linux/affs_hardblocks.h>
+
+static __inline__ __u32
+checksum_block(__u32 *m, int size)
+{
+       __u32 sum = 0;
+
+       while (size--)
+               sum += htonl(*m++);
+       return sum;
+}
+
+static int
+amiga_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
+{
+       struct buffer_head      *bh;
+       struct RigidDiskBlock   *rdb;
+       struct PartitionBlock   *pb;
+       int                      start_sect;
+       int                      nr_sects;
+       int                      blk;
+       int                      part, res;
+
+       set_blocksize(dev,512);
+       res = 0;
+
+       for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
+               if(!(bh = bread(dev,blk,512))) {
+                       printk("Dev %d: unable to read RDB block %d\n",dev,blk);
+                       goto rdb_done;
+               }
+               if (*(__u32 *)bh->b_data == htonl(IDNAME_RIGIDDISK)) {
+                       rdb = (struct RigidDiskBlock *)bh->b_data;
+                       if (checksum_block((__u32 *)bh->b_data,htonl(rdb->rdb_SummedLongs) & 0x7F)) {
+                               printk("Dev %d: RDB in block %d has bad checksum\n",dev,blk);
+                               brelse(bh);
+                               continue;
+                       }
+                       printk(" RDSK");
+                       blk = htonl(rdb->rdb_PartitionList);
+                       brelse(bh);
+                       for (part = 1; blk > 0 && part <= 16; part++) {
+                               if (!(bh = bread(dev,blk,512))) {
+                                       printk("Dev %d: unable to read partition block %d\n",
+                                                      dev,blk);
+                                       goto rdb_done;
+                               }
+                               pb  = (struct PartitionBlock *)bh->b_data;
+                               blk = htonl(pb->pb_Next);
+                               if (pb->pb_ID == htonl(IDNAME_PARTITION) && checksum_block(
+                                   (__u32 *)pb,htonl(pb->pb_SummedLongs) & 0x7F) == 0 ) {
+                                       
+                                       /* Tell Kernel about it */
+
+                                       if (!(nr_sects = (htonl(pb->pb_Environment[10]) + 1 -
+                                                         htonl(pb->pb_Environment[9])) *
+                                                        htonl(pb->pb_Environment[3]) *
+                                                        htonl(pb->pb_Environment[5]))) {
+                                               continue;
+                                       }
+                                       start_sect = htonl(pb->pb_Environment[9]) *
+                                                    htonl(pb->pb_Environment[3]) *
+                                                    htonl(pb->pb_Environment[5]);
+                                       add_partition(hd,current_minor,start_sect,nr_sects);
+                                       current_minor++;
+                                       res = 1;
+                               }
+                               brelse(bh);
+                       }
+                       printk("\n");
+                       break;
+               }
+       }
+
+rdb_done:
+       set_blocksize(dev,BLOCK_SIZE);
+       return res;
+}
+#endif /* CONFIG_AMIGA_PARTITION */
+
 static void check_partition(struct gendisk *hd, kdev_t dev)
 {
        static int first_time = 1;
@@ -583,6 +665,10 @@ static void check_partition(struct gendisk *hd, kdev_t dev)
 #ifdef CONFIG_SUN_PARTITION
        if(sun_partition(hd, dev, first_sector))
                return;
+#endif
+#ifdef CONFIG_AMIGA_PARTITION
+       if(amiga_partition(hd, dev, first_sector))
+               return;
 #endif
        printk(" unknown partition table\n");
 }
index ac34960fece1dab6a989c2513ca4a90c088a1d35..e75fd2ebc63390a80b44ed64ebc7b94b8f9a1a9f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide.c  Version 5.43  May 14, 1996
+ *  linux/drivers/block/ide.c  Version 5.45  Jul 22, 1996
  *
  *  Copyright (C) 1994-1996  Linus Torvalds & authors (see below)
  */
  * Version 5.42                simplify irq-masking after probe
  *                     fix NULL pointer deref in save_match()
  * Version 5.43                Ugh.. unexpected_intr is back: try to exterminate it
+ * Version 5.44                Fix for "irq probe failed" on cmd640
+ *                     change path on message regarding MAKEDEV.ide
+ *                     add a throttle to the unexpected_intr() messages
+ * Version 5.45                fix ugly parameter parsing bugs (thanks Derek)
+ *                     include Gadi's magic fix for cmd640 unexpected_intr
  *
  *  Some additional driver compile-time options are in ide.h
  *
 #endif /* CONFIG_BLK_DEV_PROMISE */
 
 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};
 
@@ -580,6 +584,8 @@ static void init_gendisk (ide_hwif_t *hwif)
        gd->part  = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
        bs        = kmalloc (minors*sizeof(int), GFP_KERNEL);
 
+       memset(gd->part, 0, minors * sizeof(struct hd_struct));
+
        /* cdroms and msdos f/s are examples of non-1024 blocksizes */
        blksize_size[hwif->major] = bs;
        for (unit = 0; unit < minors; ++unit)
@@ -1619,6 +1625,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
        byte stat;
        unsigned int unit;
        ide_hwif_t *hwif = hwgroup->hwif;
+       static unsigned long last_time = 0;
 
        /*
         * handle the unexpected interrupt
@@ -1630,8 +1637,12 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
                                if (!drive->present)
                                        continue;
                                SELECT_DRIVE(hwif,drive);
-                               if (!OK_STAT(stat=GET_STAT(), drive->ready_stat, BAD_STAT))
-                                       (void) ide_dump_status(drive, "unexpected_intr", stat);
+                               if (!OK_STAT(stat=GET_STAT(), drive->ready_stat, BAD_STAT)) {
+                                       if ((last_time + (HZ/2)) < jiffies && !drive->ignore_unexp) {
+                                               last_time = jiffies;
+                                               (void) ide_dump_status(drive, "unexpected_intr", stat);
+                                       }
+                               }
                                if ((stat & DRQ_STAT))
                                        try_to_flush_leftover_data(drive);
                        }
@@ -1645,8 +1656,8 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
  */
 void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
-       ide_hwgroup_t  *hwgroup = dev_id;
-       ide_handler_t  *handler;
+       ide_hwgroup_t *hwgroup = dev_id;
+       ide_handler_t *handler;
 
        if (irq == hwgroup->hwif->irq && (handler = hwgroup->handler) != NULL) {
                ide_drive_t *drive = hwgroup->drive;
@@ -1658,7 +1669,7 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
                cli();  /* this is necessary, as next rq may be different irq */
                if (hwgroup->handler == NULL) {
                        SET_RECOVERY_TIMER(HWIF(drive));
-                       ide_do_request(hwgroup);
+                       ide_do_request(hwgroup);
                }
        } else {
                unexpected_intr(irq, hwgroup);
@@ -1899,8 +1910,13 @@ static int revalidate_disk(kdev_t i_rdev)
        };
 
        drive->part[0].nr_sects = current_capacity(drive);
-       if (drive->media == ide_disk)
-               resetup_one_dev(HWIF(drive)->gd, drive->select.b.unit);
+       if (drive->media != ide_disk)
+               drive->part[0].start_sect = -1;
+       resetup_one_dev(HWIF(drive)->gd, drive->select.b.unit);
+#ifdef CONFIG_BLK_DEV_IDECD
+       if (drive->media == ide_cdrom)
+               ide_cdrom_setup(drive);
+#endif /* CONFIG_BLK_DEV_IDECD */
 
        drive->busy = 0;
        wake_up(&drive->wqueue);
@@ -2194,7 +2210,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
                if ((id->model[0] == 'N' && id->model[1] == 'E') /* NEC */
                 || (id->model[0] == 'F' && id->model[1] == 'X') /* Mitsumi */
                 || (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */
-                       bswap = 0;      /* Vertos drives may still be weird */
+                       bswap ^= 1;     /* Vertos drives may still be weird */
        }
        ide_fixstring (id->model,     sizeof(id->model),     bswap);
        ide_fixstring (id->fw_rev,    sizeof(id->fw_rev),    bswap);
@@ -2367,10 +2383,15 @@ static void delay_10ms (void)
  */
 static int try_to_identify (ide_drive_t *drive, byte cmd)
 {
-       int hd_status, rc;
+       int irqs, rc;
        unsigned long timeout;
-       int irqs = 0;
+#ifdef CONFIG_BLK_DEV_CMD640
+       int retry = 0;
+       int hd_status;
 
+try_again:
+#endif /* CONFIG_BLK_DEV_CMD640 */
+       irqs = 0;
        if (!HWIF(drive)->irq) {                /* already got an IRQ? */
                probe_irq_off(probe_irq_on());  /* clear dangling irqs */
                irqs = probe_irq_on();          /* start monitoring irqs */
@@ -2428,16 +2449,28 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
                        irqs = probe_irq_on();
                        OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* mask device irq */
                        udelay(5);
-                       (void) GET_STAT();      /* clear drive IRQ */
                        (void) probe_irq_off(irqs);
+                       (void) probe_irq_off(probe_irq_on()); /* clear self-inflicted irq */
+                       (void) GET_STAT();      /* clear drive IRQ */
+
                } else {        /* Mmmm.. multiple IRQs.. don't know which was ours */
                        printk("%s: IRQ probe failed (%d)\n", drive->name, irqs);
 #ifdef CONFIG_BLK_DEV_CMD640
                        if (HWIF(drive)->chipset == ide_cmd640) {
                                extern byte (*get_cmd640_reg)(int);
+                               byte reg9  = get_cmd640_reg(0x09);
                                printk("%s: Hmmm.. probably a driver problem.\n", drive->name);
-                               printk("%s: cmd640 reg 09h == 0x%02x\n", drive->name, get_cmd640_reg(9));
+                               printk("%s: cmd640 reg 09h == 0x%02x\n", drive->name, reg9);
                                printk("%s: cmd640 reg 51h == 0x%02x\n", drive->name, get_cmd640_reg(0x51));
+                               if (reg9 == 0x0a) {
+                                       printk("%s: perhaps PCI INTA has not been set to IRQ15?\n", drive->name);
+                                       if (retry++ == 0) {
+                                               extern void (*put_cmd640_reg)(int, int);
+                                               printk("%s: switching secondary interface to legacy mode\n", drive->name);
+                                               put_cmd640_reg(0x09,0x00);
+                                               goto try_again;
+                                       }
+                               }
                        }
 #endif /* CONFIG_BLK_DEV_CMD640 */
                }
@@ -2832,7 +2865,7 @@ void ide_setup (char *s)
                /*
                 * Cryptic check to ensure chipset not already set for hwif:
                 */
-               if (i != -1 && i != -2) {
+               if (i >= 0 || i <= -5) {
                        if (hwif->chipset != ide_unknown)
                                goto bad_option;
                        if (i < 0 && ide_hwifs[1].chipset != ide_unknown)
@@ -2841,7 +2874,7 @@ void ide_setup (char *s)
                /*
                 * Interface keywords work only for ide0:
                 */
-               if (i <= -6 && hw != 0)
+               if (i <= -5 && hw != 0)
                        goto bad_hwif;
 
                switch (i) {
@@ -3058,7 +3091,9 @@ static void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
 static int init_irq (ide_hwif_t *hwif)
 {
        unsigned long flags;
+#if MAX_HWIFS > 1
        unsigned int index;
+#endif /* MAX_HWIFS > 1 */
        ide_hwgroup_t *hwgroup;
        ide_hwif_t *match = NULL;
 
index 4c083959abcff2ce6570005e810efbb18aaf49f8..36832d58170061ab7e05cce53a69881d4fbe92e5 100644 (file)
@@ -135,7 +135,11 @@ typedef unsigned char      byte;   /* used everywhere */
  * Timeouts for various operations:
  */
 #define WAIT_DRQ       (5*HZ/100)      /* 50msec - spec allows up to 20ms */
+#ifdef CONFIG_APM
+#define WAIT_READY     (5*HZ)          /* 5sec - some laptops are very slow */
+#else
 #define WAIT_READY     (3*HZ/100)      /* 30msec - should be instantaneous */
+#endif /* CONFIG_APM */
 #define WAIT_PIDENTIFY (1*HZ)  /* 1sec   - should be less than 3ms (?) */
 #define WAIT_WORSTCASE (30*HZ) /* 30sec  - worst case when spinning up */
 #define WAIT_CMD       (10*HZ) /* 10sec  - maximum wait for an IRQ to happen */
@@ -292,6 +296,18 @@ typedef union {
                } b;
        } special_t;
 
+#ifdef __BIG_ENDIAN_BITFIELD
+typedef union {
+       unsigned all                    : 8;    /* all of the bits together */
+       struct {
+               unsigned bit7           : 1;    /* always 1 */
+               unsigned lba            : 1;    /* using LBA instead of CHS */
+               unsigned bit5           : 1;    /* always 1 */
+               unsigned unit           : 1;    /* drive select number, 0 or 1 */
+               unsigned head           : 4;    /* always zeros here */
+       } b;
+       } select_t;
+#else /* __BIG_ENDIAN_BITFIELD */
 typedef union {
        unsigned all                    : 8;    /* all of the bits together */
        struct {
@@ -302,6 +318,7 @@ typedef union {
                unsigned bit7           : 1;    /* always 1 */
        } b;
        } select_t;
+#endif /* __BIG_ENDIAN_BITFIELD */
 
 typedef struct ide_drive_s {
        special_t       special;        /* special action flags */
@@ -315,6 +332,7 @@ typedef struct ide_drive_s {
        unsigned unmask         : 1;    /* flag: okay to unmask other irqs */
        unsigned nobios         : 1;    /* flag: do not probe bios for drive */
        unsigned autotune       : 2;    /* 1=autotune, 2=noautotune, 0=default */
+       unsigned ignore_unexp   : 1;    /* flag: ignore unexpected_intr's */
 #if FAKE_FDISK_FOR_EZDRIVE
        unsigned remap_0_to_1   : 1;    /* flag: partitioned with ezdrive */
 #endif /* FAKE_FDISK_FOR_EZDRIVE */
@@ -324,7 +342,7 @@ typedef struct ide_drive_s {
        byte            ready_stat;     /* min status value for drive ready */
        byte            mult_count;     /* current multiple sector setting */
        byte            mult_req;       /* requested multiple sector setting */
-       byte            pio_req;        /* requested multiple sector setting */
+       byte            pio_req;        /* requested drive pio setting */
        byte            io_32bit;       /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
        byte            bad_wstat;      /* used for ignoring WRERR_STAT */
        byte            sect0;          /* offset of first sector for DM6:DDO */
index 8df33f2ec6b730c652ed7d06144fff0dd5866c70..a9cd04a24cad84628d9c0048af19d2daf4071ed2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/triton.c       Version 1.10  Apr 3, 1996
+ *  linux/drivers/block/triton.c       Version 1.12  Jul 24, 1996
  *
  *  Copyright (c) 1995-1996  Mark Lord
  *  May be copied or modified under the terms of the GNU General Public License
@@ -322,7 +322,7 @@ static int triton_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 
 /*
  * print_triton_drive_flags() displays the currently programmed options
- * in the 430FX (Triton) chipset for a given drive.
+ * in the 82371 (Triton) for a given drive.
  *
  *     If fastDMA  is "no", then slow ISA timings are used for DMA data xfers.
  *     If fastPIO  is "no", then slow ISA timings are used for PIO data xfers.
@@ -382,7 +382,7 @@ void ide_init_triton (byte bus, byte fn)
        unsigned short pcicmd;
        unsigned int bmiba, timings;
 
-       printk("ide: 430FX (Triton) on PCI bus %d function %d\n", bus, fn);
+       printk("ide: 82371 PIIX (Triton) on PCI bus %d function %d\n", bus, fn);
        /*
         * See if IDE and BM-DMA features are enabled:
         */
@@ -439,14 +439,14 @@ void ide_init_triton (byte bus, byte fn)
                unsigned short time;
                if (hwif->io_base == 0x1f0) {
                        time = timings & 0xffff;
-                       if ((timings & 0x8000) == 0)    /* interface enabled? */
+                       if ((time & 0x8000) == 0)       /* interface enabled? */
                                continue;
                        hwif->chipset = ide_triton;
                        if (dma_enabled)
                                init_triton_dma(hwif, bmiba);
                } else if (hwif->io_base == 0x170) {
                        time = timings >> 16;
-                       if ((timings & 0x8000) == 0)    /* interface enabled? */
+                       if ((time & 0x8000) == 0)       /* interface enabled? */
                                continue;
                        hwif->chipset = ide_triton;
                        if (dma_enabled)
index 8f1f3a31a30acfa61eeb5b09397c992daa588aee..775a5b29056f5218fd4862c437f3372a8300cfdb 100644 (file)
@@ -39,7 +39,7 @@
  *  Daniel v. Mosnenck (he sent me the Technical and Programming Reference)
  *  Gerd Knorr (he lent me his PhotoCD)
  *  Nils Faerber and Roger E. Wolff (extensively tested the LU portion)
- *  Andreas Kies (testing the mysterious hang up's)
+ *  Andreas Kies (testing the mysterious hang-ups)
  *  Heiko Eissfeldt (VERIFY_READ/WRITE)
  *  Marcin Dalecki (improved performance, shortened code)
  *  ... somebody forgotten?
index 10a981186f44a43c8c25177dca7a18bda8511532..0737c500a9e2b163f80b6063c7b7b4675dc891f5 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #define KEYBOARD_IRQ 1
+#define DISABLE_KBD_DURING_INTERRUPTS 0
 
 #include <linux/sched.h>
 #include <linux/interrupt.h>
@@ -69,14 +70,6 @@ static int initialize_kbd(void);
 #define KBD_DEFLOCK 0
 #endif
 
-/*
- * The default IO slowdown is doing 'inb()'s from 0x61, which should be
- * safe. But as that is the keyboard controller chip address, we do our
- * slowdowns here by doing short jumps: the keyboard controller should
- * be able to keep up
- */
-#define REALLY_SLOW_IO
-#define SLOW_IO_BY_JUMPING
 #include <asm/io.h>
 #include <asm/system.h>
 
@@ -337,48 +330,31 @@ int getkeycode(unsigned int scancode)
            e0_keys[scancode - 128];
 }
 
-static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+#if DISABLE_KBD_DURING_INTERRUPTS
+#define disable_keyboard()     do { send_cmd(0xAD); kb_wait(); } while (0)
+#define enable_keyboard()      send_cmd(0xAE)
+#else
+#define disable_keyboard()     /* nothing */
+#define enable_keyboard()      /* nothing */
+#endif
+
+static void handle_scancode(unsigned char scancode)
 {
-       unsigned char scancode, keycode;
+       unsigned char keycode;
        static unsigned int prev_scancode = 0;   /* remember E0, E1 */
        char up_flag;                            /* 0 or 0200 */
        char raw_mode;
-       int status;
 
-       pt_regs = regs;
-       send_cmd(0xAD);         /* disable keyboard */
-       kb_wait();
-       status = inb_p(0x64);
-       if ((status & kbd_read_mask) != 0x01) {
-         /*
-          * On some platforms (Alpha XL for one), the init code may leave
-          *  an interrupt hanging, yet with status indicating no data.
-          * After making sure that there's no data indicated and its not a
-          *  mouse interrupt, we will read the data register to clear it.
-          * If we don't do this, the data reg stays full and will not
-          *  allow new data or interrupt from the keyboard. Sigh...
-          */
-         if (!(status & 0x21)) { /* neither ODS nor OBF */
-           scancode = inb(0x60); /* read data anyway */
-#if 0
-           printk(KERN_DEBUG "keyboard: status 0x%x  mask 0x%x  data 0x%x\n",
-                  status, kbd_read_mask, scancode);
-#endif
-         }
-         goto end_kbd_intr;
-       }
-       scancode = inb(0x60);
-       mark_bh(KEYBOARD_BH);
        if (reply_expected) {
          /* 0xfa, 0xfe only mean "acknowledge", "resend" for most keyboards */
          /* but they are the key-up scancodes for PF6, PF10 on a FOCUS 9000 */
                reply_expected = 0;
                if (scancode == 0xfa) {
                        acknowledge = 1;
-                       goto end_kbd_intr;
+                       return;
                } else if (scancode == 0xfe) {
                        resend = 1;
-                       goto end_kbd_intr;
+                       return;
                }
                /* strange ... */
                reply_expected = 1;
@@ -392,7 +368,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                printk(KERN_INFO "keyboard buffer overflow\n");
 #endif
                prev_scancode = 0;
-               goto end_kbd_intr;
+               return;
        }
        do_poke_blanked_console = 1;
        mark_bh(CONSOLE_BH);
@@ -417,12 +393,12 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #endif
 #endif
                prev_scancode = 0;
-               goto end_kbd_intr;
+               return;
        }
 
        if (scancode == 0xe0 || scancode == 0xe1) {
                prev_scancode = scancode;
-               goto end_kbd_intr;
+               return;
        }
 
        /*
@@ -439,7 +415,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
          if (prev_scancode != 0xe0) {
              if (prev_scancode == 0xe1 && scancode == 0x1d) {
                  prev_scancode = 0x100;
-                 goto end_kbd_intr;
+                 return;
              } else if (prev_scancode == 0x100 && scancode == 0x45) {
                  keycode = E1_PAUSE;
                  prev_scancode = 0;
@@ -449,7 +425,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                    printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
 #endif
                  prev_scancode = 0;
-                 goto end_kbd_intr;
+                 return;
              }
          } else {
              prev_scancode = 0;
@@ -467,7 +443,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
               *  So, we should also ignore the latter. - aeb@cwi.nl
               */
              if (scancode == 0x2a || scancode == 0x36)
-               goto end_kbd_intr;
+               return;
 
              if (e0_keys[scancode])
                keycode = e0_keys[scancode];
@@ -477,7 +453,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                    printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
                           scancode);
 #endif
-                 goto end_kbd_intr;
+                 return;
              }
          }
        } else if (scancode >= SC_LIM) {
@@ -500,7 +476,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                         " - ignored\n", scancode);
 #endif
              }
-             goto end_kbd_intr;
+             return;
          }
        } else
          keycode = scancode;
@@ -526,12 +502,12 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                rep = set_bit(keycode, key_down);
 
        if (raw_mode)
-               goto end_kbd_intr;
+               return;
 
        if (kbd->kbdmode == VC_MEDIUMRAW) {
                /* soon keycodes will require more than one byte */
                put_queue(keycode + up_flag);
-               goto end_kbd_intr;
+               return;
        }
 
        /*
@@ -592,9 +568,32 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #endif
                }
        }
+}
 
-end_kbd_intr:
-       send_cmd(0xAE);         /* enable keyboard */
+static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       unsigned char status;
+
+       pt_regs = regs;
+       disable_keyboard();
+
+       status = inb_p(0x64);
+       do {
+               unsigned char scancode;
+
+               /* mouse data? */
+               if (status & kbd_read_mask & 0x20)
+                       break;
+
+               scancode = inb(0x60);
+               if (status & 0x01)
+                       handle_scancode(scancode);
+
+               status = inb(0x64);
+       } while (status & 0x01);
+
+       mark_bh(KEYBOARD_BH);
+       enable_keyboard();
 }
 
 static void put_queue(int ch)
index 6331bdc3e0c6a8b8f76ebe4df3f44121c600a586..d68219f880a6bebf962a7f3271fe7474caf110df 100644 (file)
@@ -176,6 +176,8 @@ static int read_zero(struct inode * node, struct file * file, char * buf, int co
        for (left = count; left > 0; left--) {
                put_user(0,buf);
                buf++;
+               if (need_resched)
+                       schedule();
        }
        return count;
 }
index 99d074bd996fe190014bc66d7aedfb2b3982139b..363b593998606ef9e9a2f9ed76dcea275c7f2292 100644 (file)
  * Rearranged SIGIO support to use code from tty_io.  9Sept95 ctm@ardi.com
  *
  * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
- *
- * Fixed keyboard lockups at open time (intervening kbd interrupts), handle
- * RESEND replies, better error checking
- * 3-Jul-96 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
  */
 
 /* Uncomment the following line if your mouse needs initialization. */
 #define AUX_STATUS     0x64            /* Aux device status reg */
 
 /* aux controller status bits */
-#define AUX_KOBUF_FULL 0x01            /* output buffer (from controller) full */
 #define AUX_OBUF_FULL  0x21            /* output buffer (from device) full */
 #define AUX_IBUF_FULL  0x02            /* input buffer (to device) full */
-#define AUX_TIMEOUT    0x40            /* controller reports timeout */
 
 /* aux controller commands */
 #define AUX_CMD_WRITE  0x60            /* value to write to controller */
 #define AUX_DISABLE_DEV        0xf5            /* disable aux device */
 #define AUX_RESET      0xff            /* reset aux device */
 
-/* kbd controller commands */
-#define KBD_DISABLE    0xad
-#define KBD_ENABLE     0xae
-
-/* replies */
-#define AUX_ACK                0xfa
-#define AUX_RESEND     0xfe
-
 #define MAX_RETRIES    60              /* some aux operations take long time*/
 #if defined(__alpha__) && !defined(CONFIG_PCI)
 # define AUX_IRQ       9               /* Jensen is odd indeed */
@@ -135,6 +121,7 @@ static int aux_ready = 0;
 static int aux_count = 0;
 static int aux_present = 0;
 static int poll_aux_status(void);
+static int poll_aux_status_nosleep(void);
 static int fasync_aux(struct inode *inode, struct file *filp, int on);
 
 #ifdef CONFIG_82C710_MOUSE
@@ -149,70 +136,49 @@ static int probe_qp(void);
 
 
 /*
- * Write a byte to the kbd controller and wait for it being processed
+ * Write to aux device
  */
 
-static int aux_write_byte(int val,int port)
+static void aux_write_dev(int val)
 {
-       outb_p(val, port);
-       return poll_aux_status();
+       poll_aux_status();
+       outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);    /* write magic cookie */
+       poll_aux_status();
+       outb_p(val,AUX_OUTPUT_PORT);            /* write data */
 }
 
 /*
- * Write to device, handle returned resend requests and wait for ack
+ * Write to device & handle returned ack
  */
+#if defined INITIALIZE_DEVICE
 static int aux_write_ack(int val)
 {
-       int rv, retries = 0, stat;
-
-  repeat:
-       if (poll_aux_status() < 0)
-               return -1;
-       outb_p(AUX_MAGIC_WRITE, AUX_COMMAND);
-       if (poll_aux_status() < 0)
-               return -1;
-       outb_p(val, AUX_OUTPUT_PORT);
-
-       if ((rv = poll_aux_status()) < 0)
-               /* timeout */
-               return -1;
-       else if (rv == AUX_RESEND)
-           /* controller needs last byte again... */
-               goto repeat;
-       else if (rv == AUX_ACK)
-           /* already got ACK */
-               return 0;
-       else {
-               /* wait for ACK from controller */
-               while (retries < MAX_RETRIES) {
-                       stat = inb_p(AUX_STATUS);
-                       if ((stat & AUX_OBUF_FULL) == AUX_OBUF_FULL &&
-                               inb_p(AUX_INPUT_PORT) == AUX_ACK)
-                               return 0;
-                       current->state = TASK_INTERRUPTIBLE;
-                       current->timeout = jiffies + (5*HZ + 99) / 100;
-                       schedule();
-                       retries++;
-               }
-               return -1;
+       int retries = 0;
+
+       poll_aux_status_nosleep();
+       outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
+       poll_aux_status_nosleep();
+       outb_p(val,AUX_OUTPUT_PORT);
+       poll_aux_status_nosleep();
+
+       if ((inb(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
+       {
+               return (inb(AUX_INPUT_PORT));
        }
+       return 0;
 }
+#endif /* INITIALIZE_DEVICE */
 
 /*
  * Write aux device command
  */
 
-static int aux_write_cmd(int val)
+static void aux_write_cmd(int val)
 {
-       if (poll_aux_status() < 0)
-               return -1;
-       outb_p(AUX_CMD_WRITE, AUX_COMMAND);
-       if (poll_aux_status() < 0)
-               return -1;
-       outb_p(val, AUX_OUTPUT_PORT);
-       if (poll_aux_status() < 0)
-               return -1;
-       return 0;
+       poll_aux_status();
+       outb_p(AUX_CMD_WRITE,AUX_COMMAND);
+       poll_aux_status();
+       outb_p(val,AUX_OUTPUT_PORT);
 }
 
 
@@ -292,19 +258,10 @@ static void release_aux(struct inode * inode, struct file * file)
        fasync_aux(inode, file, 0);
        if (--aux_count)
                return;
-       /* disable keyboard to avoid clashes with multi-byte command sequences */
+       aux_write_cmd(AUX_INTS_OFF);            /* disable controller ints */
+       poll_aux_status();
+       outb_p(AUX_DISABLE,AUX_COMMAND);        /* Disable Aux device */
        poll_aux_status();
-       if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
-               printk(KERN_ERR "psaux: controller timeout\n");
-       /* disable controller ints */
-       if (aux_write_cmd(AUX_INTS_OFF) < 0)
-               printk(KERN_ERR "psaux: controller timeout\n");
-       /* Disable Aux device */
-       if (aux_write_byte(AUX_DISABLE, AUX_COMMAND) < 0)
-               printk(KERN_ERR "psaux: controller timeout\n");
-       /* re-enable keyboard */
-       if (aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
-               printk(KERN_ERR "psaux: controller timeout\n");
        free_irq(AUX_IRQ, NULL);
        MOD_DEC_USE_COUNT;
 }
@@ -349,7 +306,7 @@ static int open_aux(struct inode * inode, struct file * file)
                return -ENODEV;
        if (aux_count++)
                return 0;
-       if (poll_aux_status() < 0) {
+       if (!poll_aux_status()) {
                aux_count--;
                return -EBUSY;
        }
@@ -360,27 +317,12 @@ static int open_aux(struct inode * inode, struct file * file)
        }
        MOD_INC_USE_COUNT;
        poll_aux_status();
-       /* disable keyboard to avoid clashes with multi-byte command sequences */
-       if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
-               goto open_error;
-       /* Enable Aux in kbd controller */
-       if (aux_write_byte(AUX_ENABLE, AUX_COMMAND) < 0)
-               goto open_error;
-       /* enable aux device */
-       if (aux_write_ack(AUX_ENABLE_DEV) < 0)
-               goto open_error;
-       /* enable controller ints */
-       if (aux_write_cmd(AUX_INTS_ON) < 0)
-               goto open_error;
-       /* re-enable keyboard */
-       if (aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
-               goto open_error;
-
+       outb_p(AUX_ENABLE,AUX_COMMAND);         /* Enable Aux */
+       aux_write_dev(AUX_ENABLE_DEV);          /* enable aux device */
+       aux_write_cmd(AUX_INTS_ON);             /* enable controller ints */
+       poll_aux_status();
        aux_ready = 0;
        return 0;
-  open_error:
-       printk( KERN_ERR "psaux: controller timeout\n" );
-       return -EIO;
 }
 
 #ifdef CONFIG_82C710_MOUSE
@@ -436,31 +378,17 @@ static int open_qp(struct inode * inode, struct file * file)
 static int write_aux(struct inode * inode, struct file * file, const char * buffer, int count)
 {
        int i = count;
-       int rv = 0;
-       
-       /* temporary disable keyboard to avoid clashes with multi-byte command
-        * sequence */
-       if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
-               return -EIO;
 
        while (i--) {
-               if (poll_aux_status() < 0) {
-                       rv = -EIO;
-                       break;
-               }
+               if (!poll_aux_status())
+                       return -EIO;
                outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
-               if (poll_aux_status() < 0) {
-                       rv = -EIO;
-                       break;
-               }
+               if (!poll_aux_status())
+                       return -EIO;
                outb_p(get_user(buffer++),AUX_OUTPUT_PORT);
        }
-       /* reenable keyboard */
-       if (poll_aux_status() < 0 || aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
-               rv = -EIO;
-
        inode->i_mtime = CURRENT_TIME;
-       return rv ? rv : count;
+       return count;
 }
 
 
@@ -591,11 +519,13 @@ int psaux_init(void)
                aux_write_ack(AUX_SET_RES);
                aux_write_ack(3);                       /* 8 counts per mm */
                aux_write_ack(AUX_SET_SCALE21);         /* 2:1 scaling */
+               poll_aux_status_nosleep();
 #endif /* INITIALIZE_DEVICE */
-               /* Disable Aux device and its interrupts on the controller */
-               if (aux_write_byte(AUX_DISABLE, AUX_COMMAND) < 0 ||
-                   aux_write_cmd(AUX_INTS_OFF) < 0)
-                   printk(KERN_ERR "psaux: controller timeout\n");
+               outb_p(AUX_DISABLE,AUX_COMMAND);   /* Disable Aux device */
+               poll_aux_status_nosleep();
+               outb_p(AUX_CMD_WRITE,AUX_COMMAND);
+               poll_aux_status_nosleep();             /* Disable interrupts */
+               outb_p(AUX_INTS_OFF, AUX_OUTPUT_PORT); /*  on the controller */
        }
        return 0;
 }
@@ -603,7 +533,7 @@ int psaux_init(void)
 #ifdef MODULE
 int init_module(void)
 {
-       return psaux_init();
+       return psaux_init(); /*?? Bjorn */
 }
 
 void cleanup_module(void)
@@ -615,18 +545,28 @@ void cleanup_module(void)
 static int poll_aux_status(void)
 {
        int retries=0;
-       int reply=0;
 
-       while ((inb(AUX_STATUS) & (AUX_KOBUF_FULL|AUX_IBUF_FULL)) &&
-              retries < MAX_RETRIES) {
+       while ((inb(AUX_STATUS)&0x03) && retries < MAX_RETRIES) {
                if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
-                       reply = inb_p(AUX_INPUT_PORT);
+                       inb_p(AUX_INPUT_PORT);
                current->state = TASK_INTERRUPTIBLE;
                current->timeout = jiffies + (5*HZ + 99) / 100;
                schedule();
                retries++;
        }
-       return (retries==MAX_RETRIES) ? -1 : reply;
+       return !(retries==MAX_RETRIES);
+}
+
+static int poll_aux_status_nosleep(void)
+{
+       int retries = 0;
+
+       while ((inb(AUX_STATUS)&0x03) && retries < 1000000) {
+               if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
+                       inb_p(AUX_INPUT_PORT);
+               retries++;
+       }
+       return !(retries == 1000000);
 }
 
 #ifdef CONFIG_82C710_MOUSE
index 6179e27019fb1b00085aec851192d8876c9bebe7..f9c828e94ce871f1e62ef768dd94fc46b71ffabd 100644 (file)
@@ -755,9 +755,48 @@ static int tty_read(struct inode * inode, struct file * file, char * buf, int co
        return i;
 }
 
+/*
+ * Split writes up in sane blocksizes to avoid
+ * denial-of-service type attacks
+ */
+static inline int do_tty_write(
+       int (*write)(struct tty_struct *, struct file *, const unsigned char *, unsigned int),
+       struct inode *inode,
+       struct tty_struct *tty,
+       struct file *file,
+       const unsigned char *buf,
+       unsigned int count)
+{
+       int ret = 0, written = 0;
+
+       for (;;) {
+               unsigned int size = PAGE_SIZE*2;
+               if (size > count)
+                       size = count;
+               ret = write(tty, file, buf, size);
+               if (ret <= 0)
+                       break;
+               count -= ret;
+               written += ret;
+               if (!count)
+                       break;
+               ret = -ERESTARTSYS;
+               if (current->signal & ~current->blocked)
+                       break;
+               if (need_resched)
+                       schedule();
+       }
+       if (written) {
+               inode->i_mtime = CURRENT_TIME;
+               ret = written;
+       }
+       return ret;
+}
+
+
 static int tty_write(struct inode * inode, struct file * file, const char * buf, int count)
 {
-       int i, is_console;
+       int is_console;
        struct tty_struct * tty;
 
        is_console = (inode->i_rdev == CONSOLE_DEV);
@@ -781,14 +820,12 @@ static int tty_write(struct inode * inode, struct file * file, const char * buf,
                }
        }
 #endif
-       if (tty->ldisc.write)
-               /* XXX casts are for what kernel-wide prototypes should be. */
-               i = (tty->ldisc.write)(tty,file,(const unsigned char *)buf,(unsigned int)count);
-       else
-               i = -EIO;
-       if (i > 0)
-               inode->i_mtime = CURRENT_TIME;
-       return i;
+       if (!tty->ldisc.write)
+               return -EIO;
+       return do_tty_write(tty->ldisc.write,
+               inode, tty, file,
+               (const unsigned char *)buf,
+               (unsigned int)count);
 }
 
 /*
index f758114f4297728186405bfa39138851b4258497..fc285043639c3313199e2d31a6995100b299d837 100644 (file)
@@ -1,3 +1,27 @@
+Sun Jul 21  00:00 1996 Gerard Roudier (groudier@club-internet.fr)
+       * ncr53c8xx.c, README.ncr53c8xx
+       Add the ncr53c8xx_select_queue_depths() function.
+       Set queue_depth to SCSI_NCR_MAX_TAGS (4 by default) for devices that 
+       support tagged command queueing.
+       For other devices, set queue_depth to 1. No need to queue a command 
+       to the driver if this command cannot be sent to the device.
+       Each time the driver hide io requests from the kernel and/or from the 
+       driver, it may break a little (or a lot) optimization algorithms that 
+       try to increase throughput by reordering io requests.
+       It is better to enable the disk write caching to reduce latencies for 
+       write operations, and to trust asynchronous read ahead from the device 
+       and from the kernel that can reduce latencies for read operations, 
+       even when tagged command queuing is not supported or enabled.
+
+Sat Jul 20  20:00 1996 Gerard Roudier (groudier@club-internet.fr)
+       * ncr53c8xx.c
+       Minor changes:
+       - Problem of "CCB address mismatch" that happens with the 3 versions 
+         of the driver. The CCB is correct and Stefan Esser suggests a little 
+         patch that seems to be a bypass.
+         Stefan says he will change that in a future version of the BSD driver.
+       - Set burst transfers to 8 for 815 chips.
+
 Sun Jul 14  15:00 1996 Gerard Roudier (groudier@club-internet.fr)
        * ncr53c8xx.c, Configure.help
        Memory mapped io donnot work under linux/Alpha for the driver.
index 5e3034b63f65abecd0633e290e8d83d50d3df03e..5cd945968da78d1c0939ec16b40ba76457401679 100644 (file)
@@ -40,7 +40,7 @@
 */
 
 /*
-**     23 June 1996, version 1.12
+**     21 July 1996, version 1.12b
 **
 **     Supported SCSI-II features:
 **         Synchronous negotiation
@@ -424,6 +424,10 @@ static struct {
 
 #define ScsiResult(host_code, scsi_code) (((host_code) << 16) + ((scsi_code) & 0x7f))
 
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
+static void ncr53c8xx_select_queue_depths(struct Scsi_Host *host, struct scsi_device *devlist);
+#endif
+
 #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
 static void ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
 #else
@@ -3494,6 +3498,9 @@ printf("ncr_attach: unit=%d chip=%d base=%x, io_port=%x, irq=%d\n", unit, chip,
        instance->io_port       = io_port;
        instance->n_io_port     = 128;
        instance->dma_channel   = 0;
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
+       instance->select_queue_depths = ncr53c8xx_select_queue_depths;
+#endif
 
        /*
        **      Patch script to physical addresses
@@ -4786,7 +4793,7 @@ void ncr_init (ncb_p np, char * msg, u_long code)
        else
 /**    NCR53C815                       **/
        if (ChipDevice == PCI_DEVICE_ID_NCR_53C815) {
-               OUTB(nc_dmode, 0x00);   /* Set 2-transfer burst */
+               OUTB(nc_dmode, 0x80);   /* Set 8-transfer burst */
        }
        else
 /**    NCR53C825                       **/
@@ -5874,7 +5881,7 @@ static void ncr_int_ma (ncb_p np)
        if (cp != np->header.cp) {
            printf ("%s: SCSI phase error fixup: CCB address mismatch (0x%08lx != 0x%08lx)\n", 
                    ncr_name (np), (u_long) cp, (u_long) np->header.cp);
-           return;
+/*         return;*/
        }
 
        /*
@@ -7521,6 +7528,30 @@ static int ncr53c8xx_pci_init(Scsi_Host_Template *tpnt, int unit, int board, int
                       (int) irq, bus, (uchar) device_fn);
 }
 
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
+/*
+**   Linux select queue depths function
+*/
+static void ncr53c8xx_select_queue_depths(struct Scsi_Host *host, struct scsi_device *devlist)
+{
+       struct scsi_device *device;
+
+       for (device = devlist; device; device = device->next) {
+               if (device->host == host) {
+                       if (device->tagged_supported) {
+                               device->queue_depth = SCSI_NCR_MAX_TAGS;
+                       }
+                       else {
+                               device->queue_depth = 1;
+                       }
+#ifdef DEBUG
+printk("ncr53c8xx_select_queue_depth: id=%d, lun=%d, queue_depth=%d\n",
+       device->id, device->lun, device->queue_depth);
+#endif
+               }
+       }
+}
+#endif
 
 /*
 **   Linux entry point of queuecommand() function
index 007ae0cf65e54617ac70b70a9bb149429973ce4a..a0e5d79126036f2725614d29f518ed00f8b22a96 100644 (file)
@@ -196,7 +196,7 @@ int ncr53c8xx_release(struct Scsi_Host *);
 
 #if    LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
 
-#define NCR53C8XX {NULL,NULL,NULL,NULL,"ncr53c8xx (rel 1.12a)", ncr53c8xx_detect,\
+#define NCR53C8XX {NULL,NULL,NULL,NULL,"ncr53c8xx (rel 1.12b)", ncr53c8xx_detect,\
        ncr53c8xx_release, /* info */ NULL, /* command, deprecated */ NULL,             \
        ncr53c8xx_queue_command, ncr53c8xx_abort, ncr53c8xx_reset,      \
         NULL /* slave attach */, scsicam_bios_param, /* can queue */ SCSI_NCR_CAN_QUEUE,\
@@ -207,7 +207,7 @@ int ncr53c8xx_release(struct Scsi_Host *);
 #else
 
 
-#define NCR53C8XX {NULL, NULL, "ncr53c8xx (rel 1.12a)", ncr53c8xx_detect,\
+#define NCR53C8XX {NULL, NULL, "ncr53c8xx (rel 1.12b)", ncr53c8xx_detect,\
        ncr53c8xx_release, /* info */ NULL, /* command, deprecated */ NULL,             \
        ncr53c8xx_queue_command, ncr53c8xx_abort, ncr53c8xx_reset,      \
         NULL /* slave attach */, scsicam_bios_param, /* can queue */ SCSI_NCR_CAN_QUEUE,\
index 24e5633ebe3d613856322eee7c9b512cf9c5933b..884b50194ba44118d2e21b87535211c24b2b575c 100644 (file)
@@ -2875,11 +2875,32 @@ static void resize_dma_pool(void)
     for (SDpnt=scsi_devices; SDpnt; SDpnt = SDpnt->next) {
        host = SDpnt->host;
 
-       if(SDpnt->type != TYPE_TAPE)
+       /*
+        * sd and sr drivers allocate scatterlists.
+        * sr drivers may allocate for each command 1x2048 or 2x1024 extra 
+        * buffers for 2k sector size and 1k fs.
+        * sg driver allocates buffers < 4k.
+        * st driver does not need buffers from the dma pool.
+        * estimate 4k buffer/command for devices of unknown type (should panic).
+        */
+       if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM ||
+           SDpnt->type == TYPE_DISK || SDpnt->type == TYPE_MOD) {
            new_dma_sectors += ((host->sg_tablesize *
                                 sizeof(struct scatterlist) + 511) >> 9) *
                               SDpnt->queue_depth;
-       
+           if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM)
+               new_dma_sectors += (2048 >> 9) * SDpnt->queue_depth;
+       }
+       else if (SDpnt->type == TYPE_SCANNER || SDpnt->type == TYPE_PROCESSOR) {
+           new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth;
+       }
+       else {
+           if (SDpnt->type != TYPE_TAPE) {
+               printk("resize_dma_pool: unknown device type %d\n", SDpnt->type);
+               new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth;
+           }
+        }
+
        if(host->unchecked_isa_dma &&
           scsi_need_isa_bounce_buffers &&
           SDpnt->type != TYPE_TAPE) {
@@ -2888,7 +2909,11 @@ static void resize_dma_pool(void)
            new_need_isa_buffer++;
        }
     }
-    
+
+#ifdef DEBUG_INIT
+    printk("resize_dma_pool: needed dma sectors = %d\n", new_dma_sectors);
+#endif
+
     /* limit DMA memory to 32MB: */
     new_dma_sectors = (new_dma_sectors + 15) & 0xfff0;
     
@@ -2945,6 +2970,12 @@ static void resize_dma_pool(void)
     dma_sectors = new_dma_sectors;
     need_isa_buffer = new_need_isa_buffer;
     restore_flags(flags);
+
+#ifdef DEBUG_INIT
+    printk("resize_dma_pool: dma free sectors   = %d\n", dma_free_sectors);
+    printk("resize_dma_pool: dma sectors        = %d\n", dma_sectors);
+    printk("resize_dma_pool: need isa buffers   = %d\n", need_isa_buffer);
+#endif
 }
 
 #ifdef CONFIG_MODULES          /* a big #ifdef block... */
index 3d16d74aae02f48477a7df0dd3c5ab0bd797c2ac..22f6986062688d4e75481f83423f6f8bd99a4225 100644 (file)
@@ -582,7 +582,7 @@ DMAbuf_getrdbuffer (int dev, char **buf, int *len, int dontblock)
       if (!audio_devs[dev]->go)
        tmout = 0;
       else
-       tmout = 2 * HZ;
+       tmout = 10 * HZ;
 
 
       {
index 654fde9ff89f2f84e8b3aa9f474bd858867b52a5..2b892b932e282daa153fe42e2acc9d98ce1f8d10 100644 (file)
@@ -832,7 +832,9 @@ unload_pss (struct address_info *hw_config)
 void
 unload_pss_mpu (struct address_info *hw_config)
 {
+#if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
   unload_mpu401 (hw_config);
+#endif
 }
 
 void
index 5d7e735ec323486a9bb366ab7102bbc839d0b178..8493a4c5632f91910cf9baedc3f57e8c75af8453 100644 (file)
@@ -44,16 +44,26 @@ affs_put_super(struct super_block *sb)
        lock_super(sb);
        for (i = 0; i < sb->u.affs_sb.s_bm_count; i++)
                affs_brelse(sb->u.affs_sb.s_bitmap[i].bm_bh);
-       ROOT_END_S(sb->u.affs_sb.s_root_bh->b_data,sb)->bm_flag = htonl(1);
-       secs_to_datestamp(CURRENT_TIME,&ROOT_END_S(sb->u.affs_sb.s_root_bh->b_data,sb)->disk_altered);
-       affs_fix_checksum(sb->s_blocksize,sb->u.affs_sb.s_root_bh->b_data,5);
-       mark_buffer_dirty(sb->u.affs_sb.s_root_bh,1);
+       if (!(sb->s_flags & MS_RDONLY)) {
+               ROOT_END_S(sb->u.affs_sb.s_root_bh->b_data,sb)->bm_flag = htonl(1);
+               secs_to_datestamp(CURRENT_TIME,
+                                 &ROOT_END_S(sb->u.affs_sb.s_root_bh->b_data,sb)->disk_altered);
+               affs_fix_checksum(sb->s_blocksize,sb->u.affs_sb.s_root_bh->b_data,5);
+               mark_buffer_dirty(sb->u.affs_sb.s_root_bh,1);
+       }
 
        if (sb->u.affs_sb.s_flags & SF_PREFIX)
                kfree(sb->u.affs_sb.s_prefix);
        kfree(sb->u.affs_sb.s_bitmap);
        affs_brelse(sb->u.affs_sb.s_root_bh);
+
+       /* I'm not happy with this. It would be better to save the previous
+        * value of this devices blksize_size[][] in the super block and
+        * restore it here, but with the affs superblock being quite large
+        * already ...
+        */
        set_blocksize(sb->s_dev,BLOCK_SIZE);
+
        sb->s_dev = 0;
        unlock_super(sb);
        MOD_DEC_USE_COUNT;
@@ -63,13 +73,8 @@ affs_put_super(struct super_block *sb)
 static void
 affs_write_super(struct super_block *sb)
 {
-       int                      i, clean = 2;
+       int      i, clean = 2;
 
-       if ((sb->u.affs_sb.s_flags & SF_USE_MP) && !sb->u.affs_sb.s_uid && sb->s_covered) {
-               sb->s_mounted->i_uid = sb->u.affs_sb.s_uid = sb->s_covered->i_uid;
-               sb->s_mounted->i_gid = sb->u.affs_sb.s_gid = sb->s_covered->i_gid;
-               sb->u.affs_sb.s_flags &= ~SF_USE_MP;
-       }
        if (!(sb->s_flags & MS_RDONLY)) {
                lock_super(sb);
                for (i = 0, clean = 1; i < sb->u.affs_sb.s_bm_count; i++) {
@@ -149,13 +154,6 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, i
                        }
                        *mount_opts |= SF_IMMUTABLE;
                }
-               if (!strcmp(this_char,"usemp")) {
-                       if (value) {
-                               printk("AFFS: option usemp does not take an argument\n");
-                               return 0;
-                       }
-                       *mount_opts |= SF_USE_MP;
-               }
                else if (!strcmp(this_char,"verbose")) {
                        if (value) {
                                printk("AFFS: option verbose does not take an argument\n");
@@ -380,6 +378,16 @@ affs_read_super(struct super_block *s,void *data, int silent)
        bb = affs_bread(dev,0,s->s_blocksize);
        if (bb) {
                chksum = htonl(*(__u32 *)bb->b_data);
+
+               /* Dircache filesystems are compatible with non-dircache ones
+                * when reading. As long as they aren't supported, writing is
+                * not recommended.
+                */
+               if ((chksum == FS_DCFFS || chksum == MUFS_DCFFS || chksum == FS_DCOFS
+                    || chksum == MUFS_DCOFS) && !(s->s_flags & MS_RDONLY)) {
+                       printk("AFFS: Dircache FS - mounting %s read only.\n",kdevname(dev));
+                       s->s_flags |= MS_RDONLY;
+               }
                switch (chksum) {
                        case MUFS_FS:
                        case MUFS_INTLFFS:
@@ -388,9 +396,11 @@ affs_read_super(struct super_block *s,void *data, int silent)
                        case FS_INTLFFS:
                                s->u.affs_sb.s_flags |= SF_INTL;
                                break;
+                       case MUFS_DCFFS:
                        case MUFS_FFS:
                                s->u.affs_sb.s_flags |= SF_MUFS;
                                break;
+                       case FS_DCFFS:
                        case FS_FFS:
                                break;
                        case MUFS_OFS:
@@ -399,20 +409,13 @@ affs_read_super(struct super_block *s,void *data, int silent)
                        case FS_OFS:
                                s->u.affs_sb.s_flags |= SF_OFS;
                                break;
+                       case MUFS_DCOFS:
                        case MUFS_INTLOFS:
                                s->u.affs_sb.s_flags |= SF_MUFS;
-                               /* fall thru */
+                       case FS_DCOFS:
                        case FS_INTLOFS:
                                s->u.affs_sb.s_flags |= SF_INTL | SF_OFS;
                                break;
-                       case FS_DCOFS:
-                       case FS_DCFFS:
-                       case MUFS_DCOFS:
-                       case MUFS_DCFFS:
-                               if (!silent)
-                                       printk("AFFS: Unsupported filesystem on device %s: %08X\n",
-                                               kdevname(dev),chksum);
-                               if (0)
                        default:
                                printk("AFFS: Unknown filesystem on device %s: %08X\n",
                                       kdevname(dev),chksum);
@@ -432,8 +435,8 @@ affs_read_super(struct super_block *s,void *data, int silent)
                       (char *)&chksum,((char *)&chksum)[3] + '0',blocksize);
        }
 
-       s->s_magic = AFFS_SUPER_MAGIC;
-       s->s_flags = MS_NODEV | MS_NOSUID;
+       s->s_magic  = AFFS_SUPER_MAGIC;
+       s->s_flags |= MS_NODEV | MS_NOSUID;
 
        /* Keep super block in cache */
        if (!(s->u.affs_sb.s_root_bh = affs_bread(dev,root_block,s->s_blocksize))) {
@@ -587,6 +590,7 @@ nobitmap:
        affs_brelse(s->u.affs_sb.s_root_bh);
        if (s->u.affs_sb.s_bitmap)
                kfree(s->u.affs_sb.s_bitmap);
+       set_blocksize(dev,BLOCK_SIZE);
        s->s_dev = 0;
        unlock_super(s);
        MOD_DEC_USE_COUNT;
@@ -787,7 +791,7 @@ affs_write_inode(struct inode *inode)
                                        gid = inode->i_gid ^ ~0;
                        }
                        if (!(inode->i_sb->u.affs_sb.s_flags & SF_SETUID))
-                               file_end->owner_gid = ntohs(uid);
+                               file_end->owner_uid = ntohs(uid);
                        if (!(inode->i_sb->u.affs_sb.s_flags & SF_SETGID))
                                file_end->owner_gid = ntohs(gid);
                }
index e0f93a6d3e7e385de565dd6a700f927e9816452b..127c3d681b241fe3520ebab27f6f38c63d09d19b 100644 (file)
@@ -476,20 +476,11 @@ repeat:
        return;
 }
 
-static inline unsigned long value(struct inode * inode)
-{
-       if (inode->i_lock)  
-               return 1000;
-       if (inode->i_dirt)
-               return 1000;
-       return inode->i_nrpages;
-}
-
 struct inode * get_empty_inode(void)
 {
        static int ino = 0;
        struct inode * inode, * best;
-       unsigned long badness = 1000;
+       unsigned long badness;
        int i;
 
        if (nr_inodes < max_inodes && nr_free_inodes < (nr_inodes >> 1))
@@ -497,50 +488,54 @@ struct inode * get_empty_inode(void)
 repeat:
        inode = first_inode;
        best = NULL;
+       badness = 1000;
        for (i = nr_inodes/2; i > 0; i--,inode = inode->i_next) {
                if (!inode->i_count) {
-                       unsigned long i = value(inode);
+                       unsigned long i = 999;
+                       if (!(inode->i_lock | inode->i_dirt))
+                               i = inode->i_nrpages;
                        if (i < badness) {
                                best = inode;
-                               if ((badness = i) == 0)
-                                       break;
+                               if (!i)
+                                       goto found_good;
+                               badness = i;
                        }
                }
        }
-       if (badness)
-               if (nr_inodes < max_inodes) {
-                       if (grow_inodes() == 0)
-                               goto repeat;
-               }
-       inode = best;
-       if (!inode) {
+       if (nr_inodes < max_inodes) {
+               if (grow_inodes() == 0)
+                       goto repeat;
+               best = NULL;
+       }
+       if (!best) {
                printk("VFS: No free inodes - contact Linus\n");
                sleep_on(&inode_wait);
                goto repeat;
        }
-       if (inode->i_lock) {
-               wait_on_inode(inode);
+       if (best->i_lock) {
+               wait_on_inode(best);
                goto repeat;
        }
-       if (inode->i_dirt) {
-               write_inode(inode);
+       if (best->i_dirt) {
+               write_inode(best);
                goto repeat;
        }
-       if (inode->i_count)
+       if (best->i_count)
                goto repeat;
-       clear_inode(inode);
-       inode->i_count = 1;
-       inode->i_nlink = 1;
-       inode->i_version = ++event;
-       inode->i_sem.count = 1;
-       inode->i_ino = ++ino;
-       inode->i_dev = 0;
+found_good:
+       clear_inode(best);
+       best->i_count = 1;
+       best->i_nlink = 1;
+       best->i_version = ++event;
+       best->i_sem.count = 1;
+       best->i_ino = ++ino;
+       best->i_dev = 0;
        nr_free_inodes--;
        if (nr_free_inodes < 0) {
                printk ("VFS: get_empty_inode: bad free inode count.\n");
                nr_free_inodes = 0;
        }
-       return inode;
+       return best;
 }
 
 struct inode * get_pipe_inode(void)
index 44b87b19da9db8bbc76c9cc2631e7b5afcd6b081..32b09355830bce3dfec4da8a870e8d9dfe6e3350 100644 (file)
@@ -5,9 +5,11 @@
  *
  *  (C) 1991  Linus Torvalds - minix filesystem
  *
+ *  Steve Beynon                      : Missing last directory entries fixed
+ *  (stephen@askone.demon.co.uk)      : 21st June 1996
+ * 
  *  isofs directory handling functions
  */
-
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/iso_fs.h>
@@ -133,9 +135,13 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 #ifdef DEBUG
                printk("Block, offset, f_pos: %x %x %x\n",
                       block, offset, filp->f_pos);
+               printk("inode->i_size = %x\n",inode->i_size);
 #endif
                /* Next directory_record on next CDROM sector */
                if (offset >= bufsize) {
+#ifdef DEBUG
+                       printk("offset >= bufsize\n");
+#endif
                        brelse(bh);
                        offset = 0;
                        block = isofs_bmap(inode, (filp->f_pos) >> bufbits);
@@ -151,6 +157,10 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                inode_number = (block << bufbits) + (offset & (bufsize - 1));
 
                de_len = *(unsigned char *) de;
+#ifdef DEBUG
+               printk("de_len = %ld\n", de_len);
+#endif
+           
 
                /* If the length byte is zero, we should move on to the next
                   CDROM sector.  If we are at the end of the directory, we
@@ -175,15 +185,31 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                   If not, put the two halves together in "tmpde" */
                next_offset = offset + de_len;
                if (next_offset > bufsize) {
+#ifdef DEBUG
+                       printk("next_offset (%x) > bufsize (%x)\n",next_offset,bufsize);
+#endif
                        next_offset &= (bufsize - 1);
-                       memcpy(tmpde, de, bufsize - offset);
+                       memcpy(tmpde, de, bufsize - offset);
                        brelse(bh);
                        block = isofs_bmap(inode, (filp->f_pos + de_len) >> bufbits);
                        if (!block)
+                       {
                                return 0;
-                       bh = breada(inode->i_dev, block, bufsize, filp->f_pos+de_len, inode->i_size);
+                       }
+                 
+                       bh = breada(inode->i_dev, block, bufsize, 
+                                   filp->f_pos, 
+                                   inode->i_size);
                        if (!bh)
+                       {
+#ifdef DEBUG
+                               printk("!bh block=%ld, bufsize=%ld\n",block,bufsize); 
+                               printk("filp->f_pos = %ld\n",filp->f_pos);
+                               printk("inode->i_size = %ld\n", inode->i_size);
+#endif
                                return 0;
+                       }
+                 
                        memcpy(bufsize - offset + (char *) tmpde, bh->b_data, next_offset);
                        de = tmpde;
                }
index 70c205cdc6d926766a095d1392bd678a61dca9f9..59cc720c4cc52be7b2fed4f66ef3d97a89f73b4b 100644 (file)
@@ -189,7 +189,7 @@ static unsigned int isofs_get_last_session(kdev_t dev)
          printk("isofs.inode: vol_desc_start = %d\n", ms_info.addr.lba);
        }
 #endif 0
-      if ((i==0)&&(ms_info.xa_flag)) vol_desc_start=ms_info.addr.lba;
+      if (i==0) vol_desc_start=ms_info.addr.lba;
     }
   return vol_desc_start;
 }
index 482cc751898985f162fbcd9f4239c81488aee42d..9c61412f4d4ec2240eeb7c1d849ce824d1c9954c 100644 (file)
@@ -62,6 +62,31 @@ static void probe_m68k_ide (void);
 #undef HD_DATA
 #define HD_DATA NULL
 
+/* MSch: changed sti() to STI() wherever possible in ide.c; moved STI() def. 
+ * to asm/ide.h 
+ */
+/* The Atari interrupt structure strictly requires that the IPL isn't lowered
+ * uncontrolled in an interrupt handler. In the concrete case, the IDE
+ * interrupt is already a slow int, so the irq is already disabled at the time
+ * the handler is called, and the IPL has been lowered to the minimum value
+ * possible. To avoid going below that, STI() checks for being called inside
+ * an interrupt, and in that case it does nothing. Hope that is reasonable and
+ * works. (Roman)
+ */
+#if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA)
+#define        STI()                                   \
+    do {                                       \
+       if (!intr_count) sti();                 \
+    } while(0)
+#elif defined(CONFIG_ATARI)
+#define        STI()                                           \
+    do {                                               \
+       if (!MACH_IS_ATARI || !intr_count) sti();       \
+    } while(0)
+#else /* !defined(CONFIG_ATARI) */
+#define        STI()   sti()
+#endif
+
 #define SELECT_DRIVE(hwif,drive)  OUT_BYTE((drive)->select.all, hwif->io_base+IDE_SELECT_OFFSET);
 
 #define insl(data_reg, buffer, wcount) insw(data_reg, buffer, wcount<<1)
index 1287d195917ab008166c9eb17d70da697f494db1..0ff862d13810a69f111ec8ecd9d93de5240da568 100644 (file)
@@ -64,7 +64,6 @@ struct affs_sb_info {
 #define SF_SETUID      0x0010          /* Ignore Amiga uid */
 #define SF_SETGID      0x0020          /* Ignore Amiga gid */
 #define SF_SETMODE     0x0040          /* Ignore Amiga protection bits */
-#define SF_USE_MP      0x0080          /* Use uid and gid from mount point */
 #define SF_MUFS                0x0100          /* Use MUFS uid/gid mapping */
 #define SF_OFS         0x0200          /* Old filesystem */
 #define SF_PREFIX      0x0400          /* Buffer for prefix is allocated */
index 396d20ad513c338ff8b94ac8c8cf4b079d01a140..d304fbb7cde251d8180783da727864cb62c18f6f 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -467,6 +467,7 @@ asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
        int err;
        unsigned int id;
        unsigned long addr;
+       unsigned long len;
 
        if (shmid < 0) {
                /* printk("shmat() -> EINVAL because shmid = %d < 0\n",shmid); */
@@ -490,6 +491,12 @@ asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
                else
                        return -EINVAL;
        }
+       /*
+        * Check if addr exceeds TASK_SIZE (from do_mmap)
+        */
+       len = PAGE_SIZE*shp->shm_npages;
+       if (addr >= TASK_SIZE || len > TASK_SIZE  || addr > TASK_SIZE - len)
+               return -EINVAL;
        /*
         * If shm segment goes below stack, make sure there is some
         * space left for the stack to grow (presently 4 pages).
index 7971f7b88a5d4e800b9866ad69466597e5f339c0..2d37ebd9f6281d00b71064c7ebb38451b90251fc 100644 (file)
@@ -415,7 +415,7 @@ static void profile_readahead(int async, struct file *filp)
  * Reasonable means, in this context, not too large but not too small.
  * The actual maximum value is:
  *     MAX_READAHEAD + PAGE_SIZE = 76k is CONFIG_READA_SMALL is undefined
- *      and 32K if defined.
+ *      and 32K if defined (4K page size assumed).
  *
  * Asynchronous read-ahead benefits:
  * ---------------------------------
@@ -442,15 +442,17 @@ static void profile_readahead(int async, struct file *filp)
  * - The total memory pool usage for the file access stream.
  *   This maximum memory usage is implicitly 2 IO read chunks:
  *   2*(MAX_READAHEAD + PAGE_SIZE) = 156K if CONFIG_READA_SMALL is undefined,
- *   64k if defined.
+ *   64k if defined (4K page size assumed).
  */
 
-#if 0 /* small readahead */
-#define MAX_READAHEAD (PAGE_SIZE*7)
-#define MIN_READAHEAD (PAGE_SIZE*2)
-#else
-#define MAX_READAHEAD (PAGE_SIZE*18)
-#define MIN_READAHEAD (PAGE_SIZE*3)
+#define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK)
+
+#if 0  /* small readahead */
+#define MAX_READAHEAD PageAlignSize(4096*7)
+#define MIN_READAHEAD PageAlignSize(4096*2)
+#else /* large readahead */
+#define MAX_READAHEAD PageAlignSize(4096*18)
+#define MIN_READAHEAD PageAlignSize(4096*3)
 #endif
 
 static inline unsigned long generic_file_readahead(int reada_ok, struct file * filp, struct inode * inode,
index a758e0a29f4d4118f1a391a3bcd472646357812e..0510e75277a51ddfa7a4626e420507aab30575dc 100644 (file)
@@ -756,26 +756,6 @@ bad_area:
        return -EFAULT;
 }
 
-static inline void get_empty_page(struct task_struct * tsk, struct vm_area_struct * vma,
-       pte_t * page_table, int write_access)
-{
-       pte_t pte;
-
-       pte = pte_wrprotect(mk_pte(ZERO_PAGE, vma->vm_page_prot));
-       if (write_access) {
-               unsigned long page = get_free_page(GFP_KERNEL);
-               pte = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-               vma->vm_mm->rss++;
-               tsk->min_flt++;
-               if (!page) {
-                       oom(tsk);
-                       pte = BAD_PAGE;
-               }
-               flush_page_to_ram(page);
-       }
-       put_page(page_table, pte);
-}
-
 /*
  * This function zeroes out partial mmap'ed pages at truncation time..
  */
@@ -886,6 +866,9 @@ static inline void do_swap_page(struct task_struct * tsk,
  * tries to share with existing pages, but makes a separate copy if
  * the "write_access" parameter is true in order to avoid the next
  * page fault.
+ *
+ * As this is called only for pages that do not currently exist, we
+ * do not need to flush old virtual caches or the TLB.
  */
 void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma,
        unsigned long address, int write_access)
@@ -938,23 +921,31 @@ void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma,
                entry = pte_mkwrite(pte_mkdirty(entry));
        } else if (mem_map[MAP_NR(page)].count > 1 && !(vma->vm_flags & VM_SHARED))
                entry = pte_wrprotect(entry);
-       flush_cache_page(vma, address);
        put_page(page_table, entry);
        /* no need to invalidate: a not-present page shouldn't be cached */
        return;
 
+anonymous_page:
+       entry = pte_wrprotect(mk_pte(ZERO_PAGE, vma->vm_page_prot));
+       if (write_access) {
+               unsigned long page = __get_free_page(GFP_KERNEL);
+               if (!page)
+                       goto sigbus;
+               memset((void *) page, 0, PAGE_SIZE);
+               entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
+               vma->vm_mm->rss++;
+               tsk->min_flt++;
+               flush_page_to_ram(page);
+       }
+       put_page(page_table, entry);
+       return;
+
 sigbus:
        force_sig(SIGBUS, current);
-       flush_cache_page(vma, address);
        put_page(page_table, BAD_PAGE);
        /* no need to invalidate, wasn't present */
        return;
 
-anonymous_page:
-       flush_cache_page(vma, address);
-       get_empty_page(tsk, vma, page_table, write_access);
-       return;
-
 swap_page:
        do_swap_page(tsk, vma, address, page_table, entry, write_access);
        return;