services by normal system calls - this is merely considered normal use
of the kernel, and does *not* fall under the heading of "derived work".
Also note that the GPL below is copyrighted by the Free Software
- Foundation, but the instance of code that it refers to (the linux
+ Foundation, but the instance of code that it refers to (the Linux
kernel) is copyrighted by me and others who actually wrote it.
Linus Torvalds
complexity and indentation level of that function. So, if you have a
conceptually simple function that is just one long (but simple)
case-statement, where you have to do lots of small things for a lot of
-different cases, it's ok to have a longer function.
+different cases, it's OK to have a longer function.
However, if you have a complex function, and you suspect that a
less-than-gifted first-year high-school student might not even
Chapter 6: You've made a mess of it
-That's ok, we all do. You've probably been told by your long-time unix
+That's OK, we all do. You've probably been told by your long-time Unix
user helper that "GNU emacs" automatically formats the C sources for
you, and you've noticed that yes, it does do that, but the defaults it
uses are less than desirable (in fact, they are worse than random
PC/TCP compatibility mode
CONFIG_INET_PCTCP
- If you have been having difficulties telneting to your Linux machine
+ If you have been having difficulties telnetting to your Linux machine
from a DOS system that uses (broken) PC/TCP networking software (all
versions up to OnNet 2.0) over your local ethernet try enabling this
option. Everyone else says N.
# LocalWords: ipppd syncppp RFC MPP VJ downloaded icn NICCY Creatix shmem ufr
# LocalWords: ibp md ARCnet ether encap NDIS arcether ODI Amigas AmiTCP NetBSD
# LocalWords: initrd tue util DES funet des OnNet BIOSP smc Travan Iomega CMS
-# LocalWords: FC DC dc PPA IOMEGA's ppa RNFS FMV Fujitsu ARPD arpd loran layes
+# LocalWords: FC DC dc PPA ppa RNFS FMV Fujitsu ARPD arpd loran layes
# LocalWords: FRAD indiana framerelay DLCI DCLIs Sangoma SDLA mrouted sync sec
# LocalWords: Starmode Metricom MosquitoNet mosquitonet kbit nfsroot Digiboard
-# LocalWords: DIGI Xe Xeve digiboard UMISC touchscreens mtu ethernets HBAs MEX
+# LocalWords: DIGI Xe Xeve digiboard UMISC touchscreens mtu HBAs MEX
# LocalWords: Shifflett netcom js jshiffle WIC DECchip ELCP EtherPower dst RTC
# LocalWords: rtc SMP lp Digi Intl RightSwitch DGRS dgrs AFFS Amiga UFS SDL AP
# LocalWords: Solaris RISCom riscom syncPPP PCBIT pcbit sparc anu au artoo ufs
# LocalWords: Bernd informatik rwth aachen uae affs multihosting bytecode java
# LocalWords: applets applet JDK ncsa cabi SNI Alphatronix readme LANs scarab
# LocalWords: winsock RNIS caltech OSPF honour Honouring Mbit Localtalk DEFRAG
-# LocalWords: localtalk download Packetwin Baycom baycom interwork ascii JNT
+# LocalWords: download Packetwin Baycom baycom interwork ascii JNT
# LocalWords: Camtec proxying indyramp defragment defragmented UDP FAS FASXX
# LocalWords: FastSCSI SIO FDC qlogicfas QLogic qlogicisp setbaycom ife ee LJ
# LocalWords: ethz ch Travelmates ProAudioSpectrum ProAudio SoundMan SB SBPro
where all the addresses actually point to the same thing, it's just seen
through different translations..
-Similarly, on the alpha, the normal translation is
+Similarly, on the Alpha, the normal translation is
physical address: 0
virtual address: 0xfffffc0000000000
bus address: 0x40000000
-(but there are also alpha's where the physical address and the bus address
+(but there are also Alphas where the physical address and the bus address
are the same).
Anyway, the way to look up all these translations, you do
Ok, that just about covers the basics of accessing IO portably. Questions?
Comments? You may think that all the above is overly complex, but one day you
-might find yourself with a 500MHz alpha in front of you, and then you'll be
+might find yourself with a 500 MHz Alpha in front of you, and then you'll be
happy that your driver works ;)
Note that kernel versions 2.0.x (and earlier) mistakenly called the
o Clean up warnings/volatiles.
o Fix load_TR() for non contiguous processor ids
o Iterate over the slave timer requests if one is lost (keep a count per cpu)
-o Distribute irq's (locking present just needs the 82489 to be asked
+o Distribute IRQs (locking present just needs the 82489 to be asked
nicely).
o 486 startup code.
o How to handle mixed FPU/non FPU processors.
README FOR LINUX SONY CDU-535/531 DRIVER
========================================
-This is the the Sony CDU-535 (and 531) driver version 0.7 for Linux.
+This is the Sony CDU-535 (and 531) driver version 0.7 for Linux.
I do not think I have the documentation to add features like DMA support
so if anyone else wants to pursue it or help me with it, please do.
(I need to see what was done for the CDU-31A driver -- perhaps I can
...
The metadisk driver is used to span a
- filesystem across multiple physical disks.
+ file system across multiple physical disks.
10 char Non-serial mice, misc features
0 = /dev/logibm Logitech bus mouse
33 = /dev/patmgr1 Sequencer patch manager
34 = /dev/midi02 Third MIDI port
50 = /dev/midi03 Fourth MIDI port
- block BIOS harddrive callback support
- 0 = /dev/dos_hda First BIOS harddrive whole disk
- 64 = /dev/dos_hdb Second BIOS harddrive whole disk
- 128 = /dev/dos_hdc Third BIOS harddrive whole disk
- 192 = /dev/dos_hdd Fourth BIOS harddrive whole disk
+ block BIOS hard drive callback support
+ 0 = /dev/dos_hda First BIOS hard drive whole disk
+ 64 = /dev/dos_hdb Second BIOS hard drive whole disk
+ 128 = /dev/dos_hdc Third BIOS hard drive whole disk
+ 192 = /dev/dos_hdd Fourth BIOS hard drive whole disk
Partitions are handled in the same way as IDE disks
(see major number 3).
/dev/cdwriter CD-writer symbolic Current CD-writer device
/dev/scanner scanner symbolic Current scanner device
/dev/modem modem port symbolic Current dialout device
-/dev/root root device symbolic Current root filesystem
+/dev/root root device symbolic Current root file system
/dev/swap swap device symbolic Current swap device
/dev/modem should not be used for a modem which supports dialin as
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
+root directory, the Amiga has a separate 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
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
+In all probability the device uses these ports and IRQs if it is attached
to the appropriate ide channel. Pass the parameter for the correct ide
channel to the kernel, as explained above.
Courtesy of Scott Snyder, the driver supports ATAPI cdrom drives
such as the NEC-260 and the new MITSUMI triple/quad speed drives.
-Such drives will be identified at boot time, just like a harddisk.
+Such drives will be identified at boot time, just like a hard disk.
If for some reason your cdrom drive is *not* found at boot time, you can force
the probe to look harder by supplying a kernel command line parameter
or
hdd=cdrom /* hdd = "slave" on second interface */
-For example, a GW2000 system might have a harddrive on the primary
+For example, a GW2000 system might have a hard drive on the primary
interface (/dev/hda) and an IDE cdrom drive on the secondary interface
(/dev/hdc). To mount a CD in the cdrom drive, one would use something like:
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=ide-scsi" : use the ide-scsi driver for hdx
"idebus=xx" : inform IDE driver of VESA/PCI bus speed in Mhz,
where "xx" is between 20 and 66 inclusive,
must reside within the first 1024 cylinders of the drive. If your linux
root partition is *not* completely within the first 1024 cyls (quite common),
then you can use LILO to boot linux from files on your DOS partition
-by doing the following after installing slackware (or whatever):
+by doing the following after installing Slackware (or whatever):
0. Boot from the "boot floppy" created during the installation
1. Mount your DOS partition as /dos (and stick it in /etc/fstab)
command "isdnctrl addphone <InterfaceName> in <caller-id>"
Euro-ISDN does not transmit the leading '0' of the caller-id for an
incoming call, therefore you should configure it accordingly.
- If the real number for the dialout e.g. is "09311234567" the the number
+ If the real number for the dialout e.g. is "09311234567" the number
to configure here is "9311234567". The pattern-match function
works similar to the shell mechanism.
Returns the EAZ of an interface.
"isdnctrl delphone <InterfaceName> in|out <number>"
- Deletes a number from one of the the access-lists of the interface.
+ Deletes a number from one of the access-lists of the interface.
"isdnctrl delif <InterfaceName>"
Removes the interface (and possible slaves) from the kernel.
---------------
The revision 2 Linux driver for SpellCaster ISA ISDN adapters is built
-upon ISDN4Linux available seperately or as included in Linux 2.0 and later.
+upon ISDN4Linux available separately or as included in Linux 2.0 and later.
The driver will support a maximum of 4 adapters in any one system of any
type including DataCommute/BRI, DataCommute/PRI and TeleCommute/BRI for a
maximum of 92 channels for host. The driver is supplied as a module in
the driver and at the same time doubled the number of I/O ports
probed increasing the likelyhood of finding an adapter.
- We now support all ISA adapter models with a single driver instead
- of seperate drivers for each model. The revision 2 driver supports
+ of separate drivers for each model. The revision 2 driver supports
the DataCommute/BRI, DataCommute/PRI and TeleCommute/BRI in any
combination up to a maximum of four adapters per system.
- On board PPP protocol support has been removed in favour of the
tcp.txt
- short blurb on how TCP output takes place.
tulip.txt
- - info on using DEC 21040/21041/21140 based PCI ethernet cards.
+ - info on using DEC 21040/21041/21140 based PCI Ethernet cards.
vortex.txt
- info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) e'net cards.
z8530drv.txt
INTRODUCTION TO ARCNET
----------------------
-ARCnet is a network type which works in a way similar to popular "ethernet"
+ARCnet is a network type which works in a way similar to popular Ethernet
networks but which is also different in some very important ways.
-First of all, you can get ARCnet cards in at least two speeds: 2.5Mbps
-(slower than ethernet) and 100Mbps (faster than normal ethernet). In fact,
+First of all, you can get ARCnet cards in at least two speeds: 2.5 Mbps
+(slower than Ethernet) and 100 Mbps (faster than normal Ethernet). In fact,
there are others as well, but these are less common. The different hardware
types, as far as I'm aware, are not compatible and so you cannot wire a
-100Mbps card to a 2.5Mbps card, and so on. From what I hear, my driver does
-work with 100Mbps cards, but I haven't been able to verify this myself,
-since I only have the 2.5Mbps variety. It is probably not going to saturate
-your 100Mbps card. Stop complaining :)
+100 Mbps card to a 2.5 Mbps card, and so on. From what I hear, my driver does
+work with 100 Mbps cards, but I haven't been able to verify this myself,
+since I only have the 2.5 Mbps variety. It is probably not going to saturate
+your 100 Mbps card. Stop complaining :)
-You also cannot connect an ARCnet card to any kind of ethernet card and
+You also cannot connect an ARCnet card to any kind of Ethernet card and
expect it to work.
There are two "types" of ARCnet - STAR topology and BUS topology. This
Once you get past these little stumbling blocks, ARCnet is actually quite a
well-designed standard. It uses something called "modified token passing"
which makes it completely incompatible with so-called "Token Ring" cards,
-but which makes transfers much more reliable than ethernet does. In fact,
+but which makes transfers much more reliable than Ethernet does. In fact,
ARCnet will guarantee that a packet arrives safely at the destination, and
even if it can't possibly be delivered properly (ie. because of a cable
break, or because the destination computer does not exist) it will at least
In addition, all known ARCnet cards have an (almost) identical programming
interface. This means that with one "arcnet" driver you can support any
-card; whereas, with ethernet, each manufacturer uses what is sometimes a
+card; whereas, with Ethernet, each manufacturer uses what is sometimes a
completely different programming interface, leading to a lot of different,
-sometimes very similar, ethernet drivers. Of course, always using the same
+sometimes very similar, Ethernet drivers. Of course, always using the same
programming interface also means that when high-performance hardware
facilities like PCI busmastering DMA appear, it's hard to take advantage of
them. Let's not go into that.
One thing that makes ARCnet cards difficult to program for, however, is the
limit on their packet sizes; standard ARCnet can only send packets that are
up to 508 bytes in length. This is smaller than the internet "bare minimum"
-of 576 bytes, let alone the ethernet MTU of 1500. To compensate, an extra
+of 576 bytes, let alone the Ethernet MTU of 1500. To compensate, an extra
level of encapsulation is defined by RFC1201, which I call "packet
splitting," that allows "virtual packets" to grow as large as 64K each,
-although they are generally kept down to the ethernet-style 1500 bytes.
+although they are generally kept down to the Ethernet-style 1500 bytes.
For more information on the advantages and disadvantages (mostly the
advantages) of ARCnet networks, you might try the "ARCnet Trade Association"
- Avery's favourite: 0xD0000
- the station address: Every ARCnet card has its own "unique" network
- address from 0 to 255. Unlike ethernet, you can set this address
+ address from 0 to 255. Unlike Ethernet, you can set this address
yourself with a jumper or switch (or on some cards, with special
software). Since it's only 8 bits, you can only have 254 ARCnet cards
on a network. DON'T use 0 or 255, since these are reserved (although
DIP Switches:
- The dipswitches accessible on the accessible end of the card while
+ The DIP switches accessible on the accessible end of the card while
it is installed, is used to set the arcnet address. There are 8
switches. Use an address from 1 to 254.
11111110 1
11111111 0 (Don't use this!)
- There is another dipswitch array of 8 switches at the top of the
+ There is another array of eight DIP switches at the top of the
card. There are five labelled MS0-MS4 which seem to control the
memory address, and another three labelled IO0-IO2 which seem to
control the base I/O address of the card.
Go read the NET-2-HOWTO and ETHERNET-HOWTO for Linux; they should be
available where you picked up this driver. Think of your ARCnet as a
-souped-up (or down, as the case may be) ethernet card.
+souped-up (or down, as the case may be) Ethernet card.
By the way, be sure to change all references from "eth0" to "arc0" in the
-HOWTOs. Remember that ARCnet isn't a "true" ethernet, and the device name
+HOWTOs. Remember that ARCnet isn't a "true" Ethernet, and the device name
is DIFFERENT.
How do I get it to work with...?
--------------------------------
-NFS: Should be fine linux->linux, just pretend you're using ethernet cards.
+NFS: Should be fine Linux->Linux, just pretend you're using Ethernet cards.
oak.oakland.edu:/simtel/msdos/nfs has some nice DOS clients. There
is also a DOS-based NFS server called SOSS. It doesn't multitask
quite the way Linux does (actually, it doesn't multitask AT ALL) but
LAN Manager and Windows for Workgroups: These programs use protocols that
are incompatible with the internet standard. They try to pretend
- the cards are ethernet, and confuse everyone else on the network.
+ the cards are Ethernet, and confuse everyone else on the network.
However, v2.00 and higher of the Linux ARCnet driver supports this
protocol via the 'arc0e' device. See the section on "Multiprotocol
- Tulip ethernet card driver
+ Tulip Ethernet Card Driver
The Tulip driver is developed by Donald Becker and changed by
-Takashi Manabe. This driver is designed to work with PCI ethernet
+Takashi Manabe. This driver is designed to work with PCI Ethernet
cards which use the DECchip DC21x4x family. This driver hopefully
works with all of 1.2.x and 1.3.x kernels, but I tested only
with 1.2.13, 1.3.39, 1.3.49, 1.3.52, 1.3.57 and later.
clock dpll # clock source:
# dpll = normal halfduplex operation
# external = MODEM provides own Rx/Tx clock
- # divider = use fullduplex divider if
+ # divider = use full duplex divider if
# installed (1)
mode nrzi # HDLC encoding mode
# nrzi = 1k2 MODEM, G3RUH 9k6 MODEM
Example: sccparam /dev/scc3 speed 9600
txdelay:
- The delay (in units of 10ms) after keying of the
+ The delay (in units of 10 ms) after keying of the
transmitter, until the first byte is sent. This is usually
called "TXDELAY" in a TNC. When 0 is specified, the driver
will just wait until the CTS signal is asserted. This
slottime:
This is the time between samples of the channel. It is
- expressed in units of 10ms. About 200-300 ms (value 20-30)
+ expressed in units of 10 ms. About 200-300 ms (value 20-30)
seems to be a good value.
Example: sccparam /dev/scc0 slot 20
SCC before the transmitter is keyed down. The value depends
on the baudrate selected. A few character times should be
sufficient, e.g. 40ms at 1200 baud. (value 4)
- The value of this parameter is in 10ms units.
+ The value of this parameter is in 10 ms units.
Example: sccparam /dev/scc2 4
wait:
The initial waittime before any transmit attempt, after the
frame has been queue for transmit. This is the length of
- the first slot in CSMA mode. In fullduplex modes it is
+ the first slot in CSMA mode. In full duplex modes it is
set to 0 for maximum performance.
- The value of this parameter is in 10ms units.
+ The value of this parameter is in 10 ms units.
Example: sccparam /dev/scc1 wait 4
Example: sccparam /dev/scc3 min 10
idle
- This parameter specifies the maximum idle time in fullduplex
+ This parameter specifies the maximum idle time in full duplex
2 mode, in seconds. When no frames have been sent for this
time, the transmitter will be keyed down. A value of 0 is
has same result as the fullduplex mode 1. This parameter
less a value has been received by BOOTP.
<hostname> Name of the client. If empty, the client IP address is
- used in ASCII-notation, or the value received by BOOTP.
+ used in ASCII notation, or the value received by BOOTP.
<device> Name of network device to use. If this is empty, all
devices are used for RARP requests, and the first one
\hfill Alan Cox, 1995
-The author wishes to thank Caldera Inc ( http://www.caldera.com )
-whose donation of an ASUS dual pentium board made this project possible,
+The author wishes to thank Caldera Inc. ( http://www.caldera.com )
+whose donation of an ASUS dual Pentium board made this project possible,
and Thomas Radke, whose initial work on multiprocessor Linux formed
the backbone of this project.
specification places much of the onus for hard work on the chipset and
hardware rather than the operating system.
-The Intel pentium processors have a wide variety of inbuilt facilities for
+The Intel Pentium processors have a wide variety of built-in facilities for
supporting multiprocessing, including hardware cache coherency, built in
interprocessor interrupt handling and a set of atomic test and set,
exchange and similar operations. The cache coherency in particular makes the
The memory management core of the existing Linux system functions
adequately within the multiprocessor framework providing the locking is
used. Certain processor specific areas do need changing, in particular
-invalidate() must invalidate the TLB's of all processors before it returns.
+invalidate() must invalidate the TLBs of all processors before it returns.
\subsubsection{Miscellaneous Functions}
extensions to standard kernel facilities to cope with multiple processors.
\subsubsection{Initialisation}
-The intel MP architecture captures all the processors except for a single
+The Intel MP architecture captures all the processors except for a single
processor known as the 'boot processor' in the BIOS at boot time. Thus a
single processor enters the kernel bootup code. The first processor
executes the bootstrap code, loads and uncompresses the kernel. Having
appropriately. From then on the real APIC logical identity register is
read.
-Message passing is accomplished using a pair of IPI's on interrupt 13
-(unused by the 80486 FPU's in SMP mode) and interrupt 16. Two are used in
+Message passing is accomplished using a pair of IPIs on interrupt 13
+(unused by the 80486 FPUs in SMP mode) and interrupt 16. Two are used in
order to separate messages that cannot be processed until the receiver
obtains the kernel spinlock from messages that can be processed
immediately. In effect IRQ 13 is a fast IRQ handler that does not obtain
VERSION = 2
PATCHLEVEL = 0
-SUBLEVEL = 34
+SUBLEVEL = 35
ARCH = i386
* Alpha implementation of the PCI interface:
*
* In sparse memory address space, the first
- * octant (16MB) of every 128MB segment is
- * aliased to the the very first 16MB of the
+ * octant (16 MB) of every 128 MB segment is
+ * aliased to the very first 16 MB of the
* address space (i.e., it aliases the ISA
* memory address space). Thus, we try to
* avoid allocating PCI devices in that range.
* Can be allocated in 2nd-7th octant only.
- * Devices that need more than 112MB of
+ * Devices that need more than 112 MB of
* address space must be accessed through
* dense memory space only!
*/
* FPCR_INV if invalid operation occurred, etc.
*/
unsigned long
-ieee_CVTTQ (int f, unsigned long a, unsigned long *b)
+ieee_CVTTQ (int f, unsigned long a, unsigned long *pb)
{
unsigned int midway;
- unsigned long ov, uv, res = 0;
+ unsigned long ov, uv, res, b;
fpclass_t a_type;
EXTENDED temp;
- *b = 0;
a_type = extend_ieee(a, &temp, DOUBLE);
+
+ b = 0x7fffffffffffffff;
+ res = FPCR_INV;
if (a_type == NaN || a_type == INFTY)
- return FPCR_INV;
+ goto out;
+
+ res = 0;
if (a_type == QNaN)
- return 0;
+ goto out;
if (temp.e > 0) {
ov = 0;
if (ov || (temp.f[1] & 0xffc0000000000000))
res |= FPCR_IOV | FPCR_INE;
}
- if (temp.e < 0) {
+ else if (temp.e < 0) {
while (temp.e < 0) {
++temp.e;
uv = temp.f[0] & 1; /* save sticky bit */
temp.f[0] |= uv;
}
}
- *b = ((temp.f[1] << 9) | (temp.f[0] >> 55)) & 0x7fffffffffffffff;
+ b = (temp.f[1] << 9) | (temp.f[0] >> 55);
+
/*
* Notice: the fraction is only 52 bits long. Thus, rounding
* cannot possibly result in an integer overflow.
break;
case ROUND_PINF:
- if ((temp.f[0] & 0x003fffffffffffff) != 0)
+ if ((temp.f[0] & 0x007fffffffffffff) != 0)
++b;
break;
case ROUND_NINF:
- if ((temp.f[0] & 0x003fffffffffffff) != 0)
+ if ((temp.f[0] & 0x007fffffffffffff) != 0)
--b;
break;
/* no action needed */
break;
}
- if ((temp.f[0] & 0x003fffffffffffff) != 0)
+ if ((temp.f[0] & 0x007fffffffffffff) != 0)
res |= FPCR_INE;
if (temp.s) {
- *b = -*b;
+ b = -b;
}
+
+out:
+ *pb = b;
return res;
}
static const char * i586model(unsigned int nr)
{
static const char *model[] = {
- "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83"
+ "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83",
+ "Pentium MMX", NULL, NULL, "Mobile Pentium 75+",
+ "Mobile Pentium MMX"
};
if (nr < sizeof(model)/sizeof(char *))
return model[nr];
/* ++roman:
*
* New version of ST-Ram buffer allocation. Instead of using the
- * 1 MB - 4 KB that remain when the the ST-Ram chunk starts at $1000
+ * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000
* (1 MB granularity!), such buffers are reserved like this:
*
* - If the kernel resides in ST-Ram anyway, we can take the buffer
|
| Input: a0 points to a normalized number in internal extended format
| d0 is the round precision (=1 for sgl; =2 for dbl)
-| d1 is the the single precision or double precision
+| d1 is the single precision or double precision
| denorm threshold
|
| Output: (In the format for dest_sgl or dest_dbl)
| result is provably monotonic in double precision.
|
| Speed: The program slogn takes approximately 190 cycles for input
-| argument X such that |X-1| >= 1/16, which is the the usual
+| argument X such that |X-1| >= 1/16, which is the usual
| situation. For those arguments, slognp1 takes approximately
| 210 cycles. For the less common arguments, the program will
| run no worse than 10% slower.
| result is provably monotonic in double precision.
|
| Speed: The programs sSIN and sCOS take approximately 150 cycles for
-| input argument X such that |X| < 15Pi, which is the the usual
+| input argument X such that |X| < 15Pi, which is the usual
| situation. The speed for sSINCOS is approximately 190 cycles.
|
| Algorithm:
| result is provably monotonic in double precision.
|
| Speed: The program sTAN takes approximately 170 cycles for
-| input argument X such that |X| < 15Pi, which is the the usual
+| input argument X such that |X| < 15Pi, which is the usual
| situation.
|
| Algorithm:
|
| Takes the result and puts it in where the user expects it.
| Library functions return result in fp0. If fp0 is not the
-| users destination register then fp0 is moved to the the
+| user's destination register then fp0 is moved to the
| correct floating-point destination register. fp0 and fp1
| are then restored to the original contents.
|
return;
} else {
/*
- * move this descriptor the the front of the list, since
+ * move this descriptor to the front of the list, since
* it has one or more free tables.
*/
save_flags(flags);
bnz srmmu_nviking ! is in mbus mode
nop
- rd %psr, %g3 ! DONT TOUCH %g3
+ rd %psr, %g3 ! DO NOT TOUCH %g3
andn %g3, PSR_ET, %g2
wr %g2, 0x0, %psr
WRITE_PAUSE
set AC_M_CTPR, %g4
lda [%g4] ASI_M_MMUREGS, %g4
sll %g4, 0x4, %g4 ! We use this below
- ! DONT TOUCH %g4
+ ! DO NOT TOUCH %g4
/* Set the AC bit in the Viking's MMU control reg. */
- lda [%g0] ASI_M_MMUREGS, %g5 ! DONT TOUCH %g5
+ lda [%g0] ASI_M_MMUREGS, %g5 ! DO NOT TOUCH %g5
set 0x8000, %g6 ! AC bit mask
or %g5, %g6, %g6 ! Or it in...
sta %g6, [%g0] ASI_M_MMUREGS ! Close your eyes...
* No, it doesn't work, have to play the save/readCWP/restore trick.
*/
- wr %g0, 0x0, %wim ! so we dont get a trap
+ wr %g0, 0x0, %wim ! so we do not get a trap
WRITE_PAUSE
save
#define DEVICE_BUSY busy[target]
#define USAGE access_count[target]
#define CAPACITY (bios_info[target].head*bios_info[target].sect*bios_info[target].cyl)
-/* We assume that the the bios parameters do not change, so the disk capacity
+/* We assume that the BIOS parameters do not change, so the disk capacity
will not change */
#undef MAYBE_REINIT
#define GENDISK_STRUCT hd_gendisk
case CDROMREADMODE2: {
struct cdrom_msf msf;
int blocksize, format, stat, lba;
- struct atapi_toc *toc;
char *buf;
if (cmd == CDROMREADMODE1) {
/*
- * linux/drivers/block/ide-floppy.c Version 0.7 - ALPHA Aug 4, 1997
+ * linux/drivers/block/ide-floppy.c Version 0.71 - ALPHA May 21, 1998
*
* Copyright (C) 1996, 1997 Gadi Oxman <gadio@netvision.net.il>
*/
* Fix potential null dereferencing with DEBUG_LOG.
* Ver 0.6 Jul 3 97 Limit max sectors per read/write command to 64.
* Ver 0.7 Aug 4 97 Increase irq timeout from 10 to 100 seconds.
+ * Ver 0.71 May 21 98 Disallow opening a write protected media for writing
+ * Limit max sectors only on IOMEGA ZIP 21.D
+ * Issue START cmd only if TEST_UNIT_READY fails
+ * Add CDROMEJECT ioctl
+ * Clean up error messages a bit
*/
#include <linux/config.h>
#include <linux/hdreg.h>
#include <linux/genhd.h>
#include <linux/malloc.h>
+#include <linux/cdrom.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
*/
#define IDEFLOPPY_PC_STACK (10 + IDEFLOPPY_MAX_PC_RETRIES)
-/*
- * Some drives fail read/write requests with 64 or more sectors.
- */
-#define IDEFLOPPY_MAX_SECTORS 64
+#define IDEFLOPPY_MAX_SECTORS 256
/*
* Some drives require a longer irq timeout.
int blocks, block_size, bs_factor; /* Current format */
idefloppy_capacity_descriptor_t capacity; /* Last format capacity */
idefloppy_flexible_disk_page_t flexible_disk_page; /* Copy of the flexible disk page */
+ int wp;
+ int max_sectors;
unsigned int flags; /* Status/Action flags */
} idefloppy_floppy_t;
pc->c[4] = start;
}
+static void idefloppy_create_test_unit_ready_cmd (idefloppy_pc_t *pc)
+{
+ idefloppy_init_pc (pc);
+ pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD;
+}
+
static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector)
{
int block = sector / floppy->bs_factor;
- int blocks = IDEFLOPPY_MIN(rq->nr_sectors / floppy->bs_factor, IDEFLOPPY_MAX_SECTORS);
+ int blocks = IDEFLOPPY_MIN(rq->nr_sectors, floppy->max_sectors) / floppy->bs_factor;
#if IDEFLOPPY_DEBUG_LOG
printk ("create_rw1%d_cmd: block == %d, blocks == %d\n",
return 1;
}
header = (idefloppy_mode_parameter_header_t *) pc.buffer;
+ floppy->wp = header->wp;
page = (idefloppy_flexible_disk_page_t *) (header + 1);
page->transfer_rate = ntohs (page->transfer_rate);
drive->bios_sect = page->sectors;
lba_capacity = floppy->blocks * floppy->block_size;
if (capacity != lba_capacity) {
- printk (KERN_NOTICE "%s: The drive reports both %d and %d bytes as its capacity\n",
- drive->name, capacity, lba_capacity);
+ if (!lba_capacity)
+ printk(KERN_NOTICE "%s: no media in the drive\n");
+ else printk (KERN_NOTICE "%s: The drive reports both %d and %d bytes as its capacity\n",
+ drive->name, capacity, lba_capacity);
capacity = IDEFLOPPY_MIN(capacity, lba_capacity);
floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0;
}
int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ idefloppy_pc_t pc;
+
+ if (cmd == CDROMEJECT) {
+ if (drive->usage > 1)
+ return -EBUSY;
+ idefloppy_create_prevent_cmd (&pc, 0);
+ (void) idefloppy_queue_pc_tail (drive, &pc);
+ idefloppy_create_start_stop_cmd (&pc, 2);
+ (void) idefloppy_queue_pc_tail (drive, &pc);
+ return 0;
+ }
return -EIO;
}
MOD_INC_USE_COUNT;
if (drive->usage == 1) {
- idefloppy_create_start_stop_cmd (&pc, 1);
- (void) idefloppy_queue_pc_tail (drive, &pc);
+ idefloppy_create_test_unit_ready_cmd(&pc);
+ if (idefloppy_queue_pc_tail(drive, &pc)) {
+ idefloppy_create_start_stop_cmd (&pc, 1);
+ (void) idefloppy_queue_pc_tail (drive, &pc);
+ }
if (idefloppy_get_capacity (drive)) {
drive->usage--;
MOD_DEC_USE_COUNT;
return -EIO;
}
+ if (floppy->wp && (filp->f_mode & 2)) {
+ drive->usage--;
+ MOD_DEC_USE_COUNT;
+ return -EROFS;
+ }
set_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
idefloppy_create_prevent_cmd (&pc, 1);
(void) idefloppy_queue_pc_tail (drive, &pc);
return 0;
}
-/*
- * idefloppy_get_capabilities asks the floppy about its various
- * parameters.
- */
-static void idefloppy_get_capabilities (ide_drive_t *drive)
-{
- idefloppy_pc_t pc;
- idefloppy_mode_parameter_header_t *header;
- idefloppy_capabilities_page_t *capabilities;
-
- idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_CAPABILITIES_PAGE, MODE_SENSE_CURRENT);
- if (idefloppy_queue_pc_tail (drive,&pc)) {
- printk (KERN_ERR "ide-floppy: Can't get drive capabilities\n");
- return;
- }
- header = (idefloppy_mode_parameter_header_t *) pc.buffer;
- capabilities = (idefloppy_capabilities_page_t *) (header + 1);
-
- if (!capabilities->sflp)
- printk (KERN_INFO "%s: Warning - system floppy device bit is not set\n", drive->name);
-
-#if IDEFLOPPY_DEBUG_INFO
- printk (KERN_INFO "Dumping the results of the MODE SENSE packet command\n");
- printk (KERN_INFO "Mode Parameter Header:\n");
- printk (KERN_INFO "Mode Data Length - %d\n",header->mode_data_length);
- printk (KERN_INFO "Medium Type - %d\n",header->medium_type);
- printk (KERN_INFO "WP - %d\n",header->wp);
-
- printk (KERN_INFO "Capabilities Page:\n");
- printk (KERN_INFO "Page code - %d\n",capabilities->page_code);
- printk (KERN_INFO "Page length - %d\n",capabilities->page_length);
- printk (KERN_INFO "PS - %d\n",capabilities->ps);
- printk (KERN_INFO "System Floppy Type device - %s\n",capabilities->sflp ? "Yes":"No");
- printk (KERN_INFO "Supports Reporting progress of Format - %s\n",capabilities->srfp ? "Yes":"No");
- printk (KERN_INFO "Non CD Optical device - %s\n",capabilities->ncd ? "Yes":"No");
- printk (KERN_INFO "Multiple LUN support - %s\n",capabilities->sml ? "Yes":"No");
- printk (KERN_INFO "Total LUN supported - %s\n",capabilities->tlun ? "Yes":"No");
-#endif /* IDEFLOPPY_DEBUG_INFO */
-}
-
/*
* Driver initialization.
*/
floppy->pc = floppy->pc_stack;
if (gcw.drq_type == 1)
set_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags);
-
- idefloppy_get_capabilities (drive);
+ if (strcmp(drive->id->model, "IOMEGA ZIP 100 ATAPI") == 0 &&
+ strcmp(drive->id->fw_rev, "21.D") == 0)
+ floppy->max_sectors = 64;
+ else
+ floppy->max_sectors = IDEFLOPPY_MAX_SECTORS;
(void) idefloppy_get_capacity (drive);
}
/*
- * linux/drivers/block/ide-tape.c Version 1.9 - ALPHA Nov 5, 1996
+ * linux/drivers/block/ide-tape.c Version 1.91 May 21, 1998
*
* Copyright (C) 1995, 1996 Gadi Oxman <gadio@netvision.net.il>
*
* MTTELL was sometimes returning incorrect results.
* Return the real block size in the MTIOCGET ioctl.
* Some error recovery bug fixes.
- *
- * We are currently in an *alpha* stage. The driver is not complete and not
- * much tested. I would strongly suggest to:
- *
- * 1. Connect the tape to a separate interface and irq.
- * 2. Be truly prepared for a kernel crash and the resulting data loss.
- * 3. Don't rely too much on the resulting backups.
- *
- * Other than that, enjoy !
+ * Ver 1.91 May 21 98 Add support for INTERRUPT DRQ devices.
+ * Add "speed == 0" work-around for HP COLORADO 5GB
*
* Here are some words from the first releases of hd.c, which are quoted
* in ide.c and apply here as well:
printk ("ide-tape: The removable flag is not set\n");support=0;
}
- if (gcw.drq_type != 2) {
- printk ("ide-tape: Sorry, DRQ types other than Accelerated DRQ\n");
- printk ("ide-tape: are still not supported by the driver\n");support=0;
- }
-
if (gcw.packet_size != 0) {
printk ("ide-tape: Packet size is not 12 bytes long\n");
if (gcw.packet_size == 1)
{
idetape_tape_t *tape=&(drive->tape);
unsigned int allocation_length;
+ struct idetape_id_gcw gcw;
+
#if IDETAPE_ANTICIPATE_READ_WRITE_DSC
ide_hwif_t *hwif = HWIF(drive);
unsigned long t1, tmid, tn;
tape->chrdev_direction=idetape_direction_none;
tape->reset_issued=0;
tape->pc=&(tape->pc_stack [0]);
-
+
+ *((unsigned short *) &gcw) = drive->id->config;
+ tape->drq_interrupt = (gcw.drq_type == 1) ? 1 : 0;
+
#if IDETAPE_PIPELINE
tape->max_number_of_stages=IDETAPE_MIN_PIPELINE_STAGES;
#else
capabilities->speed=idetape_swap_short (capabilities->speed);
capabilities->buffer_size=idetape_swap_short (capabilities->buffer_size);
+ if (!capabilities->speed) {
+ printk("ide-tape: %s: overriding capabilities->speed (assuming 650KB/sec)\n", drive->name);
+ capabilities->speed = 650;
+ }
+ if (!capabilities->max_speed) {
+ printk("ide-tape: %s: overriding capabilities->max_speed (assuming 650KB/sec)\n", drive->name);
+ capabilities->max_speed = 650;
+ }
+
tape->capabilities=*capabilities; /* Save us a copy */
tape->tape_block_size=capabilities->blk512 ? 512:1024;
#endif /* IDETAPE_DEBUG_LOG */
}
+static void idetape_transfer_pc (ide_drive_t *drive)
+{
+ idetape_tape_t *tape=&(drive->tape);
+ idetape_packet_command_t *pc = tape->pc;
+ idetape_ireason_reg_t ireason;
+
+ if (ide_wait_stat (drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {
+ printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
+ return;
+ }
+ ireason.all=IN_BYTE (IDE_IREASON_REG);
+ if (!ireason.b.cod || ireason.b.io) {
+ printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
+ ide_do_reset (drive);
+ return;
+ }
+ ide_set_handler (drive, &idetape_pc_intr, WAIT_CMD); /* Set the interrupt routine */
+ ide_output_data (drive,pc->c,12/4); /* Send the actual packet */
+}
+
/*
* Packet Command Interface
*
{
idetape_tape_t *tape;
idetape_bcount_reg_t bcount;
- idetape_ireason_reg_t ireason;
int dma_ok=0;
tape=&(drive->tape);
OUT_BYTE (bcount.b.high,IDETAPE_BCOUNTH_REG);
OUT_BYTE (bcount.b.low,IDETAPE_BCOUNTL_REG);
OUT_BYTE (drive->select.all,IDETAPE_DRIVESEL_REG);
-
- ide_set_handler (drive,handler,WAIT_CMD); /* Set the interrupt routine */
- OUT_BYTE (WIN_PACKETCMD,IDETAPE_ATACOMMAND_REG); /* Issue the packet command */
- if (ide_wait_stat (drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { /* Wait for DRQ to be ready - Assuming Accelerated DRQ */
- /*
- * We currently only support tape drives which report
- * accelerated DRQ assertion. For this case, specs
- * allow up to 50us. We really shouldn't get here.
- *
- * ??? Still needs to think what to do if we reach
- * here anyway.
- */
-
- printk ("ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
- return;
- }
-
- ireason.all=IN_BYTE (IDETAPE_IREASON_REG);
- if (!ireason.b.cod || ireason.b.io) {
- printk ("ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
- ide_do_reset (drive);
- return;
- }
-
- ide_output_data (drive,pc->c,12/4); /* Send the actual packet */
+
#ifdef CONFIG_BLK_DEV_TRITON
if ((pc->dma_in_progress=dma_ok)) { /* Begin DMA, if necessary */
pc->dma_error=0;
(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
}
#endif /* CONFIG_BLK_DEV_TRITON */
+
+ if (tape->drq_interrupt) {
+ ide_set_handler (drive, &idetape_transfer_pc, WAIT_CMD);
+ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
+ } else {
+ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
+ idetape_transfer_pc (drive);
+ }
}
/*
idetape_pipeline_stage_t *last_stage; /* New requests will be added to the pipeline here */
int error_in_pipeline_stage; /* Set when an error was detected in one of the pipeline stages */
+ int drq_interrupt;
+
} idetape_tape_t;
/*
* add work-around for BMI drives
* remove "LBA" from boot messages
* Version 5.53.1 add UDMA "CRC retry" support
+ * Version 5.53.2 add Promise/33 auto-detection and DMA support
+ * fix MC_ERR handling
+ * fix mis-detection of NEC cdrom as floppy
+ * issue ATAPI reset and re-probe after "no response"
*
* Some additional driver compile-time options are in ide.h
*
rq->errors = ERROR_MAX;
else if (err & TRK0_ERR) /* help it find track zero */
rq->errors |= ERROR_RECAL;
+ else if (err & MC_ERR)
+ drive->special.b.mc = 1;
}
if ((stat & DRQ_STAT) && rq->cmd != WRITE)
try_to_flush_leftover_data(drive);
return;
}
#endif /* CONFIG_BLK_DEV_PROMISE */
- switch (type) {
+ if (!drive->ide_scsi) switch (type) {
case 0:
if (!strstr(id->model, "oppy") && !strstr(id->model, "poyp") && !strstr(id->model, "ZIP"))
printk("cdrom or floppy?, assuming ");
- if (drive->media != ide_cdrom) {
+ if (drive->media != ide_cdrom && !strstr(id->model, "CD-ROM")) {
#ifdef CONFIG_BLK_DEV_IDEFLOPPY
printk("FLOPPY drive\n");
drive->media = ide_floppy;
{
int rc;
ide_hwif_t *hwif = HWIF(drive);
+ unsigned long timeout;
#ifdef CONFIG_BLK_DEV_IDEATAPI
if (drive->present) { /* avoid waiting for inappropriate probes */
if ((drive->media != ide_disk) && (cmd == WIN_IDENTIFY))
{
if ((rc = try_to_identify(drive,cmd))) /* send cmd and wait */
rc = try_to_identify(drive,cmd); /* failed: try again */
+ if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) {
+ printk("%s: no response (status = 0x%02x), resetting drive\n", drive->name, GET_STAT());
+ delay_50ms();
+ OUT_BYTE (drive->select.all, IDE_SELECT_REG);
+ delay_50ms();
+ OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
+ timeout = jiffies;
+ while ((GET_STAT() & BUSY_STAT) && jiffies < timeout + WAIT_WORSTCASE)
+ delay_50ms();
+ rc = try_to_identify(drive, cmd);
+ }
if (rc == 1)
printk("%s: no response (status = 0x%02x)\n", drive->name, GET_STAT());
(void) GET_STAT(); /* ensure drive irq is clear */
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
"serialize", "autotune", "noautotune",
- "slow", NULL};
+ "slow", "ide-scsi", NULL};
unit = s[2] - 'a';
hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES;
case -8: /* "slow" */
drive->slow = 1;
goto done;
+ case -9: /* "ide-scsi" */
+ drive->ide_scsi = 1;
+ goto done;
case 3: /* cyl,head,sect */
drive->media = ide_disk;
drive->cyl = drive->bios_cyl = vals[0];
#endif /* defined(CONFIG_BLK_DEV_RZ1000) || defined(CONFIG_BLK_DEV_TRITON) */
#endif /* CONFIG_PCI */
+static void ide_probe_promise_20246(void)
+{
+ byte fn, bus;
+ unsigned short io[6], count = 0;
+ unsigned int reg, tmp, i;
+ ide_hwif_t *hwif;
+
+ memset(io, 0, 6 * sizeof(unsigned short));
+ if (pcibios_find_device(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, 0, &bus, &fn))
+ return;
+ printk("ide: Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d\n", bus, fn);
+ for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
+ pcibios_read_config_dword(bus, fn, reg, &tmp);
+ if (tmp & PCI_BASE_ADDRESS_SPACE_IO)
+ io[count++] = tmp & PCI_BASE_ADDRESS_IO_MASK;
+ }
+ for (i = 2; i < 4; i++) {
+ hwif = ide_hwifs + i;
+ if (hwif->chipset == ide_generic) {
+ printk("ide%d: overridden with command line parameter\n", i);
+ return;
+ }
+ tmp = (i - 2) * 2;
+ if (!io[tmp] || !io[tmp + 1]) {
+ printk("ide%d: invalid port address %x, %x -- aborting\n", i, io[tmp], io[tmp + 1]);
+ return;
+ }
+ hwif->io_base = io[tmp];
+ hwif->ctl_port = io[tmp + 1] + 2;
+ hwif->noprobe = 0;
+ }
+#ifdef CONFIG_BLK_DEV_TRITON
+ ide_init_promise (bus, fn, &ide_hwifs[2], &ide_hwifs[3], io[4]);
+#endif /* CONFIG_BLK_DEV_TRITON */
+}
+
/*
* ide_init_pci() finds/initializes "known" PCI IDE interfaces
*
ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, &ide_init_triton, 0);
ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, &ide_init_triton, 0);
#endif /* CONFIG_BLK_DEV_TRITON */
+ ide_probe_promise_20246();
}
#endif /* CONFIG_PCI */
#ifdef CONFIG_BLK_DEV_CMD640
#ifdef CONFIG_BLK_DEV_IDESCSI
void *scsi; /* for ide-scsi.c */
#endif /* CONFIG_BLK_DEV_IDESCSI */
+ byte ide_scsi; /* use ide-scsi driver */
} ide_drive_t;
/*
typedef enum { ide_unknown, ide_generic, ide_triton,
ide_cmd640, ide_dtc2278, ide_ali14xx,
ide_qd6580, ide_umc8672, ide_ht6560b,
- ide_promise }
+ ide_promise, ide_promise_udma }
hwif_chipset_t;
typedef struct hwif_s {
#ifdef CONFIG_BLK_DEV_TRITON
void ide_init_triton (byte, byte);
+void ide_init_promise (byte bus, byte fn, ide_hwif_t *hwif0, ide_hwif_t *hwif1, unsigned short dma);
#endif /* CONFIG_BLK_DEV_TRITON */
* safely use __get_free_page() here instead
* of __get_dma_pages() -- no ISA limitations.
*/
- dmatable = __get_free_page(GFP_KERNEL);
+ dmatable = __get_free_pages(GFP_KERNEL, 1, 0);
}
if (dmatable) {
hwif->dmatable = (unsigned long *) dmatable;
quit: if (rc) printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));
}
+void ide_init_promise (byte bus, byte fn, ide_hwif_t *hwif0, ide_hwif_t *hwif1, unsigned short dma)
+{
+ int rc;
+ unsigned short pcicmd;
+ unsigned int bmiba = 0;
+
+ printk("ide: Enabling DMA for Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d, port 0x%04x\n", bus, fn, dma);
+ if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)) || (pcicmd & 1) == 0 || (pcicmd & 4) == 0)
+ goto abort;
+ if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
+ goto abort;
+ bmiba &= 0xfff0; /* extract port base address */
+ if (bmiba != dma || !bmiba)
+ goto abort;
+ hwif0->chipset = ide_promise_udma;
+ hwif1->chipset = ide_promise_udma;
+ init_triton_dma(hwif0, bmiba);
+ init_triton_dma(hwif1, bmiba + 0x08);
+abort:
+ printk("ide: Promise/33 not configured correctly (BIOS)\n");
+}
* This is a modified version of the CDU-31A device driver (see below).
* Changes were made using documentation for the CDU-531 (which Sony
* assures me is very similar to the 535) and partial disassembly of the
- * DOS driver. I used Minyard's driver and replaced the the CDU-31A
+ * DOS driver. I used Minyard's driver and replaced the CDU-31A
* commands with the CDU-531 commands. This was complicated by a different
* interface protocol with the drive. The driver is still polled.
*
Fri Feb 17 09:34:09 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_interrupt_single, rs_interrupt, rs_interrupt_multi):
- Change the the number of passes made from 64 to be 256,
+ Change the number of passes made from 64 to be 256,
configurable with the #define RS_ISR_PASS_LIMIT.
* serial.c (rs_init, set_serial_info, get_serial_info, rs_close):
* Linux 1.3.85
* 1.1: support user-space standby and suspend, power off after system
* halted, Linux 1.3.98
- * 1.2: When resetting RTC after resume, take care so that the the time
+ * 1.2: When resetting RTC after resume, take care so that the time
* is only incorrect by 30-60mS (vs. 1S previously) (Gabor J. Toth
* <jtoth@princeton.edu>); improve interaction between
* screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
** worth noting that while I'm not sure what this hunk of code is supposed
** to do, it is not present in the serial.c driver. Hmmm. If you know,
** please send me a note. brian@ilinx.com
-** Dont know either what this is supposed to do clameter@waterf.org.
+** Don't know either what this is supposed to do clameter@waterf.org.
*/
if(tty->ldisc.num != ldiscs[N_TTY].num) {
if(tty->ldisc.close)
#include <asm/io.h>
#include <asm/segment.h>
+#include <asm/bitops.h>
#include "kbd_kern.h"
#include "vt_kern.h"
* We also return immediately, which is what was implied within the X
* comments - KDMKTONE doesn't put the process to sleep.
*/
+
+static unsigned int mksound_lock = 0;
+
static void
kd_nosound(unsigned long ignored)
{
- /* disable counter 2 */
- outb(inb_p(0x61)&0xFC, 0x61);
+ /* if sound is being set up, don't turn it off */
+ if (!mksound_lock)
+ /* disable counter 2 */
+ outb(inb_p(0x61)&0xFC, 0x61);
return;
}
if (hz > 20 && hz < 32767)
count = 1193180 / hz;
-
- cli();
- del_timer(&sound_timer);
- if (count) {
- /* enable counter 2 */
- outb_p(inb_p(0x61)|3, 0x61);
- /* set command for counter 2, 2 byte write */
- outb_p(0xB6, 0x43);
- /* select desired HZ */
- outb_p(count & 0xff, 0x42);
- outb((count >> 8) & 0xff, 0x42);
-
- if (ticks) {
- sound_timer.expires = jiffies+ticks;
- add_timer(&sound_timer);
- }
- } else
- kd_nosound(0);
- sti();
+
+ /* ignore multiple simultaneous requests for sound */
+ if (!set_bit(0, &mksound_lock)) {
+ /* set_bit in 2.0.x is same as test-and-set in 2.1.x */
+ del_timer(&sound_timer);
+ if (count) {
+ /* enable counter 2 */
+ outb_p(inb_p(0x61)|3, 0x61);
+ /* set command for counter 2, 2 byte write */
+ outb_p(0xB6, 0x43);
+ /* select desired HZ */
+ outb_p(count & 0xff, 0x42);
+ outb((count >> 8) & 0xff, 0x42);
+
+ if (ticks) {
+ sound_timer.expires = jiffies+ticks;
+ add_timer(&sound_timer);
+ }
+ } else
+ kd_nosound(0);
+
+ mksound_lock = 0;
+ }
return;
}
{
printk(KERN_DEBUG "isdn_net: %s: %s, send ICMP\n",
dev->name, reason);
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0
+ if(skb->proto==htons(ETH_P_IP))
+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0
#if (LINUX_VERSION_CODE < 0x02010f) /* 2.1.15 */
,dev
#endif
PCI cards, with the bus master interface extensively modified to work with
the ISA bus.
-The card is capable of full-bus-master transfers with seperate
+The card is capable of full-bus-master transfers with separate
lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
DEC Tulip and Intel Speedo3.
versions of the FastEtherLink cards. The supported product IDs are
3c590, 3c592, 3c595, 3c597, 3c900, 3c905
-The ISA 3c515 is supported with a seperate driver, 3c515.c, included with
+The ISA 3c515 is supported with a separate driver, 3c515.c, included with
the kernel source or available from
cesdis.gsfc.nasa.gov:/pub/linux/drivers/3c515.html
series. The primary interface is two programmed-I/O FIFOs, with an
alternate single-contiguous-region bus-master transfer (see next).
-The 3c900 "Boomerang" series uses a full-bus-master interface with seperate
+The 3c900 "Boomerang" series uses a full-bus-master interface with separate
lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
DEC Tulip and Intel Speedo3. The first chip version retains a compatible
programmed-I/O interface that will be removed in the 'B' and subsequent
}
/*
- * Handle uncommon interrupt sources. This is a seperate routine to minimize
+ * Handle uncommon interrupt sources. This is a separate routine to minimize
* the cache impact.
*/
static void
-/* drivers/net/eepro100.c: An Intel i82557 ethernet driver for linux. */
+/* drivers/net/eepro100.c: An Intel i82557 Ethernet driver for Linux. */
/*
NOTICE: this version tested with kernels 1.3.72 and later only!
Written 1996-1998 by Donald Becker.
I. Board Compatibility
This device driver is designed for the Intel i82557 "Speedo3" chip, Intel's
-single-chip fast ethernet controller for PCI, as used on the Intel
+single-chip fast Ethernet controller for PCI, as used on the Intel
EtherExpress Pro 100 adapter.
II. Board-specific settings
added asynchronous to the normal transmit queue, so we disable interrupts
whenever the Tx descriptor ring is manipulated.
-A notable aspect of the these special configure commands is that they do
+A notable aspect of these special configure commands is that they do
work with the normal Tx ring entry scavenge method. The Tx ring scavenge
is done at interrupt time using the 'dirty_tx' index, and checking for the
command-complete bit. While the setup frames may have the NoOp command on the
/*
** Clean out the TX and RX queues here (note that one entry
- ** may get added to either the TXD or RX queues if the the TX or RX
+ ** may get added to either the TXD or RX queues if the TX or RX
** just starts processing a packet before the STOP_EWRK3 command
** is received. This will be flushed in the ewrk3_open() call).
*/
*/
#define MAX_RX_PDL 30 /* Card limit = 31 */
-#define MAX_RX_FRAG 2 /* Dont need more... */
+#define MAX_RX_FRAG 2 /* Don't need more... */
#define MAX_TX_PDL 29
#define MAX_TX_FRAG 2 /* Limit = 31 */
for (i = 0; i < MAX_ETH_CARDS; ++i)
if (ethdev_index[i] == NULL) {
sprintf(dev->name, "eth%d", i);
- printk("loading device '%s'...\n", dev->name);
+/* printk("loading device '%s'...\n", dev->name);*/
ethdev_index[i] = dev;
break;
}
*
* Returns:
* No error = 0, else, the stage at which the error
- * occured.
+ * occurred.
* Parms:
* io_base The IO port base address for the
* TLAN device with the EEPROM to
/*
- * Wavelan ISA driver
+ * WaveLAN ISA driver
*
* Jean II - HPLB '96
*
* Reorganisation and extension of the driver.
- * Original copyrigth follow (see also end of this file).
+ * Original copyright follows (also see the end of this file).
* See wavelan.p.h for details.
*/
/************************* MISC SUBROUTINES **************************/
/*
* Subroutines which won't fit in one of the following category
- * (wavelan modem or i82586)
+ * (WaveLAN modem or i82586)
*/
/*------------------------------------------------------------------*/
#undef SC
return((char *) NULL);
-} /* wv_structuct_check */
+} /* wv_struct_check */
#endif /* STRUCT_CHECK */
/********************* HOST ADAPTER SUBROUTINES *********************/
/*
- * Usefull subroutines to manage the wavelan ISA interface
+ * Useful subroutines to manage the WaveLAN ISA interface
*
- * One major difference with the Pcmcia hardware (exept the port mapping)
+ * One major difference with the PCMCIA hardware (except the port mapping)
* is that we have to keep the state of the Host Control Register
* because of the interrupt enable & bus size flags.
*/
/*------------------------------------------------------------------*/
/*
- * Disable interrupts on the wavelan hardware
+ * Disable interrupts on the WaveLAN hardware
*/
static inline void
wv_ints_off(device * dev)
/*------------------------------------------------------------------*/
/*
- * Enable interrupts on the wavelan hardware
+ * Enable interrupts on the WaveLAN hardware
*/
static inline void
wv_ints_on(device * dev)
/******************* MODEM MANAGEMENT SUBROUTINES *******************/
/*
- * Usefull subroutines to manage the modem of the wavelan
+ * Useful subroutines to manage the modem of the WaveLAN
*/
/*------------------------------------------------------------------*/
/*------------------------------------------------------------------*/
/*
* Calculate the PSA CRC (not tested yet)
- * As the Wavelan drivers don't use the CRC, I won't use it either...
+ * As the WaveLAN drivers don't use the CRC, I won't use it either.
* Thanks to Valster, Nico <NVALSTER@wcnd.nl.lucent.com> for the code
* NOTE: By specifying a length including the CRC position the
* returned value should be zero. (i.e. a correct checksum in the PSA)
/*------------------------------------------------------------------*/
/*
- * Wait for the frequency EEprom to complete a command...
+ * Wait for the frequency EEPROM to complete a command...
* I hope this one will be optimally inlined...
*/
static inline void
/*------------------------------------------------------------------*/
/*
- * Read bytes from the Frequency EEprom (frequency select cards).
+ * Read bytes from the frequency EEPROM (frequency select cards).
*/
static void
fee_read(u_long ioaddr, /* i/o port of the card */
/* Write the read command */
mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_READ);
- /* Wait until EEprom is ready (should be quick !) */
+ /* Wait until EEPROM is ready (should be quick!) */
fee_wait(ioaddr, 10, 100);
/* Read the value */
/*------------------------------------------------------------------*/
/*
- * Write bytes from the Frequency EEprom (frequency select cards).
- * This is a bit complicated, because the frequency eeprom has to
+ * Write bytes from the Frequency EEPROM (frequency select cards).
+ * This is a bit complicated, because the frequency EEPROM has to
* be unprotected and the write enabled.
* Jean II
*/
fee_wait(ioaddr, 10, 100);
- /* Write the EEprom address */
+ /* Write the EEPROM address */
mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);
/* Loop on all buffer */
fee_wait(ioaddr, 10, 100);
#ifdef EEPROM_IS_PROTECTED /* disabled */
- /* Reprotect EEprom */
+ /* Reprotect EEPROM */
mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x00);
mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
static void
wv_psa_show(psa_t * p)
{
- printk(KERN_DEBUG "##### wavelan psa contents: #####\n");
+ printk(KERN_DEBUG "##### WaveLAN psa contents: #####\n");
printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
p->psa_io_base_addr_1,
p->psa_io_base_addr_2,
lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
#endif /* WIRELESS_EXT */
- printk(KERN_DEBUG "##### wavelan modem status registers: #####\n");
+ printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
#ifdef DEBUG_SHOW_UNUSED
printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
m.mmr_unused0[0],
obram_read(ioaddr, OFFSET_SCB, (unsigned char *)&scb, sizeof(scb));
- printk(KERN_DEBUG "##### wavelan system control block: #####\n");
+ printk(KERN_DEBUG "##### WaveLAN system control block: #####\n");
printk(KERN_DEBUG "status: ");
printk("stat 0x%x[%s%s%s%s] ",
{
/* net_local *lp = (net_local *) dev->priv; */
- printk(KERN_DEBUG "##### wavelan i82586 receiver unit status: #####\n");
+ printk(KERN_DEBUG "##### WaveLAN i82586 receiver unit status: #####\n");
printk(KERN_DEBUG "ru:");
/*
* Not implemented yet...
unsigned int i;
u_short p;
- printk(KERN_DEBUG "##### wavelan i82586 command unit status: #####\n");
+ printk(KERN_DEBUG "##### WaveLAN i82586 command unit status: #####\n");
printk(KERN_DEBUG);
for(i = 0, p = lp->tx_first_in_use; i < NTXBLOCKS; i++)
{
unsigned short freq;
- /* Ask the EEprom to read the frequency from the first area */
+ /* Ask the EEPROM to read the frequency from the first area */
fee_read(ioaddr, 0x00 /* 1st area - frequency... */,
&freq, 1);
#endif
/* Setting by frequency */
- /* Theoritically, you may set any frequency between
+ /* Theoretically, you may set any frequency between
* the two limits with a 0.5 MHz precision. In practice,
* I don't want you to have trouble with local
* regulations... */
unsigned short area_verify[16];
unsigned short dac_verify[2];
/* Corresponding gain (in the power adjust value table)
- * see AT&T Wavelan Data Manual, REF 407-024689/E, page 3-8
+ * see AT&T WaveLAN Data Manual, REF 407-024689/E, page 3-8
* & WCIN062D.DOC, page 6.2.9 */
unsigned short power_limit[] = { 40, 80, 120, 160, 0 };
int power_band = 0; /* Selected band */
power_adjust &= 0xFF;
#ifdef DEBUG_IOCTL_INFO
- printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
+ printk(KERN_DEBUG "WaveLAN EEPROM Area 1:");
for(i = 0; i < 16; i++)
{
printk(" %04X",
}
printk("\n");
- printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
+ printk(KERN_DEBUG "WaveLAN EEPROM DAC: %04X %04X\n",
dac[0], dac[1]);
#endif
- /* Frequency offset (for info only...) */
+ /* Frequency offset (for info only) */
area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);
/* Receiver Principle main divider coefficient */
/* Others part of the area are flags, bit streams or unused... */
- /* Set the value in the DAC */
+ /* Set the value in the DAC. */
dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);
dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);
- /* Write the first area */
+ /* Write the first area. */
fee_write(ioaddr, 0x00,
area, 16);
- /* Write the DAC */
+ /* Write the DAC. */
fee_write(ioaddr, 0x60,
dac, 2);
- /* We now should verify here that the EEprom writting was ok */
+ /* We now should verify here that the EEPROM writing was OK. */
- /* ReRead the first area */
+ /* Reread the first area. */
fee_read(ioaddr, 0x00,
area_verify, 16);
memcmp(dac, dac_verify, 2 * 2))
{
#ifdef DEBUG_IOCTL_ERROR
- printk(KERN_INFO "Wavelan: wv_set_frequency : unable to write new frequency to EEprom (??)\n");
+ printk(KERN_INFO "WaveLAN: wv_set_frequency: unable to write new frequency to EEPROM(?).\n");
#endif
return -EOPNOTSUPP;
}
/* We must download the frequency parameters to the
- * synthetisers (from the EEprom - area 1)
- * Note : as the EEprom is auto decremented, we set the end
+ * synthesizers (from the EEPROM - area 1)
+ * Note: as the EEPROM is automatically decremented, we set the end
* if the area... */
mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x0F);
mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
fee_wait(ioaddr, 100, 100);
/* We must now download the power adjust value (gain) to
- * the synthetisers (from the EEprom - area 7 - DAC) */
+ * the synthesizers (from the EEPROM - area 7 - DAC) */
mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x61);
mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
#ifdef DEBUG_IOCTL_INFO
/* Verification of what we have done... */
- printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
+ printk(KERN_DEBUG "WaveLAN EEPROM Area 1:");
for(i = 0; i < 16; i++)
{
printk(" %04X",
}
printk("\n");
- printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
+ printk(KERN_DEBUG "WaveLAN EEPROM DAC: %04X %04X\n",
dac_verify[0], dac_verify[1]);
#endif
#ifdef HISTOGRAM
/*------------------------------------------------------------------*/
/*
- * This function calculate an histogram on the signal level.
+ * This function calculates an histogram on the signal level.
* As the noise is quite constant, it's like doing it on the SNR.
* We have defined a set of interval (lp->his_range), and each time
* the level goes in that interval, we increment the count (lp->his_sum).
- * With this histogram you may detect if one wavelan is really weak,
- * or you may also calculate the mean and standard deviation of the level...
+ * With this histogram you may detect if one WaveLAN is really weak,
+ * or you may also calculate the mean and standard deviation of the level.
*/
static inline void
wl_his_gather(device * dev,
* This is here that are treated the wireless extensions (iwconfig)
*/
static int
-wavelan_ioctl(struct device * dev, /* Device on wich the ioctl apply */
- struct ifreq * rq, /* Data passed */
- int cmd) /* Ioctl number */
+wavelan_ioctl(struct device * dev, /* device on which the ioctl is applied */
+ struct ifreq * rq, /* data passed */
+ int cmd) /* ioctl number */
{
u_long ioaddr = dev->base_addr;
net_local * lp = (net_local *)dev->priv; /* lp is not unused */
break;
case SIOCSIWNWID:
- /* Set NWID in wavelan */
+ /* Set NWID in WaveLAN */
if(wrq->u.nwid.on)
{
/* Set NWID in psa */
{
unsigned short freq;
- /* Ask the EEprom to read the frequency from the first area */
+ /* Ask the EEPROM to read the frequency from the first area */
fee_read(ioaddr, 0x00 /* 1st area - frequency... */,
&freq, 1);
wrq->u.freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
break;
case SIOCGIWRANGE:
- /* Basic checking... */
+ /* basic checking */
if(wrq->u.data.pointer != (caddr_t) 0)
{
struct iw_range range;
range.min_nwid = 0x0000;
range.max_nwid = 0xFFFF;
- /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) */
+ /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
if(!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
(MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
{
ret = -EOPNOTSUPP;
}
- /* ReEnable interrupts & restore flags */
+ /* Enable interrupts, restore flags */
wv_splx(x);
#ifdef DEBUG_IOCTL_TRACE
/*------------------------------------------------------------------*/
/*
* Get wireless statistics
- * Called by /proc/net/wireless...
+ * Called by /proc/net/wireless
*/
static iw_stats *
wavelan_get_wireless_stats(device * dev)
wstats->discard.code = 0L;
wstats->discard.misc = 0L;
- /* ReEnable interrupts & restore flags */
+ /* Enable interrupts & restore flags */
wv_splx(x);
#ifdef DEBUG_IOCTL_TRACE
/************************* PACKET RECEPTION *************************/
/*
- * This part deal with receiving the packets.
- * The interrupt handler get an interrupt when a packet has been
- * successfully received and called this part...
+ * This part deals with receiving the packets.
+ * The interrupt handler gets an interrupt when a packet has been
+ * successfully received and calls this part.
*/
/*------------------------------------------------------------------*/
/*
- * This routine does the actual copy of data (including the ethernet
+ * This routine does the actual copying of data (including the Ethernet
* header structure) from the WaveLAN card to an sk_buff chain that
- * will be passed up to the network interface layer. NOTE: We
+ * will be passed up to the network interface layer. NOTE: we
* currently don't handle trailer protocols (neither does the rest of
* the network interface), so if that is needed, it will (at least in
* part) be added here. The contents of the receive ring buffer are
#endif /* HISTOGRAM */
0)
{
- u_char stats[3]; /* Signal level, Noise level, Signal quality */
+ u_char stats[3]; /* signal level, noise level, signal quality */
/* read signal level, silence level and signal quality bytes */
- /* Note : in the Pcmcia hardware, these are part of the frame. It seem
+ /* Note: in the PCMCIA hardware, these are part of the frame. It seems
* that for the ISA hardware, it's nowhere to be found in the frame,
- * so I'm oblige to do this (it has side effect on /proc/net/wireless)
- * Any idea ? */
+ * so I'm obliged to do this (it has a side effect on /proc/net/wireless).
+ * Any ideas? */
mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
mmc_read(ioaddr, mmroff(0, mmr_signal_lvl), stats, 3);
mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
#endif
}
- /* Check is there was problems in the frame processing */
+ /* Were there problems in processing the frame? Let's check. */
if((fd.fd_status & (FD_STATUS_S6 | FD_STATUS_S7 | FD_STATUS_S8 |
FD_STATUS_S9 | FD_STATUS_S10 | FD_STATUS_S11))
!= 0)
}
}
- /* Check if frame contain a pointer to the data */
+ /* Does the frame contain a pointer to the data? Let's check. */
if(fd.fd_rbd_offset == I82586NULL)
#ifdef DEBUG_RX_ERROR
printk(KERN_INFO "%s: wv_receive(): frame has no data.\n", dev->name);
/*********************** PACKET TRANSMISSION ***********************/
/*
- * This part deal with sending packet through the wavelan
+ * This part deals with sending packet through the WaveLAN
*
*/
* Each block contain a transmit command, a nop command,
* a transmit block descriptor and a buffer.
* The CU read the transmit block which point to the tbd,
- * read the tbd and the the content of the buffer.
- * When it has finish with it, it goes to the next command
+ * read the tbd and the content of the buffer.
+ * When it has finished with it, it goes to the next command
* which in our case is the nop. The nop point on itself,
* so the CU stop here.
* When we add the next block, we modify the previous nop
sizeof(nop.nop_h.ac_link));
/*
- * Transmit buffer descriptor.
+ * Transmit buffer descriptor
*/
tbd.tbd_status = TBD_STATUS_EOF | (TBD_STATUS_ACNT & clen);
tbd.tbd_next_bd_offset = I82586NULL;
obram_write(ioaddr, tbd_addr, (unsigned char *)&tbd, sizeof(tbd));
/*
- * Data.
+ * Data
*/
obram_write(ioaddr, buf_addr, buf, clen);
/*------------------------------------------------------------------*/
/*
* This routine is called when we want to send a packet (NET3 callback)
- * In this routine, we check if the the harware is ready to accept
+ * In this routine, we check if the hardware is ready to accept
* the packet. We also prevent reentrance. Then, we call the function
* to send the packet...
*/
#endif
/* This flag indicate that the hardware can't perform a transmission.
- * Theoritically, NET3 check it before sending a packet to the driver,
- * but in fact it never do that and pool continuously.
- * As the watchdog will abort too long transmissions, we are quite safe...
+ * Theoretically, NET3 checks it before sending a packet to the driver,
+ * but in fact it never does that and pool continuously.
+ * As the watchdog will abort overly long transmissions, we are quite safe.
*/
if(dev->tbusy)
return 1;
#endif
else
{
- /* If somebody has asked to reconfigure the controler, we can do it now */
+ /* If somebody has asked to reconfigure the controller,
+ * we can do it now.
+ */
if(lp->reconfig_82586)
{
wv_82586_config(dev);
return 0;
}
-/********************** HARDWARE CONFIGURATION **********************/
+/*********************** HARDWARE CONFIGURATION ***********************/
/*
- * This part do the real job of starting and configuring the hardware.
+ * This part does the real job of starting and configuring the hardware.
*/
-/*------------------------------------------------------------------*/
+/*--------------------------------------------------------------------*/
/*
* Routine to initialize the Modem Management Controller.
* (called by wv_hw_reset())
psa.psa_nwid[0] = 0;
psa.psa_nwid[1] = 0;
- /* As NWID is not set : no NWID checking */
+ /* no NWID checking since NWID is not set */
psa.psa_nwid_select = 0;
/* Disable encryption */
m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
- /* Missing : encryption stuff... */
+ /* Missing: encryption stuff... */
/*
* Set default modem control parameters.
m.mmw_decay_prm = 0;
m.mmw_decay_updat_prm = 0;
- /* Write all info to mmc */
+ /* Write all info to MMC */
mmc_write(ioaddr, 0, (u_char *)&m, sizeof(m));
- /* The following code start the modem of the 2.00 frequency
+ /* The following code starts the modem of the 2.00 frequency
* selectable cards at power on. It's not strictly needed for the
- * following boots...
+ * following boots.
* The original patch was by Joe Finney for the PCMCIA driver, but
- * I've cleaned it a bit and add documentation.
+ * I've cleaned it up a bit and added documentation.
* Thanks to Loeke Brederveld from Lucent for the info.
*/
/* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
- * (does it work for everybody ??? - especially old cards...) */
- /* Note : WFREQSEL verify that it is able to read from EEprom
- * a sensible frequency (address 0x00) + that MMR_FEE_STATUS_ID
- * is 0xA (Xilinx version) or 0xB (Ariadne version).
- * My test is more crude but do work... */
+ * (does it work for everybody? -- especially old cards?) */
+ /* Note: WFREQSEL verifies that it is able to read a sensible
+ * frequency from from EEPROM (address 0x00) and that
+ * MMR_FEE_STATUS_ID is 0xA (Xilinx version) or 0xB (Ariadne version).
+ * My test is more crude but does work. */
if(!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
(MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
{
/* We must download the frequency parameters to the
- * synthetisers (from the EEprom - area 1)
- * Note : as the EEprom is auto decremented, we set the end
+ * synthesizers (from the EEPROM - area 1)
+ * Note : as the EEPROM is auto decremented, we set the end
* if the area... */
m.mmw_fee_addr = 0x0F;
m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
fee_wait(ioaddr, 100, 100);
#ifdef DEBUG_CONFIG_INFO
- /* The frequency was in the last word downloaded... */
+ /* The frequency was in the last word downloaded. */
mmc_read(ioaddr, (char *)&m.mmw_fee_data_l - (char *)&m,
(unsigned char *)&m.mmw_fee_data_l, 2);
- /* Print some info for the user */
- printk(KERN_DEBUG "%s: Wavelan 2.00 recognised (frequency select) : Current frequency = %ld\n",
+ /* Print some info for the user. */
+ printk(KERN_DEBUG "%s: WaveLAN 2.00 recognised (frequency select) : Current frequency = %ld\n",
dev->name,
((m.mmw_fee_data_h << 4) |
(m.mmw_fee_data_l >> 4)) * 5 / 2 + 24000L);
#endif
/* We must now download the power adjust value (gain) to
- * the synthetisers (from the EEprom - area 7 - DAC) */
+ * the synthesizers (from the EEPROM - area 7 - DAC) */
m.mmw_fee_addr = 0x61;
m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
mmc_write(ioaddr, (char *)&m.mmw_fee_ctrl - (char *)&m,
* Start the command unit executing the NOP
* self-loop of the first transmit block.
*
- * Here, we create the list of send buffer used to transmit packets
+ * Here, we create the list of send buffers used to transmit packets
* between the PC and the command unit. For each buffer, we create a
* buffer descriptor (pointing on the buffer), a transmit command
- * (pointing to the buffer descriptor) and a nop command.
- * The transmit command is linked to the nop, and the nop to itself.
- * When we will have finish to execute the transmit command, we will
- * then loop on the nop. By releasing the nop link to a new command,
+ * (pointing to the buffer descriptor) and a NOP command.
+ * The transmit command is linked to the NOP, and the NOP to itself.
+ * When we will have finished executing the transmit command, we will
+ * then loop on the NOP. By releasing the NOP link to a new command,
* we may send another buffer.
*
* (called by wv_hw_reset())
/*
* This routine does a standard config of the WaveLAN controler (i82586).
*
- * It initialise the scp, iscp and scb structure
- * The two first are only pointer to the next.
+ * It initialises the scp, iscp and scb structure
+ * The first two are just pointers to the next.
* The last one is used for basic configuration and for basic
- * communication (interrupt status)
+ * communication (interrupt status).
*
* (called by wv_hw_reset())
*/
iscp.iscp_offset = OFFSET_SCB;
obram_write(ioaddr, OFFSET_ISCP, (unsigned char *)&iscp, sizeof(iscp));
- /* Our first command is to reset the i82586 */
+ /* Our first command is to reset the i82586. */
memset(&scb, 0x00, sizeof(scb));
scb.scb_command = SCB_CMD_RESET;
scb.scb_cbl_offset = OFFSET_CU;
set_chan_attn(ioaddr, lp->hacr);
- /* Wait for command to finish */
+ /* Wait for command to finish. */
for(i = 1000; i > 0; i--)
{
obram_read(ioaddr, OFFSET_ISCP, (unsigned char *) &iscp, sizeof(iscp));
wv_ack(dev);
- /* Set the action command header */
+ /* Set the action command header. */
memset(&cb, 0x00, sizeof(cb));
cb.ac_command = AC_CFLD_EL | (AC_CFLD_CMD & acmd_diagnose);
cb.ac_link = OFFSET_CU;
/*------------------------------------------------------------------*/
/*
- * This routine does a standard config of the WaveLAN controler (i82586).
+ * This routine does a standard configuration of the WaveLAN controller
+ * (i82586).
*
* This routine is a violent hack. We use the first free transmit block
* to make our configuration. In the buffer area, we create the three
- * configure command (linked). We make the previous nop point to the
- * beggining of the buffer instead of the tx command. After, we go as
- * usual to the nop command...
- * Note that only the last command (mc_set) will generate an interrupt...
+ * configuration commands (linked). We make the previous NOP point to
+ * the beginning of the buffer instead of the tx command. After, we go
+ * as usual to the NOP command.
+ * Note that only the last command (mc_set) will generate an interrupt.
*
* (called by wv_hw_reset(), wv_82586_reconfig())
*/
lp->tx_n_in_use++;
- /* Calculate addresses of the differents part of the block */
+ /* Calculate addresses of the different parts of the block. */
tx_addr = txblock;
nop_addr = tx_addr + sizeof(tx);
tbd_addr = nop_addr + sizeof(nop);
- cfg_addr = tbd_addr + sizeof(tbd_t); /* beggining of the buffer */
+ cfg_addr = tbd_addr + sizeof(tbd_t); /* beginning of the buffer */
ias_addr = cfg_addr + sizeof(cfg);
mcs_addr = ias_addr + sizeof(ias);
/*
- * Transmit command.
+ * Transmit command
*/
tx.tx_h.ac_status = 0xFFFF; /* Fake completion value */
obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status),
sizeof(tx.tx_h.ac_status));
/*
- * NOP command.
+ * NOP command
*/
nop.nop_h.ac_status = 0;
obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
#if 0
/*
- * The default board configuration.
+ * The default board configuration
*/
cfg.fifolim_bytecnt = 0x080c;
cfg.addrlen_mode = 0x2600;
cfg.linprio_interframe = 0x7820; /* IFS=120, ACS=2 */
cfg.slot_time = 0xf00c; /* slottime=12 */
- cfg.hardware = 0x0008; /* tx even w/o CD */
+ cfg.hardware = 0x0008; /* tx even without CD */
cfg.min_frame_len = 0x0040;
#endif /* 0 */
/*------------------------------------------------------------------*/
/*
- * This routine stop gracefully the WaveLAN controler (i82586).
- * (called by wavelan_close())
+ * This routine, called by wavelan_close(), gracefully stops the
+ * WaveLAN controller (i82586).
*/
static inline void
wv_82586_stop(device * dev)
printk(KERN_DEBUG "%s: ->wv_82586_stop()\n", dev->name);
#endif
- /* Suspend both command unit and receive unit */
+ /* Suspend both command unit and receive unit. */
scb_cmd = (SCB_CMD_CUC & SCB_CMD_CUC_SUS) | (SCB_CMD_RUC & SCB_CMD_RUC_SUS);
obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
(unsigned char *)&scb_cmd, sizeof(scb_cmd));
/*------------------------------------------------------------------*/
/*
- * Totally reset the wavelan and restart it.
+ * Totally reset the WaveLAN and restart it.
* Performs the following actions:
* 1. A power reset (reset DMA)
* 2. Initialize the radio modem (using wv_mmc_init)
(unsigned int)dev);
#endif
- /* If watchdog was activated, kill it ! */
+ /* If watchdog was activated, kill it! */
if(lp->watchdog.prev != (timer_list *) NULL)
del_timer(&lp->watchdog);
/*------------------------------------------------------------------*/
/*
- * Check if there is a wavelan at the specific base address.
- * As a side effect, it read the MAC address.
+ * Check if there is a WaveLAN at the specific base address.
+ * As a side effect, this reads the MAC address.
* (called in wavelan_probe() and init_module())
*/
static int
mac, 6);
/*
- * Check the first three octets of the addr for the manufacturer's code.
- * Note: If you can't find your wavelan card, you've got a
- * non-NCR/AT&T/Lucent ISA cards, see wavelan.p.h for detail on
- * how to configure your card...
+ * Check the first three octets of the address for the manufacturer's code.
+ * Note: If this can't find your WaveLAN card, you've got a
+ * non-NCR/AT&T/Lucent ISA card. See wavelan.p.h for details on
+ * how to configure your card.
*/
for(i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++)
if((mac[0] == MAC_ADDRESSES[i][0]) &&
return 0;
#ifdef DEBUG_CONFIG_INFO
- printk(KERN_WARNING "Wavelan (0x%3X) : Your MAC address might be : %02X:%02X:%02X...\n",
+ printk(KERN_WARNING "WaveLAN (0x%3X): your MAC address might be: %02X:%02X:%02X.\n",
ioaddr, mac[0], mac[1], mac[2]);
#endif
return ENODEV;
lp = (net_local *) dev->priv;
ioaddr = dev->base_addr;
- /* Prevent reentrance. What should we do here ? */
+ /* Prevent reentrance. What should we do here? */
#ifdef DEBUG_INTERRUPT_ERROR
if(dev->interrupt)
printk(KERN_INFO "%s: wavelan_interrupt(): Re-entering the interrupt handler.\n",
return;
}
- /* Read interrupt data */
+ /* Read interrupt data. */
obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
(unsigned char *) &status, sizeof(status));
wv_receive(dev);
}
- /* Check the state of the command unit */
+ /* Check the state of the command unit. */
if(((status & SCB_ST_CNA) == SCB_ST_CNA) ||
(((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) && dev->start))
{
wv_hw_reset(dev);
}
- /* Check the state of the command unit */
+ /* Check the state of the command unit. */
if(((status & SCB_ST_RNR) == SCB_ST_RNR) ||
(((status & SCB_ST_RUS) != SCB_ST_RUS_RDY) && dev->start))
{
/*------------------------------------------------------------------*/
/*
- * Watchdog : when we start a transmission, we set a timer in the
- * kernel. If the transmission complete, this timer is disabled. If
- * it expire, it try to unlock the hardware.
+ * Watchdog: when we start a transmission, we set a timer in the
+ * kernel. If the transmission completes, this timer is disabled. If
+ * the timer expires, we try to unlock the hardware.
*
- * Note : this watchdog doesn't work on the same principle as the
- * watchdog in the previous version of the ISA driver. I make it this
+ * Note: this watchdog doesn't work on the same principle as the
+ * watchdog in the previous version of the ISA driver. I made it this
* way because the overhead of add_timer() and del_timer() is nothing
- * and that it avoid calling the watchdog, saving some CPU...
+ * and because it avoids calling the watchdog, saving some CPU time.
*/
static void
wavelan_watchdog(u_long a)
wv_hw_reset(dev);
}
else
- /* Re-set watchodog for next transmission */
+ /* Reset watchdog for next transmission. */
if(lp->tx_n_in_use > 0)
{
/* set timer to expire in WATCHDOG_JIFFIES */
/********************* CONFIGURATION CALLBACKS *********************/
/*
- * Here are the functions called by the linux networking (NET3) for
- * initialization, configuration and deinstallations of the Wavelan
- * ISA Hardware.
+ * Here are the functions called by the Linux networking code (NET3)
+ * for initialization, configuration and deinstallations of the
+ * WaveLAN ISA hardware.
*/
/*------------------------------------------------------------------*/
if(dev->irq == 0)
{
#ifdef DEBUG_CONFIG_ERRORS
- printk(KERN_WARNING "%s: wavelan_open(): no irq\n", dev->name);
+ printk(KERN_WARNING "%s: wavelan_open(): no IRQ\n", dev->name);
#endif
return -ENXIO;
}
{
irq2dev_map[dev->irq] = (device *) NULL;
#ifdef DEBUG_CONFIG_ERRORS
- printk(KERN_WARNING "%s: wavelan_open(): invalid irq\n", dev->name);
+ printk(KERN_WARNING "%s: wavelan_open(): invalid IRQ\n", dev->name);
#endif
return -EAGAIN;
}
/*------------------------------------------------------------------*/
/*
- * Shutdown the WaveLAN ISA card.
- * Called by NET3 when it "close" the device.
+ * Shut down the WaveLAN ISA card.
+ * Called by NET3 when it "closes" the device.
*/
static int
wavelan_close(device * dev)
(unsigned int) dev);
#endif
- /* Not do the job twice... */
+ /* Not do the job twice. */
if(dev->start == 0)
return 0;
dev->tbusy = 1;
dev->start = 0;
- /* If watchdog was activated, kill it ! */
+ /* If watchdog was activated, kill it! */
if(lp->watchdog.prev != (timer_list *) NULL)
del_timer(&lp->watchdog);
/*------------------------------------------------------------------*/
/*
- * Probe an i/o address, and if the wavelan is there configure the
+ * Probe an I/O address, and if the WaveLAN is there configure the
* device structure
* (called by wavelan_probe() & via init_module())
*/
memset(dev->priv, 0x00, sizeof(net_local));
lp = (net_local *)dev->priv;
- /* Back link to the device structure */
+ /* Back link to the device structure. */
lp->dev = dev;
- /* Add the device at the beggining of the linked list */
+ /* Add the device at the beginning of the linked list. */
lp->next = wavelan_list;
wavelan_list = lp;
/*
* Fill in the fields of the device structure
- * with ethernet-generic values.
+ * with Ethernet-generic values.
*/
ether_setup(dev);
/*------------------------------------------------------------------*/
/*
- * Check for a network adaptor of this type.
- * Return '0' iff one exists.
- * (There seem to be different interpretations of
+ * Check for a network adaptor of this type. Return '0' iff one
+ * exists. (There seem to be different interpretations of
* the initial value of dev->base_addr.
* We follow the example in drivers/net/ne.c.)
* (called in "Space.c")
wavelan_probe(device * dev)
{
short base_addr;
- mac_addr mac; /* Mac address (check wavelan existence) */
+ mac_addr mac; /* MAC address (check WaveLAN existence) */
int i;
int r;
/* Check if the is something at this base address */
if((r = wv_check_ioaddr(base_addr, mac)) == 0)
{
- memcpy(dev->dev_addr, mac, 6); /* Copy mac address */
+ memcpy(dev->dev_addr, mac, 6); /* Copy MAC address */
r = wavelan_config(dev);
}
return r;
}
- /* Scan all possible address of the wavelan hardware */
+ /* Scan all possible addresses of the WaveLAN hardware */
for(i = 0; i < NELS(iobase); i++)
{
- /* Check if the is something at this base address */
+ /* Check whether there is something at this base address */
if(wv_check_ioaddr(iobase[i], mac) == 0)
{
- dev->base_addr = iobase[i]; /* Copy base address */
- memcpy(dev->dev_addr, mac, 6); /* Copy mac address */
+ dev->base_addr = iobase[i]; /* Copy base address. */
+ memcpy(dev->dev_addr, mac, 6); /* Copy MAC address. */
if(wavelan_config(dev) == 0)
{
#ifdef DEBUG_CALLBACK_TRACE
}
}
- /* We may have touch base_addr : another driver may not like it... */
+ /* We may have touch base_addr: another driver may not like it. */
dev->base_addr = base_addr;
#ifdef DEBUG_CONFIG_INFO
/****************************** MODULE ******************************/
/*
- * Module entry point : insertion & removal
+ * Module entry point: insertion & removal
*/
#ifdef MODULE
/*------------------------------------------------------------------*/
/*
- * Insertion of the module...
- * I'm now quite proud of the multi-device support...
+ * Insertion of the module.
+ * I'm now quite proud of the multi-device support.
*/
int
init_module(void)
{
- mac_addr mac; /* Mac address (check wavelan existence) */
+ mac_addr mac; /* MAC address (check WaveLAN existence) */
int ret = 0;
int i;
if(io[0] == 0)
{
#ifdef DEBUG_CONFIG_ERRORS
- printk(KERN_WARNING "wavelan init_module(): doing device probing (bad !)\n");
+ printk(KERN_WARNING "WaveLAN init_module(): doing device probing (bad !)\n");
printk(KERN_WARNING "Specify base addresses while loading module to correct the problem\n");
#endif
- /* Copy the basic set of address to be probed */
+ /* Copy the basic set of address to be probed. */
for(i = 0; i < NELS(iobase); i++)
io[i] = iobase[i];
}
i = -1;
while((io[++i] != 0) && (i < NELS(io)))
{
- /* Check if the is something at this base address */
+ /* Check if there is something at this base address. */
if(wv_check_ioaddr(io[i], mac) == 0)
{
device * dev;
dev->base_addr = io[i];
dev->irq = irq[i];
dev->init = &wavelan_config;
- memcpy(dev->dev_addr, mac, 6); /* Copy mac address */
+ memcpy(dev->dev_addr, mac, 6); /* Copy MAC address */
/* Try to create the device */
if(register_netdev(dev) != 0)
kfree_s(dev, sizeof(struct device));
ret = -EIO;
}
- } /* If there is something at the address */
- } /* Loop on all addresses */
+ } /* if there is something at the address */
+ } /* Loop on all addresses. */
#ifdef DEBUG_CONFIG_ERRORS
if(wavelan_list == (net_local *) NULL)
- printk(KERN_WARNING "wavelan init_module(): No device found\n");
+ printk(KERN_WARNING "WaveLAN init_module(): no device found\n");
#endif
#ifdef DEBUG_MODULE_TRACE
printk(KERN_DEBUG "-> cleanup_module()\n");
#endif
- /* Loop on all devices and release them */
+ /* Loop on all devices and release them. */
while(wavelan_list != (net_local *) NULL)
{
device * dev = wavelan_list->dev;
/* Release the ioport-region. */
release_region(dev->base_addr, sizeof(ha_t));
- /* Remove definitely the device */
+ /* Definitely remove the device. */
unregister_netdev(dev);
- /* Unlink the device */
+ /* Unlink the device. */
wavelan_list = wavelan_list->next;
- /* Free pieces */
+ /* Free pieces. */
kfree_s(dev->priv, sizeof(struct net_local));
kfree_s(dev, sizeof(struct device));
}
return;
}
-/* This routine is logically part of the interrupt handler, but seperated
+/* This routine is logically part of the interrupt handler, but separated
for clarity and better register allocation. */
static int
yellowfin_rx(struct device *dev)
/*
* Brooktree is the video dac and is funny to program on the cg6.
* (it's even funnier on the cg3)
- * The FBC could be the the frame buffer control
+ * The FBC could be the frame buffer control
* The FHC could be the frame buffer hardware control.
*/
#define CG6_ROM_OFFSET 0x0
working conditions (3 commands per lun, FAST SCSI, no command queueing).
I get the stack overflow problem with the 2 drivers at the same
frequency.
- With only 2 commands per lun, I dont have the problem with any driver.
+ With only 2 commands per LUN, I don't have the problem with any driver.
It seems that the madness of recursion and the recent introduction of
the silly generic read function have broken performance and reliability
of scsi drivers.
*
* Function: Sccb_bad_isr
*
- * Description: Some type of interrupt has occured which is slightly
+ * Description: Some type of interrupt has occurred which is slightly
* out of the ordinary. We will now decode it fully, in
* this routine. This is broken up in an attempt to save
* processing time.
both channels to use the IRQ assigned to Channel A, 1 to force both
channels to use the IRQ assigned to Channel B, and -1 will disable
this horrible abomination of a hack. The default is disabled (-1).
+ "aic7xxx=pci_parity:x" - This option controls whether or not the driver
+ enables PCI parity error checking on the PCI bus. By default, this
+ checking is disabled. To enable the checks, simply specify pci_parity
+ with no value afterwords. To reverse the parity from even to odd,
+ supply any number other than 0 or 255. In short:
+ pci_parity - Even parity checking (even is the normal PCI parity)
+ pci_parity:x - Where x > 0, Odd parity checking
+ pci_parity:0 - No check (default)
+ NOTE: In order to get Even PCI parity checking, you must use the
+ version of the option that does not include the : and a number at
+ the end (unless you want to enter exactly 2^32 - 1 as the number).
"aic7xxx=tag_info:{{8,8..},{8,8..},..}" - This option is used to enable
tagged queueing on specific devices. As of driver version 5.0.6, we
now globally enable tagged queueing by default, but we also disable
/* Similar to aha1542_in, except that we wait a very short period of time.
We use this if we know the board is alive and awake, but we are not sure
- if the board will respond the the command we are about to send or not */
+ if the board will respond to the command we are about to send or not */
static int aha1542_in1(unsigned int base, unchar *cmdp, int len)
{
unsigned long flags;
0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
-#define AIC7XXX_C_VERSION "5.0.14"
+#define AIC7XXX_C_VERSION "5.0.19"
#define NUMBER(arr) (sizeof(arr) / sizeof(arr[0]))
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92)
# if defined(__sparc_v9__) || defined(__powerpc__)
-# error "PPC and Sparc platforms are only support under 2.1.x and above"
+# error "PPC and Sparc platforms are only support under 2.1.92 and above"
# endif
# include <linux/bios32.h>
#endif
-#if !defined(__alpha__) && !defined(__sparc__)
+#if defined(__powerpc__) || defined(__i386__)
# define MMAPIO
#endif
AHC_BIOS_ENABLED = 0x00800000,
AHC_ABORT_PENDING = 0x02000000,
AHC_RESET_PENDING = 0x04000000,
+#define AHC_IN_ISR_BIT 28
AHC_IN_ISR = 0x10000000,
AHC_IN_ABORT = 0x20000000,
AHC_IN_RESET = 0x40000000
#define DEVICE_PRINT_WDTR 0x10
#define DEVICE_SUCCESS 0x20
#define DEVICE_TAGGED_SUCCESS 0x40
+#define DEVICE_SCANNED 0x80
volatile unsigned char dev_flags[MAX_TARGETS];
volatile unsigned char dev_active_cmds[MAX_TARGETS];
unsigned char dev_temp_queue_depth[MAX_TARGETS];
unsigned char dev_commands_sent[MAX_TARGETS];
+ /*
+ * The next 128 (or 256 on 64 bit machines)....
+ */
+ Scsi_Cmnd *dev_wdtr_cmnd[MAX_TARGETS];
+ Scsi_Cmnd *dev_sdtr_cmnd[MAX_TARGETS];
+
/*
* The next 64....
*/
unsigned short ultraenb; /* Ultra mode target list */
unsigned short bios_control; /* bios control - SEEPROM */
unsigned short adapter_control; /* adapter control - SEEPROM */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+ struct pci_dev *pdev;
+#endif
unsigned char pci_bus;
unsigned char pci_device_fn;
* or reset call into the
* driver.
*/
-
+static int aic7xxx_pci_parity = 0; /*
+ * Set this to:
+ * 0 - Shut off PCI parity check
+ * -1 - Normal parity check
+ * anything else - reverse pci
+ * pci parity checking
+ */
/*
* So that insmod can find the variable and make it point to something
*/
{ "7895_irq_hack", &aic7xxx_7895_irq_hack },
{ "override_term", &aic7xxx_override_term },
{ "panic_on_abort", &aic7xxx_panic_on_abort },
+ { "pci_parity", &aic7xxx_pci_parity },
{ "tag_info", NULL }
};
* Description:
* Find the next patch to download.
*-F*************************************************************************/
-static struct patch *
-aic7xxx_next_patch(struct patch *cur_patch, int options, int instrptr)
+static struct sequencer_patch *
+aic7xxx_next_patch(struct sequencer_patch *cur_patch, int options, int instrptr)
{
while (cur_patch != NULL)
{
{
int address_offset;
unsigned int address;
- struct patch *patch;
+ struct sequencer_patch *patch;
int i;
address_offset = 0;
address = instr.address;
address |= (instr.opcode_addr & ADDR_HIGH_BIT) << 8;
- for (i = 0; i < NUMBER(patches); i++)
+ for (i = 0; i < NUMBER(sequencer_patches); i++)
{
- patch = &patches[i];
+ patch = &sequencer_patches[i];
if ((((patch->options & options) == 0) && (patch->negative == FALSE)) ||
(((patch->options & options) != 0) && (patch->negative == TRUE)))
{
aic7xxx_loadseq(struct aic7xxx_host *p)
{
int options;
- struct patch *cur_patch;
+ struct sequencer_patch *cur_patch;
int i;
int downloaded;
}
- cur_patch = patches;
+ cur_patch = sequencer_patches;
aic_outb(p, PERRORDIS | LOADRAM, SEQCTL);
aic_outb(p, 0, SEQADDR0);
aic_outb(p, 0, SEQADDR1);
cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24) |
(cmd->result & 0xffff);
}
+ if (!(p->dev_flags[tindex] & DEVICE_SCANNED))
+ {
+ if(cmd->cmnd[0] == INQUIRY)
+ {
+ char *buffer;
+
+ if(cmd->use_sg)
+ {
+ struct scatterlist *sg;
+
+ sg = (struct scatterlist *)cmd->request_buffer;
+ buffer = (char *)sg[0].address;
+ }
+ else
+ {
+ buffer = (char *)cmd->request_buffer;
+ }
+#define WIDE_INQUIRY_BITS 0x60
+#define SYNC_INQUIRY_BITS 0x10
+ if ( (buffer[7] & WIDE_INQUIRY_BITS) &&
+ (p->needwdtr_copy & (1<<tindex)) &&
+ (p->type & AHC_WIDE) )
+ {
+ p->needwdtr |= (1<<tindex);
+ p->needwdtr_copy |= (1<<tindex);
+ p->syncinfo[tindex].offset = MAX_OFFSET_16BIT;
+ }
+ else
+ {
+ p->needwdtr &= ~(1<<tindex);
+ p->needwdtr_copy &= ~(1<<tindex);
+ p->syncinfo[tindex].offset = MAX_OFFSET_8BIT;
+ }
+ if (buffer[7] & SYNC_INQUIRY_BITS)
+ {
+ p->needsdtr |= (1<<tindex);
+ p->needsdtr_copy |= (1<<tindex);
+ }
+ else
+ {
+ p->needsdtr &= ~(1<<tindex);
+ p->needsdtr_copy &= ~(1<<tindex);
+ }
+ p->dev_flags[tindex] |= DEVICE_SCANNED;
+#undef WIDE_INQUIRY_BITS
+#undef SYNC_INQUIRY_BITS
+ }
+ }
if ((scb->flags & (SCB_MSGOUT_WDTR | SCB_MSGOUT_SDTR)) != 0)
{
unsigned short mask;
scbq_insert_tail(&p->waiting_scbs, scbp);
}
}
- if ( (queue_depth > p->dev_active_cmds[tindex]) && scbp)
+ if ( (queue_depth > p->dev_active_cmds[tindex]) && scbp )
{
scbp = scbq_remove_head(&p->delayed_scbs[tindex]);
if (scbp)
scbq_insert_tail(&p->waiting_scbs, scbp);
}
}
+ if ( !(scb->tag_action) && (p->tagenable & (1<<tindex)) )
+ {
+ p->dev_temp_queue_depth[tindex] = p->dev_max_queue_depth[tindex];
+ }
p->dev_active_cmds[tindex]--;
p->activescbs--;
scsiseq = aic_inb(p, SCSISEQ);
aic_outb(p, scsiseq | SCSIRSTO, SCSISEQ);
- udelay(1000);
+ udelay(5000);
/* Turn off the bus reset. */
aic_outb(p, scsiseq & ~SCSIRSTO, SCSISEQ);
/* Re-enable reset interrupts. */
aic_outb(p, aic_inb(p, SIMODE1) | ENSCSIRST, SIMODE1);
- udelay(1000);
+ udelay(2000);
}
/*+F*************************************************************************
while ((scb = scbq_remove_head(&p->waiting_scbs)) != NULL)
{
tindex = TARGET_INDEX(scb->cmd);
+ if ( !scb->tag_action && (p->tagenable & (1<<tindex)) )
+ {
+ p->dev_temp_queue_depth[tindex] = 1;
+ }
if ( (p->dev_active_cmds[tindex] >=
p->dev_temp_queue_depth[tindex]) ||
(p->dev_last_reset[tindex] >= (jiffies - (4 * HZ))) )
}
if (sent)
{
- if(p->type & AHC_AIC78x0)
- aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
- else
- {
- pause_sequencer(p);
- aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
- unpause_sequencer(p, FALSE);
- }
+ pause_sequencer(p);
+ aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
+ unpause_sequencer(p, FALSE);
if (p->activescbs > p->max_activescbs)
p->max_activescbs = p->activescbs;
}
last_msg = aic_inb(p, LAST_MSG);
if ( (last_msg == MSG_IDENTIFYFLAG) &&
- (scb->tag_action != 0 ) &&
- !(scb->flags & SCB_MSGOUT_BITS) )
+ (scb->tag_action) &&
+ !(scb->flags & SCB_MSGOUT_BITS) )
{
if ((scb->tag_action == MSG_ORDERED_Q_TAG) &&
(p->dev_flags[scratch_offset] & DEVICE_TAGGED_SUCCESS))
}
scb->flags &= ~SCB_MSGOUT_WDTR_16BIT;
p->syncinfo[scratch_offset].offset = MAX_OFFSET_8BIT;
- /*
- * The sequencer should have already cleared the MK_MESSAGE bit in
- * the SCB, so we simply restart the message out phase and resend
- * the IDENTIFY and TAG values so that there is no confusion over
- * what has been rejected.
- */
- aic_outb(p, MSG_IDENTIFYFLAG, MSG_OUT);
- aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
+ if (p->needsdtr_copy & target_mask)
+ p->needsdtr |= target_mask;
}
else if (scb->flags & SCB_MSGOUT_SDTR)
{
"asynchronous transfers.\n", p->host_no, CTL_OF_SCB(scb));
p->dev_flags[scratch_offset] &= ~DEVICE_PRINT_SDTR;
}
- /*
- * The sequencer should have already cleared the MK_MESSAGE bit in
- * the SCB, so we simply restart the message out phase and resend
- * the IDENTIFY and TAG values so that there is no confusion over
- * what has been rejected.
- */
- aic_outb(p, MSG_IDENTIFYFLAG, MSG_OUT);
- aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
}
else if (aic7xxx_verbose & VERBOSE_SEQINT)
{
* Send a sense command to the requesting target.
* XXX - revisit this and get rid of the memcopys.
*/
- memcpy((void *) scb->sense_cmd, (void *) generic_sense,
+ memcpy(&scb->sense_cmd[0], &generic_sense[0],
sizeof(generic_sense));
scb->sense_cmd[1] = (cmd->lun << 5);
*
* 1998/04/23 - We also don't want to set the flag if the
* original command was a TEST_UNIT_READY since that
- * implies a SEND_SENSE anyway. Plus, we don't actually
- * start the negotiation here, we just flag it because
- * some devices appear to choke up their message buffer
- * when we mix things together like this.
+ * implies a SEND_SENSE anyway.
*/
- if ( !(scb->flags & SCB_MSGOUT_BITS) &&
- (scb->cmd->cmnd[0] != TEST_UNIT_READY) )
+ if (scb->cmd->cmnd[0] != TEST_UNIT_READY)
{
- if ( p->needwdtr_copy & target_mask )
+ if ( (p->needwdtr_copy & target_mask) &&
+ !(p->wdtr_pending & target_mask) &&
+ !(p->sdtr_pending & target_mask) )
{
p->needwdtr |= target_mask;
+ p->wdtr_pending |= target_mask;
+ hscb->control |= MK_MESSAGE;
+ scb->flags |= SCB_MSGOUT_WDTR_16BIT;
}
if ( p->needsdtr_copy & target_mask )
{
p->needsdtr |= target_mask;
+ if ( !(p->wdtr_pending & target_mask) &&
+ !(p->sdtr_pending & target_mask) )
+ {
+ p->sdtr_pending |= target_mask;
+ hscb->control |= MK_MESSAGE;
+ scb->flags |= SCB_MSGOUT_SDTR;
+ }
}
}
}
else if (scb->flags & SCB_ABORT)
{
- if (scb->hscb->control & TAG_ENB)
+ if (scb->tag_action)
{
if (msg_out == MSG_IDENTIFYFLAG)
{
p->msg_buf[p->msg_index++] = scb->tag_action;
p->msg_buf[p->msg_index++] = scb->hscb->tag;
- p->msg_len += 2;
- }
+ p->msg_len += 2;
+ }
p->msg_buf[p->msg_index++] = MSG_ABORT_TAG;
}
else
}
else if (scb->flags & SCB_MSGOUT_WDTR)
{
- if ( (scb->hscb->control & TAG_ENB) &&
- (msg_out == MSG_IDENTIFYFLAG) )
- {
- p->msg_buf[p->msg_index++] = scb->tag_action;
- p->msg_buf[p->msg_index++] = scb->hscb->tag;
- p->msg_len += 2;
- }
aic7xxx_construct_wdtr(p, (scb->flags & SCB_WDTR_16BIT));
}
else if (scb->flags & SCB_MSGOUT_SDTR)
period = 0;
offset = 0;
}
- if ( (scb->hscb->control & TAG_ENB) &&
- (msg_out == MSG_IDENTIFYFLAG) )
- {
- p->msg_buf[p->msg_index++] = scb->tag_action;
- p->msg_buf[p->msg_index++] = scb->hscb->tag;
- p->msg_len += 2;
- }
aic7xxx_construct_sdtr(p, period, offset);
}
else
}
scb->flags &= ~SCB_MSGOUT_WDTR_16BIT;
p->wdtr_pending &= ~target_mask;
+ /*
+ * By virtue of the SCSI spec, a WDTR message negates any existing
+ * SDTR negotiations. So, even if needsdtr isn't marked for this
+ * device, we still have to do a new SDTR message if the device
+ * supports SDTR at all. Therefore, we check needsdtr_copy instead
+ * of needstr.
+ */
+ if ( (p->needsdtr_copy & target_mask) &&
+ !(p->sdtr_pending & target_mask))
+ {
+ p->needsdtr |= target_mask;
+ }
}
else
{
aic7xxx_pci_intr(struct aic7xxx_host *p)
{
unsigned char status1;
- int error;
- error = 0;
- error = pcibios_read_config_byte(p->pci_bus, p->pci_device_fn,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+ pci_read_config_byte(p->pdev, PCI_STATUS, &status1);
+#else
+ pcibios_read_config_byte(p->pci_bus, p->pci_device_fn,
PCI_STATUS, &status1);
+#endif
- if (error == 0)
- {
- if (status1 & DPE)
- printk(WARN_LEAD "Data Parity Error during PCI address or PCI write"
- "phase.\n", p->host_no, -1, -1, -1);
- if (status1 & SSE)
- printk(WARN_LEAD "Signal System Error Detected\n", p->host_no,
- -1, -1, -1);
- if (status1 & RMA)
- printk(WARN_LEAD "Received a PCI Master Abort\n", p->host_no,
- -1, -1, -1);
- if (status1 & RTA)
- printk(WARN_LEAD "Received a PCI Target Abort\n", p->host_no,
- -1, -1, -1);
- if (status1 & STA)
- printk(WARN_LEAD "Signaled a PCI Target Abort\n", p->host_no,
- -1, -1, -1);
- if (status1 & DPR)
- printk(WARN_LEAD "Data Parity Error has been reported via PCI pin "
- "PERR#\n", p->host_no, -1, -1, -1);
- }
- else
- {
- printk(WARN_LEAD "Error reading PCI config register during PCI ERROR"
- "interrupt.\n", p->host_no, -1, -1, -1);
- aic_outb(p, CLRPARERR, CLRINT);
- return;
- }
+ if ( (status1 & DPE) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+ printk(WARN_LEAD "Data Parity Error during PCI address or PCI write"
+ "phase.\n", p->host_no, -1, -1, -1);
+ if ( (status1 & SSE) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+ printk(WARN_LEAD "Signal System Error Detected\n", p->host_no,
+ -1, -1, -1);
+ if ( (status1 & RMA) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+ printk(WARN_LEAD "Received a PCI Master Abort\n", p->host_no,
+ -1, -1, -1);
+ if ( (status1 & RTA) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+ printk(WARN_LEAD "Received a PCI Target Abort\n", p->host_no,
+ -1, -1, -1);
+ if ( (status1 & STA) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+ printk(WARN_LEAD "Signaled a PCI Target Abort\n", p->host_no,
+ -1, -1, -1);
+ if ( (status1 & DPR) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) )
+ printk(WARN_LEAD "Data Parity Error has been reported via PCI pin "
+ "PERR#\n", p->host_no, -1, -1, -1);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+ pci_write_config_byte(p->pdev, PCI_STATUS, status1);
+#else
pcibios_write_config_byte(p->pci_bus, p->pci_device_fn,
PCI_STATUS, status1);
+#endif
if (status1 & (DPR|RMA|RTA))
aic_outb(p, CLRPARERR, CLRINT);
p = (struct aic7xxx_host *)dev_id;
/*
- * Just a few sanity checks. Make sure p != NULL, that we have an
- * interrupt pending, and that we aren't already in our int handler.
+ * Just a few sanity checks. Make sure that we have an int pending.
* Also, if PCI, then we are going to check for a PCI bus error status
* should we get too many spurious interrupts.
*/
- if (p == NULL)
- {
- printk(KERN_WARNING "aic7xxx: ISR routine called with NULL dev_id\n");
- return;
- }
- else if (!(aic_inb(p, INTSTAT) & INT_PEND))
+ if (!((intstat = aic_inb(p, INTSTAT)) & INT_PEND))
{
#ifdef CONFIG_PCI
if ((p->type & AHC_AIC78x0) && (p->spurious_int > 500))
#endif
return;
}
- else if (p->flags & AHC_IN_ISR)
- {
- return;
- }
- /*
- * Handle all the interrupt sources - especially for SCSI
- * interrupts, we won't get a second chance at them.
- */
- intstat = aic_inb(p, INTSTAT);
p->spurious_int = 0;
/*
* Keep track of interrupts for /proc/scsi
*/
p->isr_count++;
- p->flags |= AHC_IN_ISR;
/*
- * Indicate that we're in the interrupt handler.
+ * Handle all the interrupt sources - especially for SCSI
+ * interrupts, we won't get a second chance at them.
*/
if (intstat & CMDCMPLT)
{
continue;
}
aic7xxx_reset_device(p, scb->cmd->target, scb->cmd->channel,
- scb->cmd->lun, scb->cmd->lun);
+ scb->cmd->lun, scb->hscb->tag);
scb->flags &= ~(SCB_QUEUED_FOR_DONE | SCB_RESET | SCB_ABORT |
SCB_QUEUED_ABORT);
unpause_sequencer(p, FALSE);
{
aic7xxx_handle_scsiint(p, intstat);
}
- aic7xxx_done_cmds_complete(p);
- aic7xxx_run_waiting_queues(p);
- p->flags &= ~AHC_IN_ISR;
}
/*+F*************************************************************************
do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long cpu_flags;
+ struct aic7xxx_host *p;
+ static unsigned int re_entry_counter = 0;
+
+ p = (struct aic7xxx_host *)dev_id;
+ if(!p)
+ return;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)
-
+ if(test_and_set_bit(AHC_IN_ISR_BIT, &p->flags))
+ {
+ if(re_entry_counter++ > 100000UL)
+ {
+ /*
+ * Hmmm...we seem to be looping here. This usually means that our
+ * interrupt routine got killed by a NULL pointer deref. Panic.
+ */
+ sti();
+ panic("aic7xxx: The interrupt routine appears to have seg faulted.\n");
+ }
+ return;
+ }
+ re_entry_counter = 0;
spin_lock_irqsave(&io_request_lock, cpu_flags);
aic7xxx_isr(irq, dev_id, regs);
+ aic7xxx_done_cmds_complete(p);
+ aic7xxx_run_waiting_queues(p);
spin_unlock_irqrestore(&io_request_lock, cpu_flags);
+ clear_bit(AHC_IN_ISR_BIT, &p->flags);
#else
+ if(set_bit(AHC_IN_ISR_BIT, (int *)&p->flags))
+ {
+ if(re_entry_counter++ > 100000UL)
+ {
+ /*
+ * Hmmm...we seem to be looping here. This usually means that our
+ * interrupt routine got killed by a NULL pointer deref. Panic.
+ */
+ sti();
+ panic("aic7xxx: The interrupt routine appears to have seg faulted.\n");
+ }
+ return;
+ }
+ re_entry_counter = 0;
DRIVER_LOCK
aic7xxx_isr(irq, dev_id, regs);
DRIVER_UNLOCK
+ aic7xxx_done_cmds_complete(p);
+ aic7xxx_run_waiting_queues(p);
+ clear_bit(AHC_IN_ISR_BIT, (int *)&p->flags);
#endif
}
scsi_conf |= p->scsi_id_b;
aic_outb(p, scsi_conf | (term) ? TERM_ENB : 0, SCSICONF + 1);
}
- if ((scsi_conf & RESET_SCSI) && (aic7xxx_no_reset == 0))
+ if ( (scsi_conf & RESET_SCSI) && !(aic7xxx_no_reset) )
{
/* Reset SCSI bus B. */
if (aic7xxx_verbose & VERBOSE_PROBE)
}
- if ((scsi_conf & RESET_SCSI) && (aic7xxx_no_reset == 0))
+ if ( (scsi_conf & RESET_SCSI) && !(aic7xxx_no_reset) )
{
/* Reset SCSI bus A. */
if (aic7xxx_verbose & VERBOSE_PROBE)
}
}
- aic_outb(p, target_settings, TARG_SCRATCH + i);
+ /*
+ * If we reset the bus, then clear the transfer ssettings, else leave
+ * them be
+ */
+ if ( (scsi_conf & RESET_SCSI) && !(aic7xxx_no_reset) )
+ aic_outb(p, target_settings, TARG_SCRATCH + i);
if (p->needsdtr_copy & (0x01 << i))
{
short sxfr, j;
}
p->needsdtr = p->needsdtr_copy;
p->needwdtr = p->needwdtr_copy;
- aic_outb(p, 0, ULTRA_ENB);
- aic_outb(p, 0, ULTRA_ENB + 1);
+
+ /*
+ * If we reset the bus, then clear the transfer ssettings, else leave
+ * them be
+ */
+ if ( (scsi_conf & RESET_SCSI) && !(aic7xxx_no_reset) )
+ {
+ aic_outb(p, 0, ULTRA_ENB);
+ aic_outb(p, 0, ULTRA_ENB + 1);
+ }
/*
* Allocate enough hardware scbs to handle the maximum number of
{
kfree(p->scb_data->scb_array[i]);
}
- /*
- * Free the SCB data area.
- */
- kfree(p->scb_data);
/*
- * Free the instance of the device structure.
+ * Free any alloced Scsi_Cmnd structures that might be around for
+ * negotiation purposes....
*/
+ for (i = 0; i < MAX_TARGETS; i++)
+ {
+ if(p->dev_wdtr_cmnd[i])
+ kfree(p->dev_wdtr_cmnd[i]);
+ if(p->dev_sdtr_cmnd[i])
+ kfree(p->dev_sdtr_cmnd[i]);
+ }
/*
- * XXXXXXXX FIXXXXXMEEEEEE. How do we unmap the I/O range we have mapped
- * if we are doing MMAPed I/O ?????????? Our biggest concern is the issue
- * of possibly calling unmap on an area that *might* be used on another
- * controller as well (aka, the 4096 byte MMAPed area is back to back
- * with another controller, and the PAGE_SIZE is greater then 4096, allowing
- * us to remap in a shared page).
+ * Free the SCB data area.
*/
- scsi_unregister(p->host);
+ kfree(p->scb_data);
}
/*+F*************************************************************************
target_settings &= ~0x70;
p->ultraenb &= ~(0x01 << i);
}
- aic_outb(p, target_settings, TARG_SCRATCH + i);
+ /*
+ * Don't output these settings if we aren't resetting the bus, instead,
+ * leave the devices current settings in place
+ */
+ if (!(aic7xxx_no_reset))
+ aic_outb(p, target_settings, TARG_SCRATCH + i);
}
aic_outb(p, ~(p->discenable & 0xFF), DISC_DSB);
aic_outb(p, ~((p->discenable >> 8) & 0xFF), DISC_DSB + 1);
*/
if(aic7xxx)
aic7xxx_setup(aic7xxx, NULL);
-
+ if(dummy_buffer[0] != 'P')
+ printk(KERN_WARNING "aic7xxx: Please read the file /usr/src/linux/drivers"
+ "/scsi/README.aic7xxx\n"
+ "aic7xxx: to see the proper way to specify options to the aic7xxx "
+ "module\n"
+ "aic7xxx: Specifically, don't use any commas when passing arguments to\n"
+ "aic7xxx: insmod or else it might trash certain memory areas.\n");
#endif
template->proc_dir = &proc_scsi_aic7xxx;
/*
* PCI-bus probe.
*/
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+ if (pci_present())
+#else
if (pcibios_present())
+#endif
{
struct
{
};
unsigned short command;
- unsigned int devconfig, i;
+ unsigned int devconfig, i, oldverbose;
#ifdef MMAPIO
unsigned long page_offset, base;
#endif
*/
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
temp_p->irq = pdev->irq;
+ temp_p->pdev = pdev;
temp_p->pci_bus = pdev->bus->number;
temp_p->pci_device_fn = pdev->devfn;
temp_p->base = pdev->base_address[0];
temp_p->mbase = pdev->base_address[1];
pci_read_config_word(pdev, PCI_COMMAND, &command);
- pci_write_config_word(pdev, PCI_COMMAND,
- command | PCI_COMMAND_MASTER |
- PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+ if (aic7xxx_verbose & VERBOSE_PROBE2)
+ {
+ printk("aic7xxx: Initial PCI_COMMAND value was 0x%x\n",
+ (int)command);
+ }
+ command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_MASTER |
+ PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+ if (aic7xxx_pci_parity == 0)
+ command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+ pci_write_config_word(pdev, PCI_COMMAND, command);
+ pci_read_config_dword(pdev, PCI_COMMAND, &devconfig);
+ if (aic7xxx_verbose & VERBOSE_PROBE2)
+ {
+ printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
+ }
+ devconfig |= 0x80000000;
+ if ((aic7xxx_pci_parity == 0) || (aic7xxx_pci_parity == -1))
+ {
+ devconfig &= ~(0x00000008);
+ }
+ else
+ {
+ devconfig |= 0x00000008;
+ }
+ pci_write_config_dword(pdev, PCI_COMMAND, devconfig);
+ if (aic7xxx_verbose & VERBOSE_PROBE2)
+ printk("aic7xxx: <%s> at PCI %d/%d\n",
+ board_names[aic7xxx_pci_devices[i].board_name_index],
+ PCI_SLOT(temp_p->pdev->devfn),
+ PCI_FUNC(temp_p->pdev->devfn));
#else
temp_p->pci_bus = pci_bus;
temp_p->pci_device_fn = pci_devfn;
&mmapbase);
temp_p->mbase = mmapbase;
pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command);
- pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND,
- command | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
- PCI_COMMAND_IO);
-#endif
-
+ if (aic7xxx_verbose & VERBOSE_PROBE2)
+ {
+ printk("aic7xxx: Initial PCI_COMMAND value was 0x%x\n",
+ (int)command);
+ }
+ command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_MASTER |
+ PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+ if (aic7xxx_pci_parity == 0)
+ command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+ pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND, command);
+ pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG, &devconfig);
+ if (aic7xxx_verbose & VERBOSE_PROBE2)
+ {
+ printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
+ }
+ devconfig |= 0x80000000;
+ if ((aic7xxx_pci_parity == 0) || (aic7xxx_pci_parity == -1))
+ {
+ devconfig &= ~(0x00000008);
+ }
+ else
+ {
+ devconfig |= 0x00000008;
+ }
+ pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG, devconfig);
if (aic7xxx_verbose & VERBOSE_PROBE2)
printk("aic7xxx: <%s> at PCI %d/%d\n",
board_names[aic7xxx_pci_devices[i].board_name_index],
PCI_SLOT(temp_p->pci_device_fn),
PCI_FUNC(temp_p->pci_device_fn));
+#endif
/*
* The first bit (LSB) of PCI_BASE_ADDRESS_0 is always set, so
temp_p->pause = temp_p->unpause | PAUSE;
#ifdef MMAPIO
- base = temp_p->mbase & PAGE_MASK;
- page_offset = temp_p->mbase - base;
- /*
- * replace the next line with this one if you are using 2.1.x:
- * temp_p->maddr = ioremap(base, page_offset + 256);
- */
+ if((temp_p->type & AHC_AIC7850) != AHC_AIC7850)
+ {
+ base = temp_p->mbase & PAGE_MASK;
+ page_offset = temp_p->mbase - base;
+ /*
+ * replace the next line with this one if you are using 2.1.x:
+ * temp_p->maddr = ioremap(base, page_offset + 256);
+ */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
- temp_p->maddr = ioremap(base, page_offset + 256);
+ temp_p->maddr = ioremap(base, page_offset + 256);
#else
- temp_p->maddr = vremap(base, page_offset + 256);
+ temp_p->maddr = vremap(base, page_offset + 256);
#endif
- if(temp_p->maddr)
+ if(temp_p->maddr)
+ {
+ temp_p->maddr += page_offset;
+ }
+ }
+ else
{
- temp_p->maddr += page_offset;
+#ifdef __i386__
+ /*
+ * Resort to PIO mode on these controllers and Intel hardware.
+ * For other hardware we need to either disable these controllers
+ * or do without MMAPed IO. However, for PPC, we can't do
+ * MMAPed IO (according to what I've heard) so we may be forced
+ * to just fail detection on those cards.
+ */
+ temp_p->maddr = NULL;
+#else
+ kfree(temp_p);
+ temp_p = NULL;
+ continue;
+#endif /* __i386__ */
}
#endif
aic_outb(temp_p, temp_p->pause, HCNTRL);
while( (aic_inb(temp_p, HCNTRL) & PAUSE) == 0 ) ;
+ /*
+ * Clear out any pending PCI error status messages. Also set
+ * verbose to 0 so that we don't emit strange PCI error messages
+ * while cleaning out the current status bits.
+ */
+ oldverbose = aic7xxx_verbose;
+ aic7xxx_verbose = 0;
+ aic7xxx_pci_intr(temp_p);
+ aic7xxx_verbose = oldverbose;
+
temp_p->bios_address = 0;
/*
case AHC_AIC7895:
temp_p->flags |= AHC_MULTI_CHANNEL;
- if (PCI_FUNC(temp_p->pci_device_fn) != 0)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
+ if (PCI_FUNC(temp_p->pdev->devfn) != 0)
{
temp_p->flags |= AHC_CHNLB;
}
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
+ devconfig = le32_to_cpu(devconfig);
devconfig |= SCBSIZE32;
+ devconfig = cpu_to_le32(devconfig);
pci_write_config_dword(pdev, DEVCONFIG, devconfig);
#else
+ if (PCI_FUNC(temp_p->pci_device_fn) != 0)
+ {
+ temp_p->flags |= AHC_CHNLB;
+ }
pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG,
&devconfig);
devconfig |= SCBSIZE32;
temp_p->flags |= AHC_USEDEFAULTS;
if (sxfrctl1 & STPWEN)
temp_p->flags |= AHC_TERM_ENB_A | AHC_TERM_ENB_B;
- temp_p->scsi_id_b = temp_p->scsi_id;
}
/*
{
found--;
aic7xxx_free(p);
+ scsi_unregister(p->host);
}
}
current_p = temp_p;
{
found--;
aic7xxx_free(p);
+ scsi_unregister(p->host);
}
}
current_p = temp_p;
{
found--;
aic7xxx_free(p);
+ scsi_unregister(p->host);
}
}
current_p = temp_p;
return (found);
}
+/*+F*************************************************************************
+ * Function:
+ * aic7xxx_negotiation_complete
+ *
+ * Description:
+ * Handle completion events for our Negotiation commands. Clear out the
+ * struct and get it ready for its next use.
+ *-F*************************************************************************/
+static void
+aic7xxx_negotiation_complete(Scsi_Cmnd *cmd)
+{
+ memset(&cmd->sense_buffer[0], 0, sizeof(cmd->sense_buffer));
+}
+
+/*+F*************************************************************************
+ * Function:
+ * aic7xxx_build_negotiation_command
+ *
+ * Description:
+ * Build a Scsi_Cmnd structure to perform negotiation with or else send
+ * a pre-built command specifically for this purpose.
+ *-F*************************************************************************/
+static void
+aic7xxx_build_negotiation_cmnd(struct aic7xxx_host *p, Scsi_Cmnd *old_cmd,
+ int tindex)
+{
+
+ if ( (p->needwdtr & (1<<tindex)) && !(p->wdtr_pending & (1<<tindex)) )
+ {
+ if(p->dev_wdtr_cmnd[tindex] == NULL)
+ {
+ Scsi_Cmnd *cmd;
+
+ if (!(p->dev_wdtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
+ {
+ return;
+ }
+ cmd = p->dev_wdtr_cmnd[tindex];
+ memset(cmd, 0, sizeof(Scsi_Cmnd));
+ memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
+ memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
+ memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
+ cmd->lun = 0;
+ cmd->request_bufflen = 0;
+ cmd->request_buffer = NULL;
+ cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
+ cmd->bufflen = 0;
+ cmd->buffer = NULL;
+ cmd->underflow = 0;
+ cmd->cmd_len = 6;
+ }
+ aic7xxx_queue(p->dev_wdtr_cmnd[tindex],
+ aic7xxx_negotiation_complete);
+ }
+ else if ( (p->needsdtr & (1<<tindex)) && !(p->sdtr_pending & (1<<tindex)) )
+ {
+ if(p->dev_sdtr_cmnd[tindex] == NULL)
+ {
+ Scsi_Cmnd *cmd;
+
+ if (!(p->dev_sdtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
+ {
+ return;
+ }
+ cmd = p->dev_sdtr_cmnd[tindex];
+ memset(cmd, 0, sizeof(Scsi_Cmnd));
+ memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
+ memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
+ memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
+ cmd->lun = 0;
+ cmd->request_bufflen = 0;
+ cmd->request_buffer = NULL;
+ cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
+ cmd->bufflen = 0;
+ cmd->buffer = NULL;
+ cmd->underflow = 0;
+ cmd->cmd_len = 6;
+ }
+ aic7xxx_queue(p->dev_sdtr_cmnd[tindex],
+ aic7xxx_negotiation_complete);
+ }
+}
+
/*+F*************************************************************************
* Function:
* aic7xxx_buildscb
}
}
}
- if ( (p->needwdtr & mask) &&
- !(p->wdtr_pending & mask) &&
- (scb->cmd->lun == 0) )
- {
- p->wdtr_pending |= mask;
- hscb->control |= MK_MESSAGE;
- if (p->needwdtr_copy & mask)
- scb->flags |= SCB_MSGOUT_WDTR_16BIT;
- else
- scb->flags |= SCB_MSGOUT_WDTR_8BIT;
- }
- else
+ if (p->dev_flags[TARGET_INDEX(cmd)] & DEVICE_SCANNED)
{
- if ( (p->needsdtr & mask) &&
- !(p->sdtr_pending & mask) &&
- !(p->wdtr_pending & mask) &&
- (scb->cmd->lun == 0) )
+ if ( (p->needwdtr & mask) && !(p->wdtr_pending & mask) )
+ {
+ if (cmd == p->dev_wdtr_cmnd[TARGET_INDEX(cmd)])
+ {
+ p->wdtr_pending |= mask;
+ scb->flags |= SCB_MSGOUT_WDTR_16BIT;
+ hscb->control &= DISCENB;
+ hscb->control |= MK_MESSAGE;
+ scb->tag_action = 0;
+ }
+ else
+ {
+ aic7xxx_build_negotiation_cmnd(p, cmd, TARGET_INDEX(cmd));
+ }
+ }
+ if ( (p->needsdtr & mask) && !(p->sdtr_pending & mask) )
{
- p->sdtr_pending |= mask;
- hscb->control |= MK_MESSAGE;
- scb->flags |= SCB_MSGOUT_SDTR;
+ if (cmd == p->dev_sdtr_cmnd[TARGET_INDEX(cmd)])
+ {
+ p->sdtr_pending |= mask;
+ scb->flags |= SCB_MSGOUT_SDTR;
+ hscb->control &= DISCENB;
+ hscb->control |= MK_MESSAGE;
+ scb->tag_action = 0;
+ }
+ else if (cmd != p->dev_wdtr_cmnd[TARGET_INDEX(cmd)])
+ {
+ aic7xxx_build_negotiation_cmnd(p, cmd, TARGET_INDEX(cmd));
+ }
}
}
hscb->target_channel_lun = ((cmd->target << 4) & 0xF0) |
}
}
- if (p->dev_active_cmds[tindex] > cmd->device->queue_depth)
+ if (p->dev_active_cmds[tindex] > (cmd->device->queue_depth + 1))
{
printk(WARN_LEAD "Commands queued exceeds queue "
"depth, active=%d\n",
aic7xxx_status(cmd) = 0;
cmd->result = 0;
cmd->host_scribble = NULL;
- memset(&cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+ memset(&cmd->sense_buffer[0], 0, sizeof(cmd->sense_buffer));
scb->flags |= SCB_ACTIVE | SCB_WAITINGQ;
{
aic7xxx_isr(p->irq, p, (void *)NULL);
pause_sequencer(p);
+ aic7xxx_done_cmds_complete(p);
}
if ((scb == NULL) || (cmd->serial_number != cmd->serial_number_at_timeout))
{
aic7xxx_isr(p->irq, p, (void *)NULL );
pause_sequencer(p);
+ aic7xxx_done_cmds_complete(p);
}
if (scb == NULL)
return (0);
}
+/*+F*************************************************************************
+ * Function:
+ * aic7xxx_release
+ *
+ * Description:
+ * Free the passed in Scsi_Host memory structures prior to unloading the
+ * module.
+ *-F*************************************************************************/
+int
+aic7xxx_release(struct Scsi_Host *host)
+{
+ struct aic7xxx_host *p = (struct aic7xxx_host *) host->hostdata;
+ struct aic7xxx_host *next, *prev;
+
+ if(p->irq)
+ free_irq(p->irq, p);
+ release_region(p->base, MAXREG - MINREG);
+ if(p->maddr)
+ {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+ vfree((void *) (((unsigned long) p->maddr) & PAGE_MASK));
+#else
+ iounmap((void *) (((unsigned long) p->maddr) & PAGE_MASK));
+#endif
+ }
+ prev = NULL;
+ next = first_aic7xxx;
+ while(next != NULL)
+ {
+ if(next == p)
+ {
+ if(prev == NULL)
+ first_aic7xxx = next->next;
+ else
+ prev->next = next->next;
+ }
+ else
+ {
+ prev = next;
+ }
+ next = next->next;
+ }
+ aic7xxx_free(p);
+ return(0);
+}
+
#include "aic7xxx_proc.c"
#ifdef MODULE
proc_info: aic7xxx_proc_info, \
name: NULL, \
detect: aic7xxx_detect, \
- release: NULL, \
+ release: aic7xxx_release, \
info: aic7xxx_info, \
command: NULL, \
queuecommand: aic7xxx_queue, \
proc_info: aic7xxx_proc_info, \
name: NULL, \
detect: aic7xxx_detect, \
- release: NULL, \
+ release: aic7xxx_release, \
info: aic7xxx_info, \
command: NULL, \
queuecommand: aic7xxx_queue, \
extern int aic7xxx_command(Scsi_Cmnd *);
extern int aic7xxx_reset(Scsi_Cmnd *, unsigned int);
extern int aic7xxx_abort(Scsi_Cmnd *);
+extern int aic7xxx_release(struct Scsi_Host *);
extern const char *aic7xxx_info(struct Scsi_Host *);
p->adapter_control);
size += sprintf(BLS, " Extended Translation: %sabled\n",
(p->flags & AHC_EXTEND_TRANS_A) ? "En" : "Dis");
- size += sprintf(BLS, " SCSI Bus Reset: %sabled\n",
- aic7xxx_no_reset ? "Dis" : "En");
size += sprintf(BLS, "Disconnect Enable Flags: 0x%04x\n", p->discenable);
if (p->type & AHC_ULTRA)
{
#define SCB_PAGING 0x8
#define TWIN_CHANNEL 0x4
#define TARGET_MODE 0x2
-struct patch {
+struct sequencer_patch {
int options;
int negative;
int begin;
int end;
-} patches[] = {
+} sequencer_patches[] = {
{ 0x00000002, 0, 0x001, 0x002 },
{ 0x00000002, 1, 0x002, 0x003 },
{ 0x00000004, 0, 0x009, 0x00d },
}
}
- /* If the DMA is active but not finished, we have the the case
+ /* If the DMA is active but not finished, we have the case
* that some other 5380 interrupt occurred within the DMA transfer.
* This means we have residual bytes, if the desired end address
* is not yet reached. Maybe we have to fetch some bytes from the
/*
- * linux/drivers/scsi/ide-scsi.c Version 0.31 - ALPHA Apr 3, 1998
+ * linux/drivers/scsi/ide-scsi.c Version 0.32 May 21, 1998
*
* Copyright (C) 1996, 1997 Gadi Oxman <gadio@netvision.net.il>
*/
* Ver 0.3 Jul 24 97 Add support for ATAPI PD/CD drives.
* Ver 0.31 Apr 3 98 Remove buggy MODE_SENSE6/MODE_SELECT6 translation.
* Add variable irq timeout support.
+ * Ver 0.32 May 21 98 Perform maximal data transfer when the drive wants
+ * to send us more data than would fit in our buffer.
*/
#include <linux/module.h>
if ( temp > pc->request_transfer) {
if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n");
- idescsi_discard_data (drive,bcount);
+ temp = pc->buffer_size - pc->actually_transferred;
+ if (temp) {
+ clear_bit(PC_WRITING, &pc->flags);
+ if (pc->sg)
+ idescsi_input_buffers(drive, pc, temp);
+ else
+ atapi_input_bytes(drive, pc->current_position, temp);
+ printk(KERN_ERR "ide-scsi: transferred %d of %d bytes\n", temp, bcount);
+ }
+ pc->actually_transferred += temp;
+ pc->current_position += temp;
+ idescsi_discard_data (drive,bcount - temp);
ide_set_handler (drive, &idescsi_pc_intr, get_timeout(pc));
return;
}
** we reach them (for forward jumps).
** Therefore we declare a struct here.
** If you make changes inside the script,
-** DONT FORGET TO CHANGE THE LENGTHS HERE!
+** DON'T FORGET TO CHANGE THE LENGTHS HERE!
**
**----------------------------------------------------------
*/
case 0x8:
/*
** JUMP / CALL
- ** dont't relocate if relative :-)
+ ** don't relocate if relative :-)
*/
if (opcode & 0x00800000)
relocs = 0;
/*
** Why not to try the immediate lower divisor and to choose
** the one that allows the fastest output speed ?
- ** We dont want input speed too much greater than output speed.
+ ** We don't want input speed too much greater than output speed.
*/
if (div >= 1 && fak < 8) {
u_long fak2, per2;
if (k)
return (r & 0xf0);
- /* Counter expired - Time out occured */
+ /* Counter expired - Time out occurred */
ppa_fail(host_no, DID_TIME_OUT);
printk("ppa timeout in ppa_wait\n");
return 0; /* command timed out */
unsigned char l = 0, h = 0;
int retv;
- /* First check for any errors that may of occured
+ /* First check for any errors that may have occurred
* Here we check for internal errors
*/
if (tmp->failed)
if (!buf || !cmdList) /* bad input ? */
return(NULL);
- if ((handle = (parseHandle*) kmalloc(sizeof(parseHandle), 1)) == 0)
+ if ((handle = (parseHandle*) kmalloc(sizeof(parseHandle), GFP_KERNEL)) == 0)
return(NULL); /* out of memory */
- if ((handle->cmdPos = (char**) kmalloc(sizeof(int), cmdNum)) == 0) {
+ if ((handle->cmdPos = (char**) kmalloc(sizeof(int) * cmdNum, GFP_KERNEL)) == 0) {
kfree(handle);
return(NULL); /* out of memory */
}
DMA numbers. Using the same values than with DOS/Win is a good idea. Don't
attempt to use the same IRQ or DMA channels twice.
-The SB mode of ATP is implemented so the the ATP driver just enables SB
+The SB mode of ATP is implemented so the ATP driver just enables SB
in the proper address. The SB driver handles the rest. You have to configure
both the SB driver and the SB mode of ATP to use the same IRQ, DMA and I/O
settings.
sound support during "make config"). Please refer to kernel documentation
for instructions about configuring and compiling kernel. File Readme.cards
contains card specific instructions for configuring this driver for
- use with various soundcards.
+ use with various sound cards.
Boot time configuration (using lilo and insmod)
-----------------------------------------------
/*
* XXX If f_owner is a process group, the
* negative return value will get converted
- * into an error. Oops. If we keep the the
+ * into an error. Oops. If we keep the
* current syscall conventions, the only way
* to fix this will be in libc.
*/
int error, slen;
slen = sprintf(silly, ".nfs%ld", inode->i_ino);
- if ((error = nfs_unlink(dir, silly, slen)) < 0) {
+ error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), silly);
+ nfs_lookup_cache_remove(dir, NULL, silly);
+ if (error < 0)
printk("NFS silly_rename cleanup failed (err = %d)\n",
-error);
- }
NFS_RENAMED_DIR(inode) = NULL;
+ iput(dir);
}
static int nfs_unlink(struct inode *dir, const char *name, int len)
static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
{
struct old_stat tmp;
+ static int nagcount = 0;
+
+ if (++nagcount < 5)
+ printk("VFS: Warning: %s using old stat() call. "
+ "Recompile your binary.\n",
+ current->comm);
- printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
- current->comm);
tmp.st_dev = kdev_t_to_nr(inode->i_dev);
tmp.st_ino = inode->i_ino;
tmp.st_mode = inode->i_mode;
struct inode *ret = NULL;
if (dir->u.umsdos_i.i_emd_dir != 0){
ret = iget (dir->i_sb,dir->u.umsdos_i.i_emd_dir);
- PRINTK (("deja trouve %d %x [%d] "
+ PRINTK (("deja trouve %d %x [%ld] "
,dir->u.umsdos_i.i_emd_dir,ret,ret->i_count));
}else{
umsdos_real_lookup (dir,UMSDOS_EMD_FILE,UMSDOS_EMD_NAMELEN,&ret);
{
PRINTK (("read inode %x ino = %d ",inode,inode->i_ino));
msdos_read_inode(inode);
- PRINTK (("ino = %d %d\n",inode->i_ino,inode->i_count));
+ PRINTK (("ino = %d %ld\n",inode->i_ino,inode->i_count));
if (S_ISDIR(inode->i_mode)
&& (inode->u.umsdos_i.u.dir_info.creating != 0
|| inode->u.umsdos_i.u.dir_info.looking != 0
if (ret == 0){
struct inode *inode = *result;
umsdos_lookup_patch (dir,inode,&info.entry,info.f_pos);
- PRINTK (("inode %p[%d] ",inode,inode->i_count));
+ PRINTK (("inode %p[%ld] ",inode,inode->i_count));
PRINTK (("Creation OK: [%d] %s %d pos %d\n",dir->i_ino
,info.fake.fname,current->pid,info.f_pos));
}else{
}else if ((ret = umsdos_nevercreat(dir,name,len,-EPERM))==0){
struct inode *olddir;
ret = umsdos_get_dirowner(oldinode,&olddir);
- PRINTK (("umsdos_link dir_owner = %d -> %p [%d] "
+ PRINTK (("umsdos_link dir_owner = %d -> %p [%ld] "
,oldinode->u.umsdos_i.i_dir_owner,olddir,olddir->i_count));
if (ret == 0){
struct umsdos_dirent entry;
ret = umsdos_newhidden (olddir,&info);
if (ret == 0){
olddir->i_count+=2;
- PRINTK (("olddir[%d] ",olddir->i_count));
+ PRINTK (("olddir[%ld] ",olddir->i_count));
ret = umsdos_rename_f (olddir,entry.name
,entry.name_len
,olddir,info.entry.name,info.entry.name_len
if (path == NULL){
ret = -ENOMEM;
}else{
- PRINTK (("olddir[%d] ",olddir->i_count));
+ PRINTK (("olddir[%ld] ",olddir->i_count));
ret = umsdos_locate_path (oldinode,path);
- PRINTK (("olddir[%d] ",olddir->i_count));
+ PRINTK (("olddir[%ld] ",olddir->i_count));
if (ret == 0){
olddir->i_count++;
ret = umsdos_symlink_x (olddir
if (sdir->i_count > 1){
ret = -EBUSY;
}else if ((empty = umsdos_isempty (sdir)) != 0){
- PRINTK (("isempty %d i_count %d ",empty,sdir->i_count));
+ PRINTK (("isempty %d i_count %ld ",empty,sdir->i_count));
/* check sticky bit */
if ( !(dir->i_mode & S_ISVTX) || fsuser() ||
current->fsuid == sdir->i_uid ||
if (ret == 0){
int empty;
if ((empty = umsdos_isempty (sdir)) != 0){
- PRINTK (("isempty %d i_count %d ",empty,sdir->i_count));
+ PRINTK (("isempty %d i_count %ld ",empty,sdir->i_count));
if (empty == 2){
/*
Not a Umsdos directory, so the previous msdos_rmdir
* this way. In front of 'return-eip' may be some data, depending on
* compilation, so we don't rely on this and save the pointer to 'oldregs'
* in 'regs32' above.
- * However, with GCC-2.7.2 and the the current CFLAGS you see exactly this:
+ * However, with GCC-2.7.2 and the current CFLAGS you see exactly this:
long return-eip; from call to vm86()
struct pt_regs oldregs; user space registers as saved by syscall
o eql load balancing driver. [TESTED]
o Token ring drivers. [TESTED]
o IPIP and tunnels [TESTED]
-o Fix ethernet/token ring promisc broadcast error [TESTED]
+o Fix Ethernet/token ring promisc broadcast error [TESTED]
(pkt_type set to OTHERHOST in error).
o Fixed bug in the routing caches [TESTED]
o Protocol header cache support [TESTED]
------->>>>> NET3 030 <<<<<----------
-o Long word align ethernet IP headers (64byte align for pentium) [TESTED]
+o Long word align Ethernet IP headers (64byte align for Pentium) [TESTED]
(less helpful than I'd have liked)
o Fixed variable length header support to really work [TESTED]
o Mend appletalk/ipx partially [TESTED]
slows fragmented I/O down, speeds up smaller
packets. UDP send ttcp can now touch 7.5Mbyte/sec
with nothing else going on. UDP recv is slower 8( [TESTED]
-o Fixed and enabled ethernet header caches [TESTED]
+o Fixed and enabled Ethernet header caches [TESTED]
o Removed junk from igmp [TESTED]
o Obscure UDP/copy&sum bug fix [TESTED]
o Fixed multicast [TESTED]
o AF_UNIX smarter buffer driving [TESTED]
o AF_UNIX full BSD semantics on STREAM writes [TESTED]
o IOVEC's support repeated calls to copy more [TESTED]
-o Zero fragment 'solaris nfs' bug fixed <Werner> [TESTED]
+o Zero fragment 'Solaris NFS' bug fixed <Werner> [TESTED]
o NetROM supports sendmsg/recvmsg [TESTED]
o Sendmsg verify_iovec bugfix [TESTED]
o ARP PERM is really permanent now <Craig> [TESTED]
lose one frame per window full of data without measurable speed loss.
4. RFC1323. These are the extensions for very fast nets.
-RFC1323 will be useful for Linux talking to systems over 100Mb/sec
-ethernet and over ATM as it allows large windows and protects from some
+RFC1323 will be useful for Linux talking to systems over 100 Mb/sec
+Ethernet and over ATM as it allows large windows and protects from some
potential high speed TCP problems.
6. Delayed ack. This is mostly supported but not actually set up and
MAX_LINKS Maximum number of netlink minor devices. (1-32)
MAX_QBYTES Size of a netlink device queue (tunable)
RIF_TABLE_SIZE Token ring RIF cache size (tunable)
-AARP_HASH_SIZE Size of appletalk hash table (tunable)
+AARP_HASH_SIZE Size of Appletalk hash table (tunable)
AX25_DEF_T1 AX.25 parameters. These are all tunable via
AX25_DEF_T2 SIOCAX25SETPARMS
AX25_DEF_T3 T1-T3,N2 have the meanings in the specification
if(sk->ip_xmit_timeout==TIME_KEEPOPEN)
tcp_reset_xmit_timer(sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
}
- return 0;
+ return 1;
}