Commit 12980ed0 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.15

parent 03ba0966
......@@ -544,14 +544,13 @@ E: ajh@primag.co.uk
D: Selection mechanism
N: Jochen Hein
E: jochen.hein@informatik.tu-clausthal.de
E: jochen.hein@delphi.central.de
P: 1024/4A27F015 25 72 FB E3 85 9F DE 3B CB 0A DA DA 40 77 05 6C
D: National Language Support
D: German Support-Disks for SLS/Slackware called SLT
D: Linux Internationalization Project
D: DOSemu
S: Muehlenweg 19
S: 34266 Niestetal
D: German Localization for Linux and GNU software
S: Frankenstrae
S: 34131 Kassel
S: Germany
N: Richard Henderson
......
This is a brief list of all the files in ./linux/Documentation and what
they contain. If you add a documentation file, please list it here in
alphabetical order as well. Note that subdirectories have their own
index files too.
Thanks -- Paul.
alphabetical order as well, or risk being hunted down like a rabid dog.
Note that subdirectories have their own index files too.
Thanks -- Paul G.
00-INDEX
- this file.
......@@ -14,6 +14,8 @@ CodingStyle
- how the boss likes the C code in the kernel to look.
Configure.help
- text file that is used for help when you run "make config"
IO-mapping.txt
- how to access I/O mapped memory from within device drivers.
SMP.txt
- notes, and "To Fix" list for multi-processor Linux. (see smp.tex)
cdrom/
......@@ -24,6 +26,8 @@ devices.txt
- plain ASCII listing of all the nodes in /dev/ with major minor #'s
digiboard.txt
- info on the Digiboard PC/X{i,e,eve} multiport boards.
exception.txt
- how linux v2.1 handles exceptions without verify_area etc.
filesystems/
- directory with info on the various filesystems that Linux supports.
ide.txt
......@@ -38,10 +42,16 @@ java.txt
- info on the in-kernel binary support for Java(tm)
locks.txt
- info on file locking implementations, flock() vs. fcntl(), etc.
logo.gif
- Full colour GIF image of Linux logo (penguin)
logo.txt
- Info on creator of above logo & site to get additional images from.
magic-number.txt
- list of magic numbers used to mark/protect kernel data structures.
mandatory.txt
- info on the linux implementation of Sys V mandatory file locking.
mca.txt
- info on supporting Micro Channel Architecture (e.g. PS/2) systems.
modules.txt
- short guide on how to make kernel parts into loadable modules
networking/
......@@ -66,4 +76,7 @@ unicode.txt
- info on the Unicode character/font mapping used in Linux.
watchdog.txt
- how to auto-reboot Linux if it has "fallen and can't get up". ;-)
xterm-linux.xpm
- XPM image of penguin logo (see logo.txt) sitting on an xterm.
......@@ -19,7 +19,7 @@ you don't need to bother doing so in the form of a diff, as this is
generated by texinfo so a diff is useless anyway (though I can
incorporate one by hand if you insist upon sending it that way ;-).
Last updated: November 20, 1996.
Last updated: December 3, 1996.
Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
Current Minimal Requirements
......@@ -28,14 +28,15 @@ Current Minimal Requirements
Upgrade to at *least* these software revisions before thinking you've
encountered a bug!
- Kernel modules 2.0.8
- Kernel modules 2.1.13
- Gnu C 2.7.2.1
- Binutils 2.7.0.3
- Linux C Library 5.4.12
- Linux C Library 5.4.13
- Dynamic Linker (ld.so) 1.8.5
- Linux C++ Library 2.7.2.1
- Procps 1.01
- SysVinit 2.64
- Util-linux 2.5
- Mount 2.5p
- Net-tools 1.32-alpha
- Kbd 0.91
......@@ -60,19 +61,21 @@ currently compile ELF, consult the ELF howto at
http://sunsite.unc.edu/mdw/HOWTO/ELF-HOWTO.html and upgrade your system
accordingly.
For modules to work, you need to be running libc-5.4.7 or greater.
For modules to work, you need to be running libc-5.4.x or greater.
Since updates to libc fix other problems as well (security flaws, for
example) and since 5.4.7 is missing a few needed symbols, try to get
the latest 5.4.x you can. Currently, that is libc-5.4.12.
the latest 5.4.x you can. Currently, libc-5.4.13 is the latest public
release.
If you upgrade to libc-5.4.x, you also have to upgrade your dynamic
linker (ld.so) to at least 1.8.3, or all sorts of weirdness will happen.
linker (ld.so) to at least 1.8.5, or all sorts of weirdness will
happen. Actually, ld.so-1.8.2 and later will work, but only 1.8.5 is
widely available, so if you need to upgrade, use it.
Modules
=======
You need to upgrade to modules-2.0.8 for kernels 2.1.8 and later.
Currently, there is no modules package which works with kernel 2.1.1.
You need to upgrade to modules-2.1.13 for kernels 2.1.8 and later.
Gnu C
=====
......@@ -105,55 +108,69 @@ Where to get the files
Binutils
========
ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/binutils-2.7.0.3.bin.tar.gz
The 2.7.0.3 release:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.7.0.3.bin.tar.gz
ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.7.0.3.bin.tar.gz
Installation notes:
ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/release.binutils-2.7.0.3
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.7.0.3
ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.7.0.3
Gnu C
=====
The 2.7.2.1 release:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/gcc-2.7.2.1.bin.tar.gz
ftp://sunsite.unc.edu/pub/Linux/GCC/gcc-2.7.2.1.bin.tar.gz
Installation notes:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.gcc-2.7.2.1
ftp://sunsite.unc.edu/pub/Linux/GCC/release.gcc-2.7.2.1
Linux C Library
===============
The stable 5.2.18 release:
ftp://sunsite.unc.edu/pub/Linux/GCC/libc-5.2.18.bin.tar.gz
Installation notes for 5.2.18:
ftp://sunsite.unc.edu/pub/Linux/GCC/release.libc-5.2.18
The latest 5.4.12 release (when it gets there):
ftp://sunsite.unc.edu/pub/Linux/GCC/libc-5.4.12.bin.tar.gz
Installation notes for 5.4.12:
ftp://sunsite.unc.edu/pub/Linux/GCC/release.libc-5.4.12
The 5.4.13 release:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/libc-5.4.13.bin.tar.gz
ftp://sunsite.unc.edu/pub/Linux/GCC/libc-5.4.13.bin.tar.gz
Installation notes for 5.4.13:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.gcc-2.7.2.1
ftp://sunsite.unc.edu/pub/Linux/GCC/release.libc-5.4.13
Linux C++ Library
=================
The 2.7.2.1 release:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/libg++-2.7.2.1.bin.tar.gz
ftp://sunsite.unc.edu/pub/Linux/GCC/libg++-2.7.2.1.bin.tar.gz
Installation notes:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.libg++-2.7.2.1
ftp://sunsite.unc.edu/pub/Linux/GCC/release.libg++-2.7.2.1
Dynamic Linker
==============
The 1.8.5 release:
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/ld.so-1.8.5.tar.gz
ftp://sunsite.unc.edu/pub/Linux/GCC/ld.so-1.8.5.tar.gz
Modules utilities
=================
ftp://sunsite.unc.edu/pub/Linux/kernel/v2.1/modules-2.0.8.tar.gz
The 2.1.13 release:
ftp://tsx-11.mit.edu/pub/linux/sources/system/v2.1/modules-2.1.13.tar.gz
ftp://sunsite.unc.edu/pub/Linux/kernel/v2.1/modules-2.1.13.tar.gz
Procps utilities
================
The 1.01 release:
ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/procps-1.01.tgz
ftp://sunsite.unc.edu/pub/Linux/system/Status/ps/procps-1.01.tgz
SysVinit utilities
==================
The 2.64 release:
ftp://tsx-11.mit.edu/pub/linux/sources/sbin/sysvinit-2.64.tar.gz
ftp://sunsite.unc.edu/pub/Linux/system/Daemons/init/sysvinit-2.64.tar.gz
Other Info
......
This diff is collapsed.
......@@ -42,7 +42,7 @@ foo \kill}%
%
\title{{\bf Linux Allocated Devices}}
\author{Maintained by H. Peter Anvin $<$hpa@zytor.com$>$}
\date{Last revised: November 18, 1996}
\date{Last revised: December 7, 1996}
\maketitle
%
\noindent
......@@ -65,8 +65,8 @@ where that applies (e.g.\ busmice), please contact me with the
appropriate device information. Also, if you have additional
information regarding any of the devices listed below, or if I have
made a mistake, I would greatly appreciate a note. When sending me
mail, please include the word ``device'' in the subject so your mail
won't accidentally get buried!
mail, {\em please\/} include the word ``device'' in the subject so
your mail won't accidentally get buried!
Allocations marked (68k/Amiga) apply to Linux/68k on the Amiga
platform only. Allocations marked (68k/Atari) apply to Linux/68k on
......@@ -185,7 +185,9 @@ reply.
\major{58}{}{char }{Hayes ESP serial card -- alternate devices}
\major{59}{}{char }{sf firewall package}
\major{60}{--63}{}{Local/experimental use}
\major{64}{--119}{}{Unallocated}
\major{64}{}{char }{ENskip kernel encryption package}
\major{65}{}{char }{Sundance ``plink'' Transputer boards}
\major{66}{--119}{}{Unallocated}
\major{120}{--127}{}{Local/experimental use}
\major{128}{--239}{}{Unallocated}
\major{240}{--254}{}{Local/experimental use}
......@@ -333,19 +335,19 @@ partitioning schemes appropriate to their respective architectures.
\minor{64}{/dev/ttyS0}{First serial port}
\minordots
\minor{127}{/dev/ttyS63}{64th serial port}
\minor{128}{/dev/ptyp0}{First pseudo-tty master}
\minor{128}{/dev/ptyp0}{First old pseudo-tty master}
\minordots
\minor{191}{/dev/ptysf}{64th pseudo-tty master}
\minor{192}{/dev/ttyp0}{First pseudo-tty slave}
\minor{191}{/dev/ptysf}{64th old pseudo-tty master}
\minor{192}{/dev/ttyp0}{First old pseudo-tty slave}
\minordots
\minor{255}{/dev/ttysf}{64th pseudo-tty slave}
\minor{255}{/dev/ttysf}{64th old pseudo-tty slave}
\end{devicelist}
\noindent
For compatibility with previous versions of Linux, the first 64 PTYs
are replicated under this device number. This use will be obsolescent
with the release of Linux 2.0 and may be removed in a future version
of Linux.
are replicated under this device number. This use is deprecated with
the release of Linux 2.0 and may be removed in a future version of
Linux. To ensure proper operation, do not mix old and new PTY devices.
\begin{devicelist}
\major{ 5}{}{char }{Alternate TTY devices}
......@@ -388,6 +390,11 @@ NOTE: These devices permit both read and write access.
\minordots
\end{devicelist}
\noindent
The loopback devices are used to mount filesystems not associated with
block devices. The binding to the loopback devices is handled by
{\bf mount}(8) or {\bf losetup}(8).
\begin{devicelist}
\major{ 8}{}{block}{SCSI disk devices}
\minor{0}{/dev/sda}{First SCSI disk whole disk}
......@@ -472,11 +479,6 @@ physical disks.
\minor{139}{/dev/openprom}{SPARC OpenBoot PROM}
\end{devicelist}
\noindent
The loopback devices are used to mount filesystems not associated with
block devices. The binding to the loopback devices is usually handled
by {\bf mount}(8).
\begin{devicelist}
\major{11}{}{char }{Raw keyboard device}
\minor{0}{/dev/kbd}{Raw keyboard device}
......@@ -1162,7 +1164,37 @@ For devices not assigned official numbers, these ranges should be
used, in order to avoid conflict with future assignments.
\begin{devicelist}
\major{64}{--119}{}{Unallocated}
\major{64}{}{char }{ENskip kernel encryption package}
\minor{0}{/dev/enskip}{Communication with ENskip kernel
module}
\end{devicelist}
\begin{devicelist}
\major{65}{}{char }{Sundance ``plink'' Transputer boards}
\minor{0}{/dev/plink0}{First plink device}
\minor{1}{/dev/plink1}{Second plink device}
\minor{2}{/dev/plink2}{Third plink device}
\minor{3}{/dev/plink3}{Fourth plink device}
\minor{64}{/dev/rplink0}{First plink device, raw}
\minor{65}{/dev/rplink1}{Second plink device, raw}
\minor{66}{/dev/rplink2}{Third plink device, raw}
\minor{67}{/dev/rplink3}{Fourth plink device, raw}
\minor{128}{/dev/plink0d}{First plink device, debug}
\minor{129}{/dev/plink1d}{Second plink device, debug}
\minor{130}{/dev/plink2d}{Third plink device, debug}
\minor{131}{/dev/plink3d}{Fourth plink device, debug}
\minor{192}{/dev/rplink0d}{First plink device, raw, debug}
\minor{193}{/dev/rplink1d}{Second plink device, raw, debug}
\minor{194}{/dev/rplink2d}{Third plink device, raw, debug}
\minor{195}{/dev/rplink3d}{Fourth plink device, raw, debug}
\end{devicelist}
\noindent
This is a commercial driver; contact James Howes
$<$jth@prosig.demon.co.uk$>$ for information.
\begin{devicelist}
\major{66}{--119}{}{Unallocated}
\end{devicelist}
\begin{devicelist}
......
......@@ -2,7 +2,7 @@
Maintained by H. Peter Anvin <hpa@zytor.com>
Last revised: November 18, 1996
Last revised: December 7, 1996
This list is the successor to Rick Miller's Linux Device List, which
he stopped maintaining when he got busy with other things in 1993. It
......@@ -22,7 +22,7 @@ where that applies (e.g. busmice), please contact me with the
appropriate device information. Also, if you have additional
information regarding any of the devices listed below, or if I have
made a mistake, I would greatly appreciate a note. When sending me
mail, please include the word "device" in the subject so your mail
mail, *please* include the word "device" in the subject so your mail
won't accidentally get buried!
Allocations marked (68k/Amiga) apply to Linux/68k on the Amiga
......@@ -160,18 +160,19 @@ reply.
64 = /dev/ttyS0 First serial port
...
127 = /dev/ttyS63 64th serial port
128 = /dev/ptyp0 First pseudo-tty master
128 = /dev/ptyp0 First old pseudo-tty master
...
191 = /dev/ptysf 64th pseudo-tty master
192 = /dev/ttyp0 First pseudo-tty slave
191 = /dev/ptysf 64th old pseudo-tty master
192 = /dev/ttyp0 First old pseudo-tty slave
...
255 = /dev/ttysf 64th pseudo-tty slave
255 = /dev/ttysf 64th old pseudo-tty slave
For compatibility with previous versions of Linux, the
first 64 PTYs are replicated under this device
number. This use will be obsolescent with the release
of Linux 1.4 and may be removed in a future version of
Linux.
first 64 PTYs are replicated under this device number.
This use is deprecated with the release of Linux 2.0
and may be removed in a future version of Linux. To
ensure proper operation, do not mix old and new PTY
devices.
5 char Alternate TTY devices
0 = /dev/tty Current TTY device
......@@ -207,7 +208,7 @@ reply.
The loopback devices are used to mount filesystems not
associated with block devices. The binding to the
loopback devices is usually handled by mount(8).
loopback devices is handled by mount(8) or losetup(8).
8 block SCSI disk devices
0 = /dev/sda First SCSI disk whole disk
......@@ -813,7 +814,31 @@ reply.
assigned official numbers, these ranges should be
used, in order to avoid conflicting with future assignments.
64-119 UNALLOCATED
64 char ENskip kernel encryption package
0 = /dev/enskip Communication with ENskip kernel module
65 char Sundance "plink" Transputer boards
0 = /dev/plink0 First plink device
1 = /dev/plink1 Second plink device
2 = /dev/plink2 Third plink device
3 = /dev/plink3 Fourth plink device
64 = /dev/rplink0 First plink device, raw
65 = /dev/rplink1 Second plink device, raw
66 = /dev/rplink2 Third plink device, raw
67 = /dev/rplink3 Fourth plink device, raw
128 = /dev/plink0d First plink device, debug
129 = /dev/plink1d Second plink device, debug
130 = /dev/plink2d Third plink device, debug
131 = /dev/plink3d Fourth plink device, debug
192 = /dev/rplink0d First plink device, raw, debug
193 = /dev/rplink1d Second plink device, raw, debug
194 = /dev/rplink2d Third plink device, raw, debug
195 = /dev/rplink3d Fourth plink device, raw, debug
This is a commercial driver; contact James Howes
<jth@prosig.demon.co.uk> for information.
66-119 UNALLOCATED
120-127 LOCAL/EXPERIMENTAL USE
......@@ -826,6 +851,7 @@ reply.
ADDITIONAL /dev DIRECTORY ENTRIES
This section details additional entries that should or may exist in
......
......@@ -66,6 +66,7 @@ NEW! - support for IDE ATAPI *floppy* drives
- the hdparm-3.1 package can be used to set PIO modes for some chipsets.
NEW! - support for the OPTi 82C621 chipset, courtesy of Jaromir Koutek.
NEW! - support for loadable modules
NEW! - optional SCSI host adapter emulation for ATAPI devices
For work in progress, see the comments in ide.c, ide-cd.c, triton.c, ...
......@@ -110,12 +111,12 @@ shell script: /usr/src/linux/scripts/MAKEDEV.ide
Apparently many releases of Slackware 2.2/2.3 have incorrect entries
in /dev for hdc* and hdd* -- this can also be corrected by running MAKEDEV.ide
ide.c automatically probes for the primary and secondary interfaces,
ide.c automatically probes for the standard four IDE interfaces,
for the drives/geometries attached to those interfaces, and for the
IRQ numbers being used by the interfaces (normally IRQ14 & IRQ15).
IRQ numbers being used by the interfaces (normally 14, 15, 11 and 10).
Interfaces beyond the first two are not normally probed for, but may be
specified using kernel "command line" options. For example,
For special cases, interfaces may be specified using kernel "command line"
options. For example,
ide3=0x168,0x36e,10 /* ioports 0x168-0x16f,0x36e, irq 10 */
......@@ -234,6 +235,25 @@ and still allows newer hardware to run on the 2nd/3rd/4th IDE ports
under control of ide.c. To have ide.c also "take over" the primary
IDE port in this situation, use the "command line" parameter: ide0=0x1f0
The IDE driver is partly modularized. The high level disk/cdrom/tape/floppy
drivers can always be compiled as loadable modules, the chipset drivers
can only be compiled into the kernel, and the core code (ide.c) can be
compiled as a loadable module provided no chipset support and no special
partition table translations are needed.
When using ide.c/ide-tape.c as modules in combination with kerneld, add:
alias block-major-3 ide-probe
alias char-major-37 ide-tape
respectively to /etc/conf.modules.
When ide.c is used as a module, you can pass command line parameters to the
driver using the "options=" keyword to insmod, while replacing any ',' with
';'. For example:
insmod ide.o options="ide0=serialize ide2=0x1e8;0x3ee;11"
mlord@pobox.com
snyder@fnald0.fnal.gov
================================================================================
......@@ -256,6 +276,7 @@ Summary of ide driver parameters for kernel "command line":
older/odd IDE drives.
"hdx=slow" : insert a huge pause after each access to the data
port. Should be used only as a last resort.
"hdx=swapdata" : when the drive is a disk, byte swap all data
"idebus=xx" : inform IDE driver of VESA/PCI bus speed in MHz,
where "xx" is between 20 and 66 inclusive,
......@@ -283,6 +304,7 @@ Summary of ide driver parameters for kernel "command line":
This is the default for most chipsets,
except the cmd640.
"idex=serialize" : do not overlap operations on idex and ide(x^1)
"idex=reset" : reset interface after probe
The following are valid ONLY on ide0,
and the defaults for the base,ctl ports must not be altered.
......
Ioctl Numbers
5 Oct 1996
2 Dec 1996
Michael Chastain
<mec@duracef.shout.net>
<mec@shout.net>
If you are adding new ioctl's to the kernel, you should use the _IO
macros defined in <linux/ioctl.h>:
......@@ -51,7 +51,7 @@ Following the convention is good because:
code to call verify_area to validate parameters.
This table lists ioctls visible from user land for Linux/i386. It is
current to Linux 2.1.1
current to Linux 2.1.14.
Code Seq# Include File Comments
========================================================
......@@ -64,10 +64,8 @@ Code Seq# Include File Comments
0x09 all linux/md.h
0x12 all linux/fs.h
0x20 all linux/cm206.h
0x22 all linux/scc.h conflict! (version 2.01 of z8530drv)
0x22 all scsi/sg.h conflict!
0x22 all scsi/sg.h
'A' all linux/apm_bios.h
'B' all linux/baycom.h
'C' all linux/soundcard.h
'F' all linux/fb.h
'I' all linux/isdn.h
......@@ -86,7 +84,6 @@ Code Seq# Include File Comments
'V' all linux/vt.h
'W' 00-1F linux/pcwd.h
'Y' all linux/cyclades.h
'Z' all linux/scc.h version 2.2 of z8530drv
'a' all various, see http://lrcwww.epfl.ch/linux-atm/magic.html
'c' all linux/comstats.h
'f' all linux/ext2_fs.h
......@@ -102,7 +99,9 @@ Code Seq# Include File Comments
'v' all linux/ext2_fs.h
'w' all CERN SCI driver (in development)
0x89 00-0F asm-i386/sockios.h
0x89 10-FF linux/sockios.h
0x89 10-DF linux/sockios.h
0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range
0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range
0x90 00 linux/sbpcd.h
0x99 00-0F 537-Addinboard driver (in development, e-mail contact:
b.kohl@ipn-b.comlink.apc.org)
i386 Micro Channel Architecture Support
=======================================
MCA support is enabled using the CONFIG_MCA define. A machine with a MCA
bus will have the kernel variable MCA_bus set, assuming the BIOS feature
bits are set properly (see arch/i386/boot/setup.S for information on
how this detection is done).
Adapter Detection
=================
The ideal MCA adapter detection is done through the use of the
Programmable Option Select registers. Generic functions for doing
this have been added in include/linux/mca.h and arch/i386/kernel/mca.c.
Everything needed to detect adapters and read (and write) configuration
information is there. A number of MCA-specific drivers already use
this. The typical probe code looks like the following:
#include <linux/mca.h>
unsigned char pos2, pos3, pos4, pos5;
struct device* dev;
int slot;
if( MCA_bus ) {
slot = mca_find_adapter( ADAPTER_ID, 0 );
if( slot == MCA_NOTFOUND ) {
return ENODEV;
}
/* optional - see below */
mca_set_adapter_name( slot, "adapter name & description" );
mca_set_adapter_procfn( slot, dev_getinfo, dev );
/* read the POS registers. Most devices only need
2 and 3 */
pos2 = mca_read_stored_pos( slot, 2 );
pos3 = mca_read_stored_pos( slot, 3 );
pos4 = mca_read_stored_pos( slot, 4 );
pos5 = mca_read_stored_pos( slot, 5 );
} else {
return ENODEV;
}
/* extract configuration from pos[2345] and set everything up */
Loadable modules should modify this to test that the specified IRQ and
IO ports (plus whatever other stuff) match. See 3c523.c for example
code.
Keep in mind that devices should never directly access the POS registers
(via inb(), outb(), etc). While it's generally safe, there is a small
potential for blowing up hardware when it's done at the wrong time.
Furthermore, accessing a POS register disables a device temporarily.
This is usually okay during startup, but do _you_ want to rely on it?
During initial configuration, mca_init() reads all the POS registers
into memory. mca_read_stored_pos() accesses that data. mca_read_pos()
and mca_write_pos() are also available for (safer) direct POS access,
but their use is _highly_ discouraged. mca_write_pos() is particularly
dangerous, as it is possible for adapters to be put in inconsistent
states (i.e. sharing IO address, etc) and may result in crashes, toasted
hardware, and operator injury.
User level drivers (such as the AGX X server) can use /proc/mca to find
adapters (see below).
Some MCA adapters can also be detected via the usual ISA-style device
probing (many SCSI adapters, for example). This sort of thing is highly
discouraged. Perfectly good information is available telling you what's
there, so there's no excuse for messing with random IO ports. However,
we MCA people still appreciate any ISA-style driver that will work with
our hardware. You take what you can get...
Level-Triggered Interrupts
==========================
Because MCA uses level-triggered interrupts, a few problems arise with
what might best be described as the ISA mindset and its effects on
drivers. These sorts of problems are expected to become less common as
more people use shared IRQs on PCI machines.
In general, an interrupt must be acknowledged not only at the ICU (which
is done automagically by the kernel), but at the device level. In
particular, IRQ 0 must be reset after a timer interrupt (now done in
arch/i386/kernel/time.c) or the first timer interrupt hangs the system.
There were also problems with the 1.3.x floppy drivers, but that seems
to have been fixed.
IRQs are also shareable, and most MCA-specific devices should be coded
with shared IRQs in mind.
/proc/mca
=========
I did a major rewrite of /proc/mca. It is now a directory containing
various files for adapters and other stuff.
/proc/mca/pos Straight listing of POS registers
/proc/mca/slot[1-8] Information on adapter in specific slot
/proc/mca/video Same for integrated video
/proc/mca/scsi Same for integrated SCSI
/proc/mca/machine Machine information
Device drivers can easily add their own information function for
specific slots (including integrated ones) via the
mca_set_adapter_procfn() call. Drivers that support this are ESDI, IBM
SCSI, and 3c523. If a device is also a module, make sure that the proc
function is removed in the module cleanup. This will require storing
the slot information in a private structure somewhere. See the 3c523
driver for details.
Your typical proc function will look something like this:
static int
dev_getinfo( char* buf, int slot, void* d ) {
struct device* dev = (struct device*) d;
int len = 0;
len += sprintf( buf+len, "Device: %s\n", dev->name );
len += sprintf( buf+len, "IRQ: %d\n", dev->irq );
len += sprintf( buf+len, "IO Port: %#lx-%#lx\n", ... );
...
return len;
}
Some of the standard MCA information will already be printed, so don't
bother repeating it. Don't try putting in more that 3K of information.
Enable this function with:
mca_set_adapter_procfn( slot, dev_getinfo, dev );
Disable it with:
mca_set_adapter_procfn( slot, NULL, NULL );
It is also recommended that, even if you don't write a proc function, to
set the name of the adapter (i.e. "PS/2 ESDI Controller") via
mca_set_adapter_name( int slot, char* name ). Up to 30 characters are
used.
MCA Device Drivers
==================
Currently, there are a number of MCA-specific device drivers.
1) PS/2 ESDI
drivers/block/ps2esdi.c
include/linux/ps2esdi.h
Uses major number 36, and should use /dev files /dev/eda, /dev/edb.
Supports two drives, but only one controller. Usually requires the
command-line args ed=cyl,head,sec
2) PS/2 SCSI
drivers/scsi/ibmmca.c
drivers/scsi/ibmmca.h
The driver for the IBM SCSI subsystem. Includes both integrated
controllers and adapter cards. May require command-line arg
ibmmcascsi=pun to force detection of an adapter.
3) 3c523
drivers/net/3c523.c
drivers/net/3c523.h
3Com 3c523 Etherlink/MC ethernet driver.
4) SMC Ultra/MCA
drivers/net/smc-mca.c
drivers/net/smc-mca.h
Elite/A (8013EP/A) and Elite10T/A (8013WP/A) ethernet driver
As well, drivers/char/psaux.c was modified to support IRQ sharing (it's
#ifdef CONFIG_MCA'ed, for your convenience, although PCI users might be
able to use it...)
The serial drivers were modified to support the extended IO port range
of the typical MCA system (also #ifdef CONFIG_MCA).
The following devices work with existing drivers:
1) Token-ring
2) Future Domain SCSI (MCS-600, MCS-700, not MCS-350)
3) Adaptec 1640 SCSI (aha1542 driver)
4) Buslogic SCSI (various)
Bugs & Other Weirdness
======================
NMIs tend to occur with MCA machines because of various hardware
weirdness, bus timeouts, and many other non-critical things. Those of
you who have NMI problems should probably set the CONFIG_IGNORE_NMI flag
somewhere. NMIs seem to be particularly common on the model 70.
Various Pentium machines have serious problems with the FPU test in
bugs.h. You may need to comment out the FPU test before you can even
boot. This occurs, as far as we know, on the Pentium-equipped 85s, 95s,
and some servers. The PCI/MCA PC 750s are fine as far as I can tell.
The model 80 has a raft of problems that are just too weird and unique
to get into here. Some people have no trouble while others have nothing
but problems. I'd suspect the problems are related to the age of the
average 80 and accompanying hardware deterioration.
Credits
=======
A whole pile of people have contributed to the MCA code. I'd include
their names here, but I don't have a list handy. Check the MCA Linux
home page (URL below) for an out-of-date list.
=====================================================================
http://glycerine.cetmm.uni.edu/mca
Chris Beauregard
chrisb@truespectra.com
......@@ -20,6 +20,8 @@ net-modules.txt
- info and "insmod" parameters for all network driver modules.
ppp.txt
- info on what software you should use to run PPP.
shaper.txt
- info on the module that can shape/limit transmitted traffic.
tcp.txt
- short blurb on how TCP output takes place.
tulip.txt
......
Traffic Shaper For Linux
This is the current ALPHA release of the traffic shaper for Linux. It works
within the following limits:
o Minimum shaping speed is currently about 9600 baud (it can only
shape down to 1 byte per clock tick)
o Maximum is about 256K, it will go above this but get a bit blocky.
o If you ifconfig the master device that a shaper is attached to down
then your machine will follow.
o The shaper must be a module.
Setup:
A shaper device is configured using the shapeconfig program.
Typically you will do something like this
shapecfg attach shaper0 eth1
shapecfg speed shaper0 64000
ifconfig shaper0 myhost netmask 255.255.255.240 broadcast 1.2.3.4.255 up
route add -net some.network netmask a.b.c.d dev shaper0
The shaper should have the same IP address as the device it is attached to
for normal use.
Gotchas:
The shaper shapes transmitted traffic. Its rather impossible to
shape received traffic except at the end (or a router) transmiting it.
Gated/routed/rwhod/mrouted all see the shaper as an additional device
and will treat it as such unless patched. Note that for mrouted you can run
mrouted tunnels via a traffic shaper to control bandwidth usage.
The shaper is device/route based. This makes it very easy to use
with any setup BUT less flexible. You may well want to combine this patch
with Mike McLagan <mmclagan@linux.org>'s patch to allow routes to be
specified by source/destination pairs.
There is no "borrowing" or "sharing" scheme. This is a simple
traffic limiter. I'd like to implement Van Jacobson and Sally Floyd's CBQ
architecture into Linux one day (maybe in 2.1 sometime) and do this with
style.
Alan
......@@ -43,11 +43,7 @@ trivial patch so apply some common sense.
7. Happy hacking.
[This file is new: I've just put the existing network contacts in, other
people please add yourselves] -- AC
-----------------------------------
-----------------------------------
Maintainers List (try to look for most precise areas first)
......@@ -113,8 +109,8 @@ S: Maintained
APPLETALK NETWORK LAYER
P: Alan Cox & University Of Michigan
M: net-patches@lxorguk.ukuu.org.uk, Cc: netatalk@umich.edu
L: [Someone fill in the netatalk list here]
M: net-patches@lxorguk.ukuu.org.uk
L: netatalk@umich.edu
S: Maintained
AX.25 NETWORK LAYER
......@@ -190,7 +186,7 @@ L: linux-scsi@vger.rutgers.edu
S: Odd fixes (e.g., new signatures)
SCSI TAPE DRIVER
P: Kai Mkisara
P: Kai Mdkisara
M: Kai.Makisara@metla.fi
L: linux-scsi@vger.rutgers.edu
S: Maintained
......@@ -254,7 +250,8 @@ NETWORKING [GENERAL]:
P: Alan Cox
M: net-patches@lxorguk.ukuu.org.uk
L: linux-net@vger.rutgers.edu
S: Odd Fixes <-> Maintained subject to workloads
W: http://www.uk.linux.org/NetNews.html
S: Maintained
PPP PROTOCOL DRIVERS AND COMPRESSORS
P: Al Longyear
......
VERSION = 2
PATCHLEVEL = 1
SUBLEVEL = 14
SUBLEVEL = 15
ARCH = i386
......
......@@ -19,6 +19,9 @@ list. To do this, e-mail majordomo@vger.rutgers.edu, and put in the body
of the message "subscribe linux-kernel" or "subscribe linux-kernel-digest"
for a daily digest of the mailing list (it is a high-traffic list.)
However, please make sure you don't ask questions which are already answered
in various files in the Documentation directory. See DOCUMENTATION below.
WHAT IS LINUX?
Linux is a Unix clone written from scratch by Linus Torvalds with
......@@ -51,7 +54,9 @@ DOCUMENTATION:
- There are various readme's in the kernel Documentation/ subdirectory:
these typically contain kernel-specific installation notes for some
drivers for example. See ./Documentation/00-INDEX for a list of what
is contained in each file.
is contained in each file. Please read the Changes file, as it
contains information about the problems, which may result by upgrading
your kernel.
INSTALLING the kernel:
......
......@@ -8,10 +8,10 @@ OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
strchr.o strrchr.o \
copy_user.o clear_user.o strncpy_from_user.o strlen_user.o
ifeq($(CONFIG_IPV6),y)
ifeq ($(CONFIG_IPV6),y)
OBJS += csum_ipv6_magic.o
else
ifeq($(CONFIG_IPV6),m)
ifeq ($(CONFIG_IPV6),m)
OBJS += csum_ipv6_magic.o
endif
endif
......
......@@ -30,6 +30,7 @@ if [ "$CONFIG_PCI" = "y" ]; then
bool ' PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
fi
fi
bool 'MCA support' CONFIG_MCA
bool 'System V IPC' CONFIG_SYSVIPC
tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
......
......@@ -21,6 +21,7 @@ CONFIG_MODULES=y
CONFIG_NET=y
# CONFIG_MAX_16M is not set
CONFIG_PCI=y
# CONFIG_MCA is not set
CONFIG_SYSVIPC=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
......@@ -44,6 +45,7 @@ CONFIG_BLK_DEV_IDEDISK=y
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
CONFIG_BLK_DEV_CMD640=y
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
CONFIG_BLK_DEV_RZ1000=y
......@@ -75,7 +77,7 @@ CONFIG_INET=y
#
# CONFIG_INET_PCTCP is not set
# CONFIG_INET_RARP is not set
# CONFIG_NO_PATH_MTU_DISCOVERY is not set
CONFIG_PATH_MTU_DISCOVERY=y
CONFIG_IP_NOSR=y
CONFIG_SKB_LARGE=y
......@@ -110,6 +112,7 @@ CONFIG_EL3=y
# CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
# CONFIG_DLCI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_NET_RADIO is not set
......@@ -156,6 +159,7 @@ CONFIG_SERIAL=y
# CONFIG_CYCLADES is not set
# CONFIG_STALDRV is not set
# CONFIG_RISCOM8 is not set
# CONFIG_ESP is not set
# CONFIG_PRINTER is not set
# CONFIG_MOUSE is not set
# CONFIG_UMISC is not set
......
......@@ -24,6 +24,10 @@ O_TARGET := kernel.o
O_OBJS := process.o signal.o entry.o traps.o irq.o vm86.o bios32.o \
ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o ksyms.o
ifdef CONFIG_MCA
O_OBJS += mca.o
endif
ifdef SMP
O_OBJS += smp.o
......
......@@ -280,6 +280,9 @@ ENTRY(system_call)
ALIGN
.globl ret_from_sys_call
ret_from_sys_call:
#ifdef __SMP__
GET_CURRENT
#endif
cmpl $0,SYMBOL_NAME(intr_count)
jne 1f
9: movl SYMBOL_NAME(bh_mask),%eax
......@@ -572,7 +575,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_iopl) /* 110 */
.long SYMBOL_NAME(sys_vhangup)
.long SYMBOL_NAME(sys_idle)
.long SYMBOL_NAME(sys_vm86)
.long SYMBOL_NAME(sys_vm86old)
.long SYMBOL_NAME(sys_wait4)
.long SYMBOL_NAME(sys_swapoff) /* 115 */
.long SYMBOL_NAME(sys_sysinfo)
......@@ -625,6 +628,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_mremap)
.long SYMBOL_NAME(sys_setresuid)
.long SYMBOL_NAME(sys_getresuid)
.rept NR_syscalls-165
.long SYMBOL_NAME(sys_vm86)
.rept NR_syscalls-166
.long SYMBOL_NAME(sys_ni_syscall)
.endr
......@@ -34,9 +34,28 @@ startup_32:
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
#ifdef __SMP__
orw %bx,%bx
jz 1f
/*
* New page tables may be in 4Mbyte page mode
*/
#ifdef GAS_KNOWS_CR4
movl %cr4,%eax # Turn on 4Mb pages
orl $16,%eax
movl %eax,%cr4
#else
.byte 0x0f,0x20,0xe0
orl $16,%eax
.byte 0x0f,0x22,0xe0
#endif
movl %eax,%cr3 /* flush TLB as per app note */
movl %cr0,%eax
#endif
/*
* Setup paging (the tables are already set up, just switch them on)
*/
1:
movl $0x101000,%eax
movl %eax,%cr3 /* set the page table pointer.. */
movl %cr0,%eax
......@@ -54,10 +73,12 @@ startup_32:
/*
* Set up the stack
*/
movl $(KERNEL_DS),%eax /* walken modif */
mov %ax,%ss
xorl %eax,%eax
movw %cx, %ax
movl %eax,%esp
addl $0xC0000000, %esp /* shift it to the upper mapping */
pushl $0
popfl
jmp checkCPUtype
......@@ -151,6 +172,8 @@ isnew: pushl %ecx # restore original EFLAGS
popfl
incl SYMBOL_NAME(have_cpuid) # we have CPUID
/* get processor type */
# LINUS WE HAVE A BUG HERE - MUST CHECK WITH
# CPUID#0 THAT CPUID#1 IS SUPPORTED...
movl $1, %eax # Use the CPUID instruction to
.byte 0x0f, 0xa2 # check the processor type
movb %al, %cl # save reg for future use
......@@ -187,11 +210,11 @@ is386: pushl %ecx # restore original EFLAGS
2: movl %eax,%cr0
call check_x87
#ifdef __SMP__
movb ready,%eax
orb %eax,%eax
jz 3f
movb ready,%al # First CPU if 0
orb %al,%al
jz 4f # First CPU skip this stuff
#ifdef GAS_KNOWS_CR4
movl %cr4,%eax
movl %cr4,%eax # Turn on 4Mb pages
orl $16,%eax
movl %eax,%cr4
#else
......@@ -199,13 +222,14 @@ is386: pushl %ecx # restore original EFLAGS
orl $16,%eax
.byte 0x0f,0x22,0xe0
#endif
jmp 4f
movl %cr3, %eax # Intel specification clarification says
movl %eax, %cr3 # to do this. Maybe it makes a difference.
# Who knows ?
#endif
3:
4:
#ifdef __SMP__
incb ready
#endif
4:
lgdt gdt_descr
lidt idt_descr
ljmp $(KERNEL_CS),$1f
......
#include <linux/config.h>
#include <linux/module.h>
#include <linux/smp.h>
#include <linux/user.h>
#include <linux/elfcore.h>
#include <linux/mca.h>
#include <asm/semaphore.h>
#include <asm/processor.h>
......@@ -32,6 +34,17 @@ static struct symbol_table arch_symbol_table = {
X(active_kernel_processor),
X(smp_invalidate_needed),
#endif
#ifdef CONFIG_MCA
/* Adapter probing and info methods. */
X(mca_write_pos),
X(mca_read_pos),
X(mca_read_stored_pos),
X(mca_set_adapter_name),
X(mca_get_adapter_name),
X(mca_set_adapter_procfn),
X(mca_isenabled),
X(mca_isadapter),
#endif
#include <linux/symtab_end.h>
};
......
......@@ -61,7 +61,7 @@ static inline int limits_ok(struct modify_ldt_ldt_s *ldt_info)
return (last >= first && last < TASK_SIZE);
}
static int write_ldt(void * ptr, unsigned long bytecount)
static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
{
struct modify_ldt_ldt_s ldt_info;
unsigned long *lp;
......@@ -75,10 +75,10 @@ static int write_ldt(void * ptr, unsigned long bytecount)
copy_from_user(&ldt_info, ptr, sizeof(ldt_info));
if (ldt_info.contents == 3 || ldt_info.entry_number >= LDT_ENTRIES)
if ((ldt_info.contents == 3 && (oldmode || ldt_info.seg_not_present == 0)) || ldt_info.entry_number >= LDT_ENTRIES)
return -EINVAL;
if (!limits_ok(&ldt_info))
if (!limits_ok(&ldt_info) && (oldmode || ldt_info.seg_not_present == 0))
return -EINVAL;
if (!current->ldt) {
......@@ -95,7 +95,14 @@ static int write_ldt(void * ptr, unsigned long bytecount)
lp = (unsigned long *) &current->ldt[ldt_info.entry_number];
/* Allow LDTs to be cleared by the user. */
if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
if (ldt_info.base_addr == 0 && ldt_info.limit == 0
&& (oldmode ||
( ldt_info.contents == 0
&& ldt_info.read_exec_only == 1
&& ldt_info.seg_32bit == 0
&& ldt_info.limit_in_pages == 0
&& ldt_info.seg_not_present == 1
&& ldt_info.useable == 0 )) ) {
*lp = 0;
*(lp+1) = 0;
return 0;
......@@ -111,6 +118,7 @@ static int write_ldt(void * ptr, unsigned long bytecount)
(ldt_info.limit_in_pages << 23) |
((ldt_info.seg_not_present ^1) << 15) |
0x7000;
if (!oldmode) *(lp+1) |= (ldt_info.useable << 20);
return 0;
}
......@@ -119,6 +127,8 @@ asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
if (func == 0)
return read_ldt(ptr, bytecount);
if (func == 1)
return write_ldt(ptr, bytecount);
return write_ldt(ptr, bytecount, 1);
if (func == 0x11)
return write_ldt(ptr, bytecount, 0);
return -ENOSYS;
}
This diff is collapsed.
......@@ -53,6 +53,12 @@ char hlt_works_ok = 1; /* set if the "hlt" instruction works */
* Bus types ..
*/
int EISA_bus = 0;
int MCA_bus = 0;
/* for MCA, but anyone else can use it if they want */
unsigned int machine_id = 0;
unsigned int machine_submodel_id = 0;
unsigned int BIOS_revision = 0;
/*
* Setup options
......@@ -62,6 +68,10 @@ struct screen_info screen_info;
#ifdef CONFIG_APM
struct apm_bios_info apm_bios_info;
#endif
struct sys_desc_table_struct {
unsigned short length;
unsigned char table[0];
};
unsigned char aux_device_present;
......@@ -94,6 +104,7 @@ extern char empty_zero_page[PAGE_SIZE];
#define KERNEL_START (*(unsigned long *) (PARAM+0x214))
#define INITRD_START (*(unsigned long *) (PARAM+0x218))
#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0x220))
#define COMMAND_LINE ((char *) (PARAM+2048))
#define COMMAND_LINE_SIZE 256
......@@ -124,6 +135,12 @@ void setup_arch(char **cmdline_p,
#ifdef CONFIG_APM
apm_bios_info = APM_BIOS_INFO;
#endif
if( SYS_DESC_TABLE.length != 0 ) {
MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
machine_id = SYS_DESC_TABLE.table[0];
machine_submodel_id = SYS_DESC_TABLE.table[1];
BIOS_revision = SYS_DESC_TABLE.table[2];
}
aux_device_present = AUX_DEVICE_INFO;
memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= PAGE_MASK;
......@@ -199,7 +216,7 @@ void setup_arch(char **cmdline_p,
/* request io space for devices used on all i[345]86 PC'S */
request_region(0x00,0x20,"dma1");
request_region(0x40,0x20,"timer");
request_region(0x80,0x20,"dma page reg");
request_region(0x80,0x10,"dma page reg");
request_region(0xc0,0x20,"dma2");
request_region(0xf0,0x10,"npu");
}
......
......@@ -82,7 +82,10 @@ asmlinkage int sys_sigreturn(unsigned long __unused)
#define COPY(x) regs->x = context->x
#define COPY_SEG(seg) \
{ unsigned int tmp = context->seg; \
if ((tmp & 0xfffc) && (tmp & 3) != 3) goto badframe; \
if ( (tmp & 0xfffc) /* not a NULL selectors */ \
&& (tmp & 0x4) != 0x4 /* not a LDT selector */ \
&& (tmp & 3) != 3 /* not a RPL3 GDT selector */ \
) goto badframe; \
regs->x##seg = tmp; }
#define COPY_SEG_STRICT(seg) \
{ unsigned int tmp = context->seg; \
......@@ -90,7 +93,10 @@ if ((tmp & 0xfffc) && (tmp & 3) != 3) goto badframe; \
regs->x##seg = tmp; }
#define GET_SEG(seg) \
{ unsigned int tmp = context->seg; \
if ((tmp & 0xfffc) && (tmp & 3) != 3) goto badframe; \
if ( (tmp & 0xfffc) /* not a NULL selectors */ \
&& (tmp & 0x4) != 0x4 /* not a LDT selector */ \
&& (tmp & 3) != 3 /* not a RPL3 GDT selector */ \
) goto badframe; \
__asm__("mov %w0,%%" #seg: :"r" (tmp)); }
struct sigcontext * context;
struct pt_regs * regs;
......
This diff is collapsed.
......@@ -371,6 +371,21 @@ static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
closely for now.. */
/*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
#ifdef CONFIG_MCA
if( MCA_bus ) {
/* The PS/2 uses level-triggered interrupts. You can't
turn them off, nor would you want to (any attempt to
enable edge-triggered interrupts usually gets intercepted by a
special hardware circuit). Hence we have to acknowledge
the timer interrupt. Through some incredibly stupid
design idea, the reset for IRQ 0 is done by setting the
high bit of the PPI port B (0x61). Note that some PS/2s,
notably the 55SX, work fine if this is removed. */
irq = inb_p( 0x61 ); /* read the current state */
outb_p( irq|0x80, 0x61 ); /* reset the IRQ */
}
#endif
}
#ifndef CONFIG_APM /* cycle counter may be unreliable */
......
......@@ -52,15 +52,27 @@ gdt:
.word 0,0,0,0 ! unused
.word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 ! base address=0
.word 0x9A00 ! code read/exec
.word 0x00C0 ! granularity=4096, 386
!walken modif
.word 0xFFFF ! 4Gb - (0x100000*0x1000 = 4Gb)
.word 0x0000 ! base address=0
.word 0x9A00 ! code read/exec
.word 0x00CF ! granularity=4096, 386 (+5th nibble of limit)
.word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 ! base address=0
.word 0x9200 ! data read/write
.word 0x00C0 ! granularity=4096, 386
.word 0xFFFF ! 4Gb - (0x100000*0x1000 = 4Gb)
.word 0x0000 ! base address=0
.word 0x9200 ! data read/write
.word 0x00CF ! granularity=4096, 386 (+5th nibble of limit)
!walken modif
! .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
! .word 0x0000 ! base address=0
! .word 0x9A00 ! code read/exec
! .word 0x00C0 ! granularity=4096, 386
! .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
! .word 0x0000 ! base address=0
! .word 0x9200 ! data read/write
! .word 0x00C0 ! granularity=4096, 386
idt_48:
.word 0 ! idt limit=0
......
......@@ -44,6 +44,20 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
die_if_kernel(str,regs,error_code); \
}
#define DO_VM86_ERROR(trapnr, signr, str, name, tsk) \
asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
{ \
if (regs->eflags & VM_MASK) { \
if (!handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr)) \
return; \
/* else fall through */ \
} \
tsk->tss.error_code = error_code; \
tsk->tss.trap_no = trapnr; \
force_sig(signr, tsk); \
die_if_kernel(str,regs,error_code); \
}
#define get_seg_byte(seg,addr) ({ \
register unsigned char __res; \
__asm__("push %%fs;mov %%ax,%%fs;movb %%fs:%2,%%al;pop %%fs" \
......@@ -164,12 +178,12 @@ int kstack_depth_to_print = 24;
do_exit(SIGSEGV);
}
DO_ERROR( 0, SIGFPE, "divide error", divide_error, current)
DO_ERROR( 3, SIGTRAP, "int3", int3, current)
DO_ERROR( 4, SIGSEGV, "overflow", overflow, current)
DO_ERROR( 5, SIGSEGV, "bounds", bounds, current)
DO_VM86_ERROR( 0, SIGFPE, "divide error", divide_error, current)
DO_VM86_ERROR( 3, SIGTRAP, "int3", int3, current)
DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow, current)
DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds, current)
DO_ERROR( 6, SIGILL, "invalid operand", invalid_op, current)
DO_ERROR( 7, SIGSEGV, "device not available", device_not_available, current)
DO_VM86_ERROR( 7, SIGSEGV, "device not available", device_not_available, current)
DO_ERROR( 8, SIGSEGV, "double fault", double_fault, current)
DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun, last_task_used_math)
DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS, current)
......@@ -181,7 +195,7 @@ DO_ERROR(18, SIGSEGV, "reserved", reserved, current)
asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
{
if (regs->eflags & VM_MASK) {
handle_vm86_fault((struct vm86_regs *) regs, error_code);
handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
return;
}
die_if_kernel("general protection",regs,error_code);
......@@ -206,7 +220,7 @@ asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
asmlinkage void do_debug(struct pt_regs * regs, long error_code)
{
if (regs->eflags & VM_MASK) {
handle_vm86_debug((struct vm86_regs *) regs, error_code);
handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
return;
}
force_sig(SIGTRAP, current);
......
This diff is collapsed.
......@@ -70,8 +70,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
2: movl %%edx, %%ecx
andl $0x1c, %%edx
je 4f
shrl $2, %%edx
testl %%esi, %%esi
shrl $2, %%edx # This clears CF
3: adcl (%%esi), %%eax
lea 4(%%esi), %%esi
dec %%edx
......@@ -117,52 +116,48 @@ unsigned int csum_partial_copy(const char *src, char *dst,
addw %%bx, %%ax
adcl $0, %%eax
2:
movl %%ecx, %%edx
pushl %%ecx
shrl $5, %%ecx
jz 2f
testl %%esi, %%esi
1: movl (%%esi), %%ebx
movl 4(%%esi), %%edx
adcl %%ebx, %%eax
movl %%ebx, (%%edi)
movl 4(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 4(%%edi)
adcl %%edx, %%eax
movl %%edx, 4(%%edi)
movl 8(%%esi), %%ebx
movl 12(%%esi), %%edx
adcl %%ebx, %%eax
movl %%ebx, 8(%%edi)
movl 12(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 12(%%edi)
adcl %%edx, %%eax
movl %%edx, 12(%%edi)
movl 16(%%esi), %%ebx
movl 20(%%esi), %%edx
adcl %%ebx, %%eax
movl %%ebx, 16(%%edi)
movl 20(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 20(%%edi)
adcl %%edx, %%eax
movl %%edx, 20(%%edi)
movl 24(%%esi), %%ebx
movl 28(%%esi), %%edx
adcl %%ebx, %%eax
movl %%ebx, 24(%%edi)
movl 28(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 28(%%edi)
adcl %%edx, %%eax
movl %%edx, 28(%%edi)
lea 32(%%esi), %%esi
lea 32(%%edi), %%edi
dec %%ecx
jne 1b
adcl $0, %%eax
2: movl %%edx, %%ecx
andl $28, %%edx
2: popl %%edx
movl %%edx, %%ecx
andl $0x1c, %%edx
je 4f
shrl $2, %%edx
testl %%esi, %%esi
shrl $2, %%edx # This clears CF
3: movl (%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, (%%edi)
......
......@@ -165,7 +165,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
/* Are we prepared to handle this fault? */
if ((fixup = search_exception_table(regs->eip)) != 0) {
printk("Exception at %lx (%lx)\n", regs->eip, fixup);
printk(KERN_DEBUG "Exception at %lx (%lx)\n", regs->eip, fixup);
regs->eip = fixup;
return;
}
......
......@@ -152,7 +152,6 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
* Intel Pentium cpu, unfortunately the SMP kernel can't
* handle the 4MB page table optimizations yet
*/
#ifndef __SMP__
/*
* This will create page tables that
* span up to the next 4MB virtual
......@@ -177,7 +176,6 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
address += 4*1024*1024;
continue;
}
#endif
/* map the memory at virtual addr 0xC0000000 */
/* pg_table is physical at this point */
pg_table = (pte_t *) (PAGE_MASK & pgd_val(pg_dir[768]));
......@@ -224,6 +222,9 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
#ifdef __SMP__
/*
* But first pinch a few for the stack/trampoline stuff
* FIXME: Don't need the extra page at 4K, but need to fix
* trampoline before removing it. (see the GDT stuff)
*
*/
start_low_mem += PAGE_SIZE; /* 32bit startup code */
start_low_mem = smp_alloc_memory(start_low_mem); /* AP processor stacks */
......
......@@ -15,6 +15,7 @@ else
dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE
dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE
dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE
if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
bool ' CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640
if [ "$CONFIG_BLK_DEV_CMD640" = "y" ]; then
......@@ -41,6 +42,9 @@ else
fi
fi
fi
if [ "$CONFIG_MCA" = "y" ]; then
bool 'PS/2 ESDI harddisk support' CONFIG_BLK_DEV_PS2
fi
comment 'Additional Block Devices'
......
......@@ -72,6 +72,11 @@ ifeq ($(CONFIG_BLK_DEV_TRITON),y)
L_OBJS += triton.o
endif
ifeq ($(CONFIG_BLK_DEV_PS2),y)
L_OBJS += ps2esdi.o
endif
ifeq ($(CONFIG_BLK_DEV_DTC2278),y)
L_OBJS += dtc2278.o
endif
......
This diff is collapsed.
......@@ -143,6 +143,7 @@
* 4.02 Dec 01, 1996 -- Applied patch from Gadi Oxman <gadio@netvision.net.il>
* to fix the drive door locking problems.
*
* 4.03 Dec 04, 1996 -- Added DSC overlap support.
*
* MOSTLY DONE LIST:
* Query the drive to find what features are available
......@@ -969,6 +970,53 @@ static void cdrom_start_read_continuation (ide_drive_t *drive)
&cdrom_read_intr);
}
#define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */
#define IDECD_SEEK_TIMER (2 * WAIT_MIN_SLEEP) /* 40 ms */
#define IDECD_SEEK_TIMEOUT (20 * IDECD_SEEK_TIMER) /* 0.8 sec */
static void cdrom_seek_intr (ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
int stat;
static int retry = 10;
if (cdrom_decode_status (drive, 0, &stat)) return;
CDROM_CONFIG_FLAGS(drive)->seeking = 1;
if (retry && jiffies - info->start_seek > IDECD_SEEK_TIMER) {
if (--retry == 0) {
printk ("%s: disabled DSC seek overlap\n", drive->name);
drive->dsc_overlap = 0;
}
}
}
static void cdrom_start_seek_continuation (ide_drive_t *drive)
{
struct packet_command pc;
struct request *rq = HWGROUP(drive)->rq;
int sector, frame, nskip;
sector = rq->sector;
nskip = (sector % SECTORS_PER_FRAME);
if (nskip > 0)
sector -= nskip;
frame = sector / SECTORS_PER_FRAME;
memset (&pc.c, 0, sizeof (pc.c));
pc.c[0] = SEEK;
put_unaligned(htonl (frame), (unsigned int *) &pc.c[2]);
(void) cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c), &cdrom_seek_intr);
}
static void cdrom_start_seek (ide_drive_t *drive, unsigned int block)
{
struct cdrom_info *info = drive->driver_data;
info->dma = 0;
info->start_seek = jiffies;
cdrom_start_packet_command (drive, 0, cdrom_start_seek_continuation);
}
/*
* Start a read request from the CD-ROM.
......@@ -1250,8 +1298,28 @@ void ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, unsigned long bloc
} else if (rq -> cmd != READ) {
printk ("ide-cd: bad cmd %d\n", rq -> cmd);
cdrom_end_request (0, drive);
} else
cdrom_start_read (drive, block);
} else {
struct cdrom_info *info = drive->driver_data;
if (CDROM_CONFIG_FLAGS(drive)->seeking) {
unsigned long elpased = jiffies - info->start_seek;
int stat = GET_STAT();
if ((stat & SEEK_STAT) != SEEK_STAT) {
if (elpased < IDECD_SEEK_TIMEOUT) {
ide_stall_queue (drive, IDECD_SEEK_TIMER);
return;
}
printk ("%s: DSC timeout\n", drive->name);
}
CDROM_CONFIG_FLAGS(drive)->seeking = 0;
}
if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
cdrom_start_seek (drive, block);
else
cdrom_start_read (drive, block);
info->last_block = block;
}
}
......@@ -2831,6 +2899,7 @@ static ide_driver_t ide_cdrom_driver = {
ide_cdrom, /* media */
0, /* busy */
1, /* supports_dma */
1, /* supports_dsc_overlap */
ide_cdrom_cleanup, /* cleanup */
ide_do_rw_cdrom, /* do_request */
NULL, /* ??? or perhaps
......
......@@ -76,6 +76,7 @@
#define ALLOW_MEDIUM_REMOVAL 0x1e
#define READ_CAPACITY 0x25
#define READ_10 0x28
#define SEEK 0x2b
#define MODE_SENSE_10 0x5a
#define MODE_SELECT_10 0x55
#define READ_CD 0xbe
......@@ -125,7 +126,8 @@ struct ide_cd_config_flags {
__u8 is_changer : 1; /* Drive is a changer. */
__u8 supp_disc_present: 1; /* Changer can report exact contents
of slots. */
__u8 reserved : 7;
__u8 seeking : 1; /* Seeking in progress */
__u8 reserved : 6;
};
#define CDROM_CONFIG_FLAGS(drive) ((struct ide_cd_config_flags *)&((drive)->bios_cyl))
......@@ -383,6 +385,8 @@ struct cdrom_info {
struct request request_sense_request;
struct packet_command request_sense_pc;
int dma;
unsigned long last_block;
unsigned long start_seek;
/* Buffer to hold mechanism status and changer slot table. */
struct atapi_changer_info *changer_info;
......
/*
* linux/drivers/block/ide-disk.c Version 1.0 Oct 6, 1996
* linux/drivers/block/ide-disk.c Version 1.01 Nov 25, 1996
*
* Copyright (C) 1994-1996 Linus Torvalds & authors (see below)
*/
......@@ -36,8 +36,9 @@
* code is still sprinkled about. Think of it as a major evolution, with
* inspiration from lots of linux users, esp. hamish@zot.apana.org.au
*
* Version 1.0 move disk only code from ide.c to ide-disk.c
* Version 1.00 move disk only code from ide.c to ide-disk.c
* support optional byte-swapping of all data
* Version 1.01 fix previous byte-swapping code
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
......@@ -85,9 +86,12 @@ static inline void idedisk_input_data (ide_drive_t *drive, void *buffer, unsigne
static inline void idedisk_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
{
ide_output_data(drive, buffer, wcount);
if (drive->bswap)
if (drive->bswap) {
idedisk_bswap_data(buffer, wcount);
ide_output_data(drive, buffer, wcount);
idedisk_bswap_data(buffer, wcount);
} else
ide_output_data(drive, buffer, wcount);
}
/*
......@@ -501,6 +505,7 @@ static ide_driver_t idedisk_driver = {
ide_disk, /* media */
0, /* busy */
1, /* supports_dma */
0, /* supports_dsc_overlap */
NULL, /* cleanup */
do_rw_disk, /* do_request */
NULL, /* end_request */
......
/*
* linux/drivers/block/ide-floppy.c Version 0.2 - ALPHA Oct 31, 1996
* linux/drivers/block/ide-floppy.c Version 0.3 - ALPHA Dec 2, 1996
*
* Copyright (C) 1996 Gadi Oxman <gadio@netvision.net.il>
*/
......@@ -15,6 +15,7 @@
*
* Ver 0.1 Oct 17 96 Initial test version, mostly based on ide-tape.c.
* Ver 0.2 Oct 31 96 Minor changes.
* Ver 0.3 Dec 2 96 Fixed error recovery bug.
*/
#include <linux/config.h>
......@@ -451,21 +452,26 @@ static void idefloppy_write_zeros (ide_drive_t *drive, unsigned int bcount)
static void idefloppy_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
{
ide_drive_t *drive = hwgroup->drive;
idefloppy_floppy_t *floppy = drive->driver_data;
struct request *rq = hwgroup->rq;
int error;
#if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "Reached idefloppy_end_request\n");
#endif /* IDEFLOPPY_DEBUG_LOG */
switch (uptodate) {
case 0: error = IDEFLOPPY_ERROR_GENERAL; break;
case 1: error = 0; break;
default: error = uptodate;
}
if (error)
floppy->failed_pc = NULL;
if (!IDEFLOPPY_RQ_CMD (rq->cmd)) {
ide_end_request (uptodate, hwgroup);
return;
}
switch (uptodate) {
case 0: rq->errors = IDEFLOPPY_ERROR_GENERAL; break;
case 1: rq->errors = 0; break;
default: rq->errors = uptodate;
}
rq->errors = error;
ide_end_drive_cmd (drive, 0, 0);
}
......@@ -967,8 +973,11 @@ static void idefloppy_do_request (ide_drive_t *drive, struct request *rq, unsign
#endif /* IDEFLOPPY_DEBUG_LOG */
if (rq->errors >= ERROR_MAX) {
printk (KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
drive->name, floppy->failed_pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);
if (floppy->failed_pc != NULL)
printk (KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
drive->name, floppy->failed_pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);
else
printk (KERN_ERR "ide-floppy: %s: I/O error\n", drive->name);
idefloppy_end_request (0, HWGROUP(drive));
return;
}
......@@ -1367,6 +1376,7 @@ static ide_driver_t idefloppy_driver = {
ide_floppy, /* media */
0, /* busy */
1, /* supports_dma */
0, /* supports_dsc_overlap */
idefloppy_cleanup, /* cleanup */
idefloppy_do_request, /* do_request */
idefloppy_end_request, /* end_request */
......
......@@ -535,14 +535,11 @@ static int init_irq (ide_hwif_t *hwif)
hwgroup = match->hwgroup;
} else {
hwgroup = kmalloc(sizeof(ide_hwgroup_t), GFP_KERNEL);
hwgroup->hwif = hwgroup->next_hwif = hwif->next = hwif;
memset(hwgroup, 0, sizeof(ide_hwgroup_t));
hwgroup->hwif = hwif->next = hwif;
hwgroup->rq = NULL;
hwgroup->handler = NULL;
if (hwif->drives[0].present)
hwgroup->drive = &hwif->drives[0];
else
hwgroup->drive = &hwif->drives[1];
hwgroup->poll_timeout = 0;
hwgroup->drive = NULL;
init_timer(&hwgroup->timer);
hwgroup->timer.function = &ide_timer_expiry;
hwgroup->timer.data = (unsigned long) hwgroup;
......@@ -567,6 +564,16 @@ static int init_irq (ide_hwif_t *hwif)
hwif->next = hwgroup->hwif->next;
hwgroup->hwif->next = hwif;
for (index = 0; index < MAX_DRIVES; ++index) {
ide_drive_t *drive = &hwif->drives[index];
if (!drive->present)
continue;
if (!hwgroup->drive)
hwgroup->drive = drive;
drive->next = hwgroup->drive->next;
hwgroup->drive->next = drive;
}
hwgroup->hwif = HWIF(hwgroup->drive);
restore_flags(flags); /* safe now that hwif->hwgroup is set up */
#ifndef __mc68000__
......@@ -671,7 +678,9 @@ static int hwif_init (int h)
(void) unregister_blkdev (hwif->major, hwif->name);
} else {
init_gendisk(hwif);
blk_dev[hwif->major].data = hwif;
blk_dev[hwif->major].request_fn = rfn;
blk_dev[hwif->major].queue = ide_get_queue;
read_ahead[hwif->major] = 8; /* (4kB) */
hwif->present = 1; /* success */
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -145,6 +145,9 @@ typedef unsigned char byte; /* used everywhere */
#define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */
#define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */
#define SECTOR_WORDS (512 / 4) /* number of 32bit words per sector */
#define IDE_LARGE_SEEK(b1,b2,t) (((b1) > (b2) + (t)) || ((b2) > (b1) + (t)))
#define IDE_MIN(a,b) ((a)<(b) ? (a):(b))
#define IDE_MAX(a,b) ((a)>(b) ? (a):(b))
/*
* Timeouts for various operations:
......@@ -158,6 +161,7 @@ typedef unsigned char byte; /* used everywhere */
#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 */
#define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */
#if defined(CONFIG_BLK_DEV_HT6560B) || defined(CONFIG_BLK_DEV_PROMISE)
#define SELECT_DRIVE(hwif,drive) \
......@@ -175,6 +179,7 @@ typedef unsigned char byte; /* used everywhere */
* Now for the data we need to maintain per-drive: ide_drive_t
*/
#define ide_scsi 0x21
#define ide_disk 0x20
#define ide_cdrom 0x5
#define ide_tape 0x1
......@@ -192,6 +197,11 @@ typedef union {
} special_t;
typedef struct ide_drive_s {
struct request *queue; /* request queue */
struct ide_drive_s *next; /* circular list of hwgroup drives */
unsigned long sleep; /* sleep until this time */
unsigned long service_start; /* time we started last request */
unsigned long service_time; /* service time of last request */
special_t special; /* special action flags */
unsigned present : 1; /* drive is physically present */
unsigned noprobe : 1; /* from: hdx=noprobe */
......@@ -208,6 +218,11 @@ typedef struct ide_drive_s {
unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */
unsigned revalidate : 1; /* request revalidation */
unsigned bswap : 1; /* flag: byte swap data */
unsigned dsc_overlap : 1; /* flag: DSC overlap */
unsigned atapi_overlap : 1; /* flag: ATAPI overlap (not supported) */
unsigned nice0 : 1; /* flag: give obvious excess bandwidth */
unsigned nice1 : 1; /* flag: give potential excess bandwidth */
unsigned nice2 : 1; /* flag: give a share in our own bandwidth */
#if FAKE_FDISK_FOR_EZDRIVE
unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */
#endif /* FAKE_FDISK_FOR_EZDRIVE */
......@@ -325,17 +340,17 @@ typedef struct hwgroup_s {
ide_handler_t *handler;/* irq handler, if active */
ide_drive_t *drive; /* current drive */
ide_hwif_t *hwif; /* ptr to current hwif in linked-list */
ide_hwif_t *next_hwif; /* next selected hwif (for tape) */
struct request *rq; /* current request */
struct timer_list timer; /* failsafe timer */
struct request wrq; /* local copy of current write rq */
unsigned long poll_timeout; /* timeout value during long polls */
int active; /* set when servicing requests */
} ide_hwgroup_t;
/*
* Subdrivers support.
*/
#define IDE_SUBDRIVER_VERSION 0
#define IDE_SUBDRIVER_VERSION 1
typedef int (ide_cleanup_proc)(ide_drive_t *);
typedef void (ide_do_request_proc)(ide_drive_t *, struct request *, unsigned long);
......@@ -352,6 +367,7 @@ typedef struct ide_driver_s {
byte media;
unsigned busy : 1;
unsigned supports_dma : 1;
unsigned supports_dsc_overlap : 1;
ide_cleanup_proc *cleanup;
ide_do_request_proc *do_request;
ide_end_request_proc *end_request;
......@@ -513,8 +529,7 @@ typedef enum
* If action is ide_end, then the rq is queued at the end of the
* request queue, and the function returns immediately without waiting
* for the new rq to be completed. This is again intended for careful
* use by the ATAPI tape/cdrom driver code. (Currently used by ide-tape.c,
* when operating in the pipelined operation mode).
* use by the ATAPI tape/cdrom driver code.
*/
int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action);
......@@ -538,7 +553,16 @@ int ide_system_bus_speed (void);
*/
void ide_multwrite (ide_drive_t *drive, unsigned int mcount);
void ide_revalidate_drives (void);
/*
* ide_stall_queue() can be used by a drive to give excess bandwidth back
* to the hwgroup by sleeping for timeout jiffies.
*/
void ide_stall_queue (ide_drive_t *drive, unsigned long timeout);
/*
* ide_get_queue() returns the queue which corresponds to a given device.
*/
struct request **ide_get_queue (kdev_t dev);
void ide_timer_expiry (unsigned long data);
void ide_intr (int irq, void *dev_id, struct pt_regs *regs);
......@@ -559,6 +583,9 @@ void ide_init_subdrivers (void);
extern struct file_operations ide_fops[];
#endif
#ifdef CONFIG_BLK_DEV_IDEDISK
int idedisk_init (void);
#endif /* CONFIG_BLK_DEV_IDEDISK */
#ifdef CONFIG_BLK_DEV_IDECD
int ide_cdrom_init (void);
#endif /* CONFIG_BLK_DEV_IDECD */
......@@ -568,9 +595,9 @@ int idetape_init (void);
#ifdef CONFIG_BLK_DEV_IDEFLOPPY
int idefloppy_init (void);
#endif /* CONFIG_BLK_DEV_IDEFLOPPY */
#ifdef CONFIG_BLK_DEV_IDEDISK
int idedisk_init (void);
#endif /* CONFIG_BLK_DEV_IDEDISK */
#ifdef CONFIG_BLK_DEV_IDESCSI
int idescsi_init (void);
#endif /* CONFIG_BLK_DEV_IDESCSI */
int ide_register_module (ide_module_t *module);
void ide_unregister_module (ide_module_t *module);
......
......@@ -81,6 +81,16 @@ int * blksize_size[MAX_BLKDEV] = { NULL, NULL, };
*/
int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, };
static inline struct request **get_queue(kdev_t dev)
{
int major = MAJOR(dev);
struct blk_dev_struct *bdev = blk_dev + major;
if (bdev->queue)
return bdev->queue(dev);
return &blk_dev[major].current_request;
}
/*
* remove the plug and let it rip..
*/
......@@ -94,7 +104,7 @@ void unplug_device(void * data)
if (dev->current_request == &dev->plug) {
struct request * next = dev->plug.next;
dev->current_request = next;
if (next) {
if (next || dev->queue) {
dev->plug.next = NULL;
(dev->request_fn)();
}
......@@ -111,6 +121,8 @@ void unplug_device(void * data)
*/
static inline void plug_device(struct blk_dev_struct * dev)
{
if (dev->current_request)
return;
dev->current_request = &dev->plug;
queue_task_irq_off(&dev->plug_tq, &tq_disk);
}
......@@ -233,7 +245,7 @@ static inline void drive_stat_acct(int cmd, unsigned long nr_sectors,
void add_request(struct blk_dev_struct * dev, struct request * req)
{
struct request * tmp;
struct request * tmp, **current_request;
short disk_index;
switch (MAJOR(req->rq_dev)) {
......@@ -255,12 +267,14 @@ void add_request(struct blk_dev_struct * dev, struct request * req)
}
req->next = NULL;
current_request = get_queue(req->rq_dev);
cli();
if (req->bh)
mark_buffer_clean(req->bh);
if (!(tmp = dev->current_request)) {
dev->current_request = req;
(dev->request_fn)();
if (!(tmp = *current_request)) {
*current_request = req;
if (dev->current_request != &dev->plug)
(dev->request_fn)();
sti();
return;
}
......@@ -358,7 +372,7 @@ static void make_request(int major,int rw, struct buffer_head * bh)
* Try to coalesce the new request with old requests
*/
cli();
req = blk_dev[major].current_request;
req = *get_queue(bh->b_rdev);
if (!req) {
/* MD and loop can't handle plugging without deadlocking */
if (major != MD_MAJOR && major != LOOP_MAJOR)
......@@ -378,7 +392,8 @@ static void make_request(int major,int rw, struct buffer_head * bh)
* All other drivers need to jump over the first entry, as that
* entry may be busy being processed and we thus can't change it.
*/
req = req->next;
if (req == blk_dev[major].current_request)
req = req->next;
if (!req)
break;
/* fall through */
......@@ -614,6 +629,7 @@ int blk_dev_init(void)
for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) {
dev->request_fn = NULL;
dev->queue = NULL;
dev->current_request = NULL;
dev->plug.rq_status = RQ_INACTIVE;
dev->plug.cmd = -1;
......@@ -643,6 +659,9 @@ int blk_dev_init(void)
#ifdef CONFIG_BLK_DEV_HD
hd_init();
#endif
#ifdef CONFIG_BLK_DEV_PS2
ps2esdi_init();
#endif
#ifdef CONFIG_BLK_DEV_XD
xd_init();
#endif
......
This diff is collapsed.
......@@ -1979,8 +1979,7 @@ sony_get_subchnl_info(long arg)
return -EIO;
}
err = verify_area(VERIFY_READ, (char *) arg, sizeof(schi)) ||
verify_area(VERIFY_WRITE, (char *) arg, sizeof(schi));
err = verify_area(VERIFY_WRITE, (char *) arg, sizeof(schi));
if (err) return err;
copy_from_user(&schi, (char *) arg, sizeof(schi));
......
Wed Dec 4 07:51:52 1996 Theodre Ts'o <tytso@localhost.mit.edu>
* serial.c (change_speed): Use save_flags(); cli() and
restore_flags() in order to ensure we don't accidentally
turn on interrupts when starting up the port.
(startup): Move the insertion of serial structure into the
IRQ chain earlier into the startup processing. Interrupts
should be off this whole time, but we eventually will want
to reduce this window.
Thu Nov 21 10:05:22 1996 Theodre Ts'o <tytso@localhost.mit.edu>
* tty_ioctl.c (tty_wait_until_sent): Always check the driver
wait_until_ready routine, even if there are no characters
in the xmit buffer. (There may be charactes in the device
FIFO.)
(n_tty_ioctl): Add new flag tty->flow_stopped which
indicates whether the tty is stopped due to a request by
the TCXONC ioctl (used by tcflow). If so, don't let an
incoming XOFF character restart the tty. The tty can only
be restarted by another TCXONC request.
* tty_io.c (start_tty): Don't allow the tty to be restarted if
tty->flow_stopped is true.
* n_tty.c (n_tty_receive_char): If tty->flow_stopped is true, and
IXANY is set, don't eat a character trying to restart the
tty.
* serial.c (startup): Remove need for MCR_noint from the
async_struct structure. Only turn on DTR and RTS if the
baud rate is not zero.
(change_speed): More accurately calculate the timeout
value based on the word size. Move responsibility of
hangup when speed becomes B0 to rs_set_termios()
(set_serial_info): When changing the UART type set the
current xmit_fifo_size as well as the permanent
xmit_fifo_size.
(rs_ioctl): Fix TCSBRK (used by tcdrain) and TCSBRKP
ioctls to return EINTR if interrupted by a signal.
(rs_set_termios): If the baud rate changes to or from B0,
this function is now responsible for setting or clearing
DTR and RTS. DTR and RTS are only be changed on the
transition to or from the B0 state.
(rs_close): Wait for the characters to drain based on
info->timeout. At low baud rates (50bps), it may take a
long time for the FIFO to completely drain out!
(rs_wait_until_sent): Fixed timeout handling. Now
releases control to the scheduler, but checks frequently
enough so that the function is sensitive enough to pass
the timing requirements of the NIST-PCTS.
(block_til_ready): When opening the device, don't turn on
DTR and RTS if the baud rate is B0.
Thu Nov 14 00:06:09 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c (autoconfig): Fix autoconfiguration problems;
......
......@@ -13,6 +13,11 @@ if [ "$CONFIG_STALDRV" = "y" ]; then
tristate ' Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION
fi
tristate 'SDL RISCom/8 card support' CONFIG_RISCOM8
tristate 'Hayes ESP serial port support' CONFIG_ESP
if [ "$CONFIG_ESP" = "y" -o "$CONFIG_ESP" = "m" ]; then
int ' DMA channel' CONFIG_ESP_DMA_CHANNEL 1
int ' FIFO trigger level' CONFIG_ESP_TRIGGER_LEVEL 768
fi
tristate 'Parallel printer support' CONFIG_PRINTER
......@@ -27,18 +32,25 @@ if [ "$CONFIG_MOUSE" = "y" ]; then
fi
fi
bool 'Support for user misc device modules' CONFIG_UMISC
if [ "$CONFIG_MODULES" = "y" ]; then
bool 'Support for user misc device modules' CONFIG_UMISC
fi
bool 'QIC-02 tape support' CONFIG_QIC02_TAPE
if [ "$CONFIG_QIC02_TAPE" = "y" ]; then
bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF
if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then
tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE
if [ "$CONFIG_QIC02_TAPE" = "y" -o "$CONFIG_QIC02_TAPE" = "m" ]; then
if [ "$CONFIG_QIC02_TAPE" = "y" ]; then
bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF
if [ "$CONFIG_QIC02_DYNCONF" = "y" ]; then
comment 'Setting runtime QIC-02 configuration is done with qic02conf'
comment 'from the tpqic02-support package. It is available at'
comment 'ftp://titus.cfw.com/pub/Linux/util/'
else
comment 'Edit configuration parameters in ./include/linux/tpqic02.h!'
fi
fi
if [ "$CONFIG_QIC02_TAPE" = "m" ]; then
comment 'Edit configuration parameters in ./include/linux/tpqic02.h!'
else
comment 'Setting runtime QIC-02 configuration is done with qic02conf'
comment 'from the tpqic02-support package. It is available at'
comment 'ftp://titus.cfw.com/pub/Linux/util/'
fi
fi
fi
tristate 'Ftape (QIC-80/Travan) support' CONFIG_FTAPE
......@@ -67,6 +79,11 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then
tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG
fi
tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
if [ "$CONFIG_PCWATCHDOG" != "n" ]; then
bool ' Support for Revision A cards' CONFIG_PCWD_REV_A
bool ' Support for Revision C cards' CONFIG_PCWD_REV_C
bool ' Show card state on reset' CONFIG_PCWD_SHOW_PREVSTAT
fi
fi
bool 'Enhanced Real Time Clock Support' CONFIG_RTC
endmenu
......@@ -78,6 +78,14 @@ else
endif
endif
ifeq ($(CONFIG_ESP),y)
L_OBJS += esp.o
else
ifeq ($(CONFIG_ESP),m)
M_OBJS += esp.o
endif
endif
ifeq ($(CONFIG_ATIXL_BUSMOUSE),y)
M = y
L_OBJS += atixlmouse.o
......@@ -171,7 +179,11 @@ L_OBJS += rtc.o
endif
ifdef CONFIG_QIC02_TAPE
L_OBJS += tpqic02.o
ifeq ($(CONFIG_QIC02_TAPE),m)
M_OBJS += tpqic02.o
else
L_OBJS += tpqic02.o
endif
endif
ifeq ($(CONFIG_FTAPE),y)
......
HAYES ESP DRIVERS VERSION 1.0
Features:
- Uses the enhanced mode of the ESP card, allowing a wider range of
interrupts and features than compatibilty mode
- Uses DMA to transfer data to and from the ESP's FIFOs, reducing CPU load
- Supports primary and secondary ports
The driver can be compiled as a module. The module will be called 'esp.o'.
The IRQs to use can be specified by using the irq= option. The format is:
irq=[0x100],[0x140],[0x180],[0x200],[0x240],[0x280],[0x300],[0x380]
The address in brackets is the base address of the card. The IRQ of
nonexistant cards can be set to 0. If and IRQ of a card that does exist is set
to 0, the driver will attempt to guess at the correct IRQ. For example, to set
the IRQ of the card at address 0x300 to 12, the insmod command would be:
insmod esp irq=0,0,0,0,0,0,12,0
The custom divisor can be set by using the divisor= option. The format is the
same as for the irq= option. Each divisor value is a series of hex digits,
with each digit representing the divisor to use for a corresponding port. The
divisor value is constructed RIGHT TO LEFT. Specifying a nonzero divisor value
will automatically set the spd_cust flag. To calculate the divisor to use for
a certain baud rate, divide the port's base baud (921600) by the desired rate.
For example, to set the divisor of the primary port at 0x300 to 4 and the
divisor of the secondary port at 0x308 to 8, the insmod command would be:
insmod esp divisor=0,0,0,0,0,0,0x84,0
The dma= option can be used to set the DMA channel. The channel can be either
1 or 3. For example, to set the dma channel to 3, the insmod command would be:
insmod esp dma=3
The trigger= option can be used to set the FIFO trigger levels. This specifies
when the ESP card should send an interrupt. Larger values will decrease the
number of interrupts; however, a value too high may result in data loss.
Valid values are 1 through 1015, with 768 being the default. For example, to
set the trigger levels to 512 bytes, the insmod command would be:
insmod esp trigger=512
Multiple options can be listed on the insmod command line by separating each
option with a space. For example:
insmod esp dma=3 trigger=512
The esp module can be automatically loaded when needed. To cause this to
happen, add the following lines to /etc/conf.modules (replacing the last line
with options for your configuration):
alias char-major-57 esp
alias char-major-58 esp
options esp irq=0,0,0,0,0,0,3,0 divisor=0,0,0,0,0,0,0x4,0
You may also need to run 'depmod -a'.
Devices must be created manually. To create the devices, note the output from
the module after it is inserted. The output will appear in the location where
kernel messages usually appear (usually /var/adm/messages). Create two devices
for each 'tty' mentioned, one with major of 57 and the other with major of 58.
The minor number should be the same as the tty number reported. The commands
would be (replace ? with the tty number):
mknod /dev/ttyP? c 57 ?
mknod /dev/cup? c 58 ?
For example, if the following line appears:
Oct 24 18:17:23 techno kernel: ttyP8 at 0x0140 (irq = 3) is an ESP primary port
...two devices should be created:
mknod /dev/ttyP8 c 57 8
mknod /dev/cup8 c 58 8
You may need to set the permissions on the devices:
chmod 666 /dev/ttyP*
chmod 666 /dev/cup*
The ESP module and the serial module should not conflict (they can be used at
the same time). After the ESP module has been loaded the ports on the ESP card
will no longer be accessable by the serial driver.
If I/O errors are experienced when accessing the port, check for IRQ and DMA
conflicts ('cat /proc/interrupts' and 'cat /proc/dma' for a list of IRQs and
DMAs currently in use).
Enjoy!
Andrew J. Robinson <arobinso@nyx.net>
This diff is collapsed.
#ifndef ESP_H
#define ESP_H
#define ESP_IN_MAJOR 57 /* major dev # for dial in */
#define ESP_OUT_MAJOR 58 /* major dev # for dial out */
#define ESPC_SCALE 3
#define UART_ESI_BASE 0x00
#define UART_ESI_SID 0x01
#define UART_ESI_RX 0x02
#define UART_ESI_TX 0x02
#define UART_ESI_CMD1 0x04
#define UART_ESI_CMD2 0x05
#define UART_ESI_STAT1 0x04
#define UART_ESI_STAT2 0x05
#define UART_ESI_RWS 0x07
#define UART_IER_DMA_TMOUT 0x80
#define UART_IER_DMA_TC 0x08
#define ESI_SET_IRQ 0x04
#define ESI_SET_DMA_TMOUT 0x05
#define ESI_SET_SRV_MASK 0x06
#define ESI_SET_ERR_MASK 0x07
#define ESI_SET_FLOW_CNTL 0x08
#define ESI_SET_FLOW_CHARS 0x09
#define ESI_SET_FLOW_LVL 0x0a
#define ESI_SET_TRIGGER 0x0b
#define ESI_SET_RX_TIMEOUT 0x0c
#define ESI_SET_FLOW_TMOUT 0x0d
#define ESI_WRITE_UART 0x0e
#define ESI_READ_UART 0x0f
#define ESI_SET_MODE 0x10
#define ESI_GET_ERR_STAT 0x12
#define ESI_GET_UART_STAT 0x13
#define ESI_GET_RX_AVAIL 0x14
#define ESI_GET_TX_AVAIL 0x15
#define ESI_START_DMA_RX 0x16
#define ESI_START_DMA_TX 0x17
#define ESI_ISSUE_BREAK 0x1a
#define ESI_FLUSH_RX 0x1b
#define ESI_FLUSH_TX 0x1c
#define ESI_SET_BAUD 0x1d
#define ESI_SET_ENH_IRQ 0x1f
#define ESI_SET_REINTR 0x20
#define ESI_SET_PRESCALAR 0x23
#define ESI_NO_COMMAND 0xff
#define STAT_RX_TIMEOUT 0x01
#define STAT_NEED_DMA 0x02
#define ESP_EVENT_WRITE_WAKEUP 0
#define ESP_MAGIC 0x53ee
#define ESP_XMIT_SIZE 4096
struct esp_struct {
int magic;
int baud_base;
int port;
int irq;
int flags; /* defined in tty.h */
int type; /* UART type */
struct tty_struct *tty;
int read_status_mask;
int ignore_status_mask;
int timeout;
int stat_flags;
int custom_divisor;
int close_delay;
unsigned short closing_wait;
unsigned short closing_wait2;
int IER; /* Interrupt Enable Register */
int MCR; /* Modem control register */
int MCR_noint; /* MCR with interrupts off */
unsigned long event;
unsigned long last_active;
int line;
int count; /* # of fd on device */
int blocked_open; /* # of blocked opens */
long session; /* Session of opening process */
long pgrp; /* pgrp of opening process */
unsigned char *xmit_buf;
int xmit_head;
int xmit_tail;
int xmit_cnt;
struct tty_flip_buffer *tty_buf;
struct tq_struct tqueue;
struct tq_struct tqueue_hangup;
struct termios normal_termios;
struct termios callout_termios;
struct wait_queue *open_wait;
struct wait_queue *close_wait;
struct wait_queue *delta_msr_wait;
struct wait_queue *break_wait;
struct async_icount icount; /* kernel counters for the 4 input interrupts */
struct esp_struct *next_port; /* For the linked list */
struct esp_struct *prev_port;
};
#endif /* ESP_H */
......@@ -355,7 +355,8 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
return;
}
if (tty->stopped && I_IXON(tty) && I_IXANY(tty)) {
if (tty->stopped && !tty->flow_stopped &&
I_IXON(tty) && I_IXANY(tty)) {
start_tty(tty);
return;
}
......
This diff is collapsed.
......@@ -270,7 +270,11 @@ static void release_aux(struct inode * inode, struct file * file)
poll_aux_status();
/* reenable kbd bh */
enable_bh(KEYBOARD_BH);
#ifdef CONFIG_MCA
free_irq(AUX_IRQ, inode);
#else
free_irq(AUX_IRQ, NULL);
#endif
MOD_DEC_USE_COUNT;
}
......@@ -319,7 +323,11 @@ static int open_aux(struct inode * inode, struct file * file)
return -EBUSY;
}
queue->head = queue->tail = 0; /* Flush input queue */
#ifdef CONFIG_MCA
if (request_irq(AUX_IRQ, aux_interrupt, MCA_bus ? SA_SHIRQ : 0, "PS/2 Mouse", inode)) {
#else
if (request_irq(AUX_IRQ, aux_interrupt, 0, "PS/2 Mouse", NULL)) {
#endif
aux_count--;
return -EBUSY;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -705,7 +705,7 @@ void stop_tty(struct tty_struct *tty)
void start_tty(struct tty_struct *tty)
{
if (!tty->stopped)
if (!tty->stopped || tty->flow_stopped)
return;
tty->stopped = 0;
if (tty->link && tty->link->packet) {
......@@ -1923,6 +1923,9 @@ int tty_init(void)
panic("Couldn't register /dev/console driver\n");
kbd_init();
#ifdef CONFIG_ESP /* init ESP before rs, so rs doesn't see the port */
esp_init();
#endif
#ifdef CONFIG_SERIAL
rs_init();
#endif
......
......@@ -47,8 +47,7 @@ void tty_wait_until_sent(struct tty_struct * tty, int timeout)
#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
printk("%s wait until sent...\n", tty_name(tty));
#endif
if (!tty->driver.chars_in_buffer ||
!tty->driver.chars_in_buffer(tty))
if (!tty->driver.chars_in_buffer)
return;
add_wait_queue(&tty->write_wait, &wait);
current->counter = 0; /* make us low-priority */
......@@ -462,10 +461,16 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
return retval;
switch (arg) {
case TCOOFF:
stop_tty(tty);
if (!tty->flow_stopped) {
tty->flow_stopped = 1;
stop_tty(tty);
}
break;
case TCOON:
start_tty(tty);
if (tty->flow_stopped) {
tty->flow_stopped = 0;
start_tty(tty);
}
break;
case TCIOFF:
if (STOP_CHAR(tty) != __DISABLED_CHAR)
......
This diff is collapsed.
......@@ -51,8 +51,10 @@
#ifdef CONFIG_WDT501_FAN /* Full board, Fan has no tachometer */
#define FEATUREMAP1 0
#define WDT_OPTION_MASK (WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER|WDIOF_EXTERN1|WDIOF_EXTERN2|WDIOF_FANFAULT)
#else
#define FEATUREMAP1 WDC_SR_FANGOOD
#define WDT_OPTION_MASK (WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER|WDIOF_EXTERN1|WDIOF_EXTERN2)
#endif
#define FEATUREMAP2 0
......@@ -65,6 +67,7 @@
#ifdef CONFIG_WDT_500 /* Minimal board */
#define FEATUREMAP1 (WDC_SR_TGOOD|WDC_SR_FANGOOD)
#define FEATUREMAP2 (WDC_SR_PSUOVER|WDC_SR_PSUUNDR)
#define WDT_OPTION_MASK (WDIOF_OVERHEAT)
#endif
#ifndef FEATUREMAP1
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -59,6 +59,7 @@ struct ei_device {
void (*get_8390_hdr)(struct device *, struct e8390_pkt_hdr *, int);
void (*block_output)(struct device *, int, const unsigned char *, int);
void (*block_input)(struct device *, int, struct sk_buff *, int);
unsigned char mcfilter[8];
unsigned open:1;
unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */
unsigned txing:1; /* Transmit Active */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment