diff -u --recursive --new-file v2.0.8/linux/CREDITS linux/CREDITS --- v2.0.8/linux/CREDITS Tue Jul 23 08:23:11 1996 +++ linux/CREDITS Thu Jul 25 09:08:27 1996 @@ -1004,9 +1004,10 @@ 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: USA N: Hans-Joachim Widmaier -E: jbhr@sofal.tynet.sub.org +E: hjw@zvw.de D: AFFS rewrite S: Eichenweg 16 S: 73650 Winterbach diff -u --recursive --new-file v2.0.8/linux/Documentation/Changes linux/Documentation/Changes --- v2.0.8/linux/Documentation/Changes Wed Jul 17 08:12:14 1996 +++ linux/Documentation/Changes Tue Jul 23 10:26:49 1996 @@ -22,7 +22,11 @@ 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 @@ - 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 @@ 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 @@ 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 @@ 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 @@ pages due to changes in groff. If your man pages display 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 ************************************************* diff -u --recursive --new-file v2.0.8/linux/Documentation/filesystems/affs.txt linux/Documentation/filesystems/affs.txt --- v2.0.8/linux/Documentation/filesystems/affs.txt Mon May 20 08:20:58 1996 +++ linux/Documentation/filesystems/affs.txt Thu Jul 25 09:08:28 1996 @@ -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 @@ 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 @@ 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 @@ 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/ (where + 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 @@ 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 diff -u --recursive --new-file v2.0.8/linux/Documentation/ide.txt linux/Documentation/ide.txt --- v2.0.8/linux/Documentation/ide.txt Mon Jul 8 16:09:50 1996 +++ linux/Documentation/ide.txt Tue Jul 23 11:33:32 1996 @@ -107,7 +107,7 @@ 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: @@ -119,6 +119,9 @@ ide1=0x170,0x376,15 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 diff -u --recursive --new-file v2.0.8/linux/Makefile linux/Makefile --- v2.0.8/linux/Makefile Tue Jul 23 08:23:11 1996 +++ linux/Makefile Tue Jul 23 08:22:48 1996 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 0 -SUBLEVEL = 8 +SUBLEVEL = 9 ARCH = i386 diff -u --recursive --new-file v2.0.8/linux/arch/alpha/defconfig linux/arch/alpha/defconfig --- v2.0.8/linux/arch/alpha/defconfig Wed Jul 17 08:12:15 1996 +++ linux/arch/alpha/defconfig Thu Jul 25 20:24:49 1996 @@ -62,6 +62,7 @@ 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 diff -u --recursive --new-file v2.0.8/linux/arch/i386/Makefile linux/arch/i386/Makefile --- v2.0.8/linux/arch/i386/Makefile Tue Jul 23 08:23:11 1996 +++ linux/arch/i386/Makefile Thu Jul 25 19:35:00 1996 @@ -40,7 +40,7 @@ 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 diff -u --recursive --new-file v2.0.8/linux/drivers/block/Config.in linux/drivers/block/Config.in --- v2.0.8/linux/drivers/block/Config.in Thu Jun 6 17:42:32 1996 +++ linux/drivers/block/Config.in Tue Jul 23 11:33:32 1996 @@ -16,13 +16,13 @@ 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 @@ 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 diff -u --recursive --new-file v2.0.8/linux/drivers/block/ali14xx.c linux/drivers/block/ali14xx.c --- v2.0.8/linux/drivers/block/ali14xx.c Mon Feb 12 07:04:02 1996 +++ linux/drivers/block/ali14xx.c Tue Jul 23 11:33:32 1996 @@ -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: * @@ -23,6 +25,16 @@ * * 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 @@ }; /* 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 @@ 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; } diff -u --recursive --new-file v2.0.8/linux/drivers/block/cmd640.c linux/drivers/block/cmd640.c --- v2.0.8/linux/drivers/block/cmd640.c Sun May 5 08:51:58 1996 +++ linux/drivers/block/cmd640.c Tue Jul 23 11:33:32 1996 @@ -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. @@ -44,7 +55,12 @@ * * 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 @@ 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 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 @@ * 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 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 @@ 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 @@ /* * 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 @@ */ 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 @@ /* * 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 @@ 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 @@ 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 @@ * 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 @@ 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 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 @@ { int b_reg; int ac, rc, at; + byte b; /* * Set address setup count and drive read/write timing registers. @@ -588,22 +646,28 @@ 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 @@ * 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 @@ 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 @@ * 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 @@ 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 @@ /* * 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 @@ 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 @@ 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"); } - diff -u --recursive --new-file v2.0.8/linux/drivers/block/dtc2278.c linux/drivers/block/dtc2278.c --- v2.0.8/linux/drivers/block/dtc2278.c Sun May 5 08:51:58 1996 +++ linux/drivers/block/dtc2278.c Tue Jul 23 11:33:32 1996 @@ -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 + * DTC2278E also has serial ports and a printer port + * DTC2278EB: has onboard BIOS, and "works like a charm" -- Kent Bradford * * There may be a fourth controller type. The S and D versions use the * Winbond chip, and I think the E version does also. diff -u --recursive --new-file v2.0.8/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.0.8/linux/drivers/block/genhd.c Mon May 20 08:20:58 1996 +++ linux/drivers/block/genhd.c Thu Jul 25 09:08:28 1996 @@ -551,6 +551,88 @@ #endif /* CONFIG_SUN_PARTITION */ +#ifdef CONFIG_AMIGA_PARTITION +#include +#include + +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; @@ -582,6 +664,10 @@ #endif #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"); diff -u --recursive --new-file v2.0.8/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.0.8/linux/drivers/block/ide.c Tue Jul 23 08:23:12 1996 +++ linux/drivers/block/ide.c Wed Jul 24 07:48:47 1996 @@ -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) */ @@ -238,6 +238,11 @@ * 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 * @@ -284,7 +289,6 @@ #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 @@ 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 @@ 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 @@ 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 @@ */ 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 @@ 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 @@ }; 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 @@ 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 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 @@ 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 @@ /* * 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 @@ /* * 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 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; diff -u --recursive --new-file v2.0.8/linux/drivers/block/ide.h linux/drivers/block/ide.h --- v2.0.8/linux/drivers/block/ide.h Sat May 11 10:42:05 1996 +++ linux/drivers/block/ide.h Thu Jul 25 20:27:39 1996 @@ -135,7 +135,11 @@ * 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 @@ } 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 @@ 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 @@ 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 @@ 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 */ diff -u --recursive --new-file v2.0.8/linux/drivers/block/triton.c linux/drivers/block/triton.c --- v2.0.8/linux/drivers/block/triton.c Wed Apr 10 17:02:24 1996 +++ linux/drivers/block/triton.c Thu Jul 25 07:18:32 1996 @@ -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 @@ /* * 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 @@ 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 @@ 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) diff -u --recursive --new-file v2.0.8/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c --- v2.0.8/linux/drivers/cdrom/mcdx.c Thu Jun 6 22:35:43 1996 +++ linux/drivers/cdrom/mcdx.c Tue Jul 23 10:26:54 1996 @@ -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? diff -u --recursive --new-file v2.0.8/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- v2.0.8/linux/drivers/char/keyboard.c Mon May 13 23:02:48 1996 +++ linux/drivers/char/keyboard.c Thu Jul 25 20:24:49 1996 @@ -18,6 +18,7 @@ */ #define KEYBOARD_IRQ 1 +#define DISABLE_KBD_DURING_INTERRUPTS 0 #include #include @@ -69,14 +70,6 @@ #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 #include @@ -337,48 +330,31 @@ 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 @@ 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 @@ #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 @@ 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 @@ 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 @@ * 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 @@ 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 @@ " - ignored\n", scancode); #endif } - goto end_kbd_intr; + return; } } else keycode = scancode; @@ -526,12 +502,12 @@ 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 @@ #endif } } +} + +static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned char status; -end_kbd_intr: - send_cmd(0xAE); /* enable keyboard */ + 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) diff -u --recursive --new-file v2.0.8/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.0.8/linux/drivers/char/mem.c Wed Jul 3 22:05:08 1996 +++ linux/drivers/char/mem.c Thu Jul 25 16:52:13 1996 @@ -176,6 +176,8 @@ for (left = count; left > 0; left--) { put_user(0,buf); buf++; + if (need_resched) + schedule(); } return count; } diff -u --recursive --new-file v2.0.8/linux/drivers/char/psaux.c linux/drivers/char/psaux.c --- v2.0.8/linux/drivers/char/psaux.c Tue Jul 23 08:23:12 1996 +++ linux/drivers/char/psaux.c Tue Jul 23 06:48:28 1996 @@ -25,10 +25,6 @@ * Rearranged SIGIO support to use code from tty_io. 9Sept95 ctm@ardi.com * * Modularised 8-Sep-95 Philip Blundell - * - * Fixed keyboard lockups at open time (intervening kbd interrupts), handle - * RESEND replies, better error checking - * 3-Jul-96 Roman Hodek */ /* Uncomment the following line if your mouse needs initialization. */ @@ -61,10 +57,8 @@ #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 */ @@ -87,14 +81,6 @@ #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_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 @@ /* - * 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; + int retries = 0; - 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; + 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 @@ 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 @@ return -ENODEV; if (aux_count++) return 0; - if (poll_aux_status() < 0) { + if (!poll_aux_status()) { aux_count--; return -EBUSY; } @@ -360,27 +317,12 @@ } 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 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 @@ 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 @@ #ifdef MODULE int init_module(void) { - return psaux_init(); + return psaux_init(); /*?? Bjorn */ } void cleanup_module(void) @@ -615,18 +545,28 @@ 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 diff -u --recursive --new-file v2.0.8/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.0.8/linux/drivers/char/tty_io.c Wed Jul 3 22:05:08 1996 +++ linux/drivers/char/tty_io.c Wed Jul 24 10:53:39 1996 @@ -755,9 +755,48 @@ 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 @@ } } #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); } /* diff -u --recursive --new-file v2.0.8/linux/drivers/scsi/ChangeLog.ncr53c8xx linux/drivers/scsi/ChangeLog.ncr53c8xx --- v2.0.8/linux/drivers/scsi/ChangeLog.ncr53c8xx Wed Jul 17 08:12:16 1996 +++ linux/drivers/scsi/ChangeLog.ncr53c8xx Tue Jul 23 10:26:41 1996 @@ -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. diff -u --recursive --new-file v2.0.8/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.0.8/linux/drivers/scsi/ncr53c8xx.c Wed Jul 17 08:12:16 1996 +++ linux/drivers/scsi/ncr53c8xx.c Tue Jul 23 10:26:41 1996 @@ -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 @@ #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 @@ 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 @@ 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 @@ 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 @@ (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 diff -u --recursive --new-file v2.0.8/linux/drivers/scsi/ncr53c8xx.h linux/drivers/scsi/ncr53c8xx.h --- v2.0.8/linux/drivers/scsi/ncr53c8xx.h Sat Jul 6 14:51:24 1996 +++ linux/drivers/scsi/ncr53c8xx.h Tue Jul 23 10:26:41 1996 @@ -196,7 +196,7 @@ #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 @@ #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,\ diff -u --recursive --new-file v2.0.8/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.0.8/linux/drivers/scsi/scsi.c Wed Jul 10 15:20:26 1996 +++ linux/drivers/scsi/scsi.c Tue Jul 23 10:26:49 1996 @@ -2875,11 +2875,32 @@ 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 @@ 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 @@ 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... */ diff -u --recursive --new-file v2.0.8/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c --- v2.0.8/linux/drivers/sound/dmabuf.c Sat Jul 6 14:51:26 1996 +++ linux/drivers/sound/dmabuf.c Tue Jul 23 10:26:49 1996 @@ -582,7 +582,7 @@ if (!audio_devs[dev]->go) tmout = 0; else - tmout = 2 * HZ; + tmout = 10 * HZ; { diff -u --recursive --new-file v2.0.8/linux/drivers/sound/pss.c linux/drivers/sound/pss.c --- v2.0.8/linux/drivers/sound/pss.c Sat Jul 6 14:51:27 1996 +++ linux/drivers/sound/pss.c Tue Jul 23 10:26:53 1996 @@ -832,7 +832,9 @@ 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 diff -u --recursive --new-file v2.0.8/linux/fs/affs/inode.c linux/fs/affs/inode.c --- v2.0.8/linux/fs/affs/inode.c Tue May 21 19:52:37 1996 +++ linux/fs/affs/inode.c Thu Jul 25 09:08:28 1996 @@ -44,16 +44,26 @@ 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 @@ 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 @@ } *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 @@ 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 @@ 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 @@ 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 @@ (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 @@ 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 @@ 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); } diff -u --recursive --new-file v2.0.8/linux/fs/inode.c linux/fs/inode.c --- v2.0.8/linux/fs/inode.c Fri Apr 19 10:08:01 1996 +++ linux/fs/inode.c Wed Jul 24 07:03:07 1996 @@ -476,20 +476,11 @@ 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 @@ 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) diff -u --recursive --new-file v2.0.8/linux/fs/isofs/dir.c linux/fs/isofs/dir.c --- v2.0.8/linux/fs/isofs/dir.c Fri Dec 22 13:00:19 1995 +++ linux/fs/isofs/dir.c Tue Jul 23 10:26:40 1996 @@ -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 #include #include @@ -133,9 +135,13 @@ #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 @@ 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 @@ 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; } diff -u --recursive --new-file v2.0.8/linux/fs/isofs/inode.c linux/fs/isofs/inode.c --- v2.0.8/linux/fs/isofs/inode.c Sat Jun 1 20:11:33 1996 +++ linux/fs/isofs/inode.c Tue Jul 23 10:27:00 1996 @@ -189,7 +189,7 @@ 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; } diff -u --recursive --new-file v2.0.8/linux/include/asm-m68k/ide.h linux/include/asm-m68k/ide.h --- v2.0.8/linux/include/asm-m68k/ide.h Tue Apr 23 13:57:12 1996 +++ linux/include/asm-m68k/ide.h Tue Jul 23 11:33:32 1996 @@ -62,6 +62,31 @@ #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) diff -u --recursive --new-file v2.0.8/linux/include/linux/affs_fs_sb.h linux/include/linux/affs_fs_sb.h --- v2.0.8/linux/include/linux/affs_fs_sb.h Tue May 21 19:52:37 1996 +++ linux/include/linux/affs_fs_sb.h Thu Jul 25 09:08:28 1996 @@ -64,7 +64,6 @@ #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 */ diff -u --recursive --new-file v2.0.8/linux/ipc/shm.c linux/ipc/shm.c --- v2.0.8/linux/ipc/shm.c Sat Apr 27 15:20:07 1996 +++ linux/ipc/shm.c Tue Jul 23 10:26:53 1996 @@ -467,6 +467,7 @@ 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 @@ 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). diff -u --recursive --new-file v2.0.8/linux/mm/filemap.c linux/mm/filemap.c --- v2.0.8/linux/mm/filemap.c Tue Jul 23 08:23:15 1996 +++ linux/mm/filemap.c Tue Jul 23 10:26:40 1996 @@ -415,7 +415,7 @@ * 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 @@ * - 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, diff -u --recursive --new-file v2.0.8/linux/mm/memory.c linux/mm/memory.c --- v2.0.8/linux/mm/memory.c Tue Jul 23 08:23:15 1996 +++ linux/mm/memory.c Tue Jul 23 14:03:43 1996 @@ -756,26 +756,6 @@ 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 @@ * 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,21 +921,29 @@ 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: