mirror of https://github.com/tLDP/LDP
1949 lines
104 KiB
Plaintext
1949 lines
104 KiB
Plaintext
<!doctype linuxdoc system>
|
|
<article>
|
|
<title> Plug-and-Play-HOWTO </title>
|
|
<author>David S.Lawyer
|
|
<tt><url url="mailto:dave@lafn.org"></tt>
|
|
<date> v1.07, August 2003
|
|
|
|
<!--
|
|
Revision history:
|
|
v1.07 August 2003: New M$ url, reserve resources for isa-pnp, lspci+,
|
|
scanport may not find hdw, finding dev. and config.
|
|
v1.06 September 2002: Revised about telling the BIOS if the OS is PnP
|
|
v1.05 July 2002: typos: or => of, and => an, A Allocate => Allocate,
|
|
programs => program; Dell PCs: "Plug and Play Configuration Error",
|
|
clarity on telling BIOS if your OS is PnP, "Intro to PnP" had truncated
|
|
sentence, routing IRQs on PCI clarified, Change of emphasis in entire
|
|
doc: Linux is now a PnP OS (sort of), PCI has almost replaced ISA
|
|
v1.04 March 2002 finding a device driver, PCI serial ports,
|
|
alias example in modules.conf, PnP needed for linmodems
|
|
v1.03 August 2001: error messages, boot-prompt parameters
|
|
v1.02 July 2001: PCI config regs.
|
|
v1.01 April 2001: less shortage today of bus-resources, clarity in sect. 2,
|
|
Windows 2000 OK (even if "not a PnP OS" in CMOS)
|
|
v1.00 November 2000: "skip file" workaround for reconfiguring under Windows.
|
|
PCI interrupt details: X, W were transposed, rewrote, mentioned MSI,
|
|
etc. General Introduction added. Revised "How Linux Does PnP",
|
|
etc.. Patching kernel to make it PnP no longer feasible. Drivers do
|
|
more now due to kernel-provided functions.
|
|
v0.12 June 2000 scanpci, workaround for Dos zeroing PCI IRQs.
|
|
v0.11 May 2000 scanport utility, many typos fixed, setpci hard to use
|
|
v0.10 2 March 2000 typo: /bus/pnp/devices, lspci+, book "Programming
|
|
..."
|
|
v0.09 /proc/bus/pci/devices too cryptic,
|
|
v0.08 my new email
|
|
v0.07 in Windows: remove devices
|
|
v0.06 Oct. 1999 in Windows: forced+, legacy into ESCD, pause key (bios)
|
|
v0.05 Aug. 1999 lspci, url for isapnp, tell the dev. driver, PCI still
|
|
needs PnP
|
|
v0.04 June 1999 alternatives to reinstall Windows?, add D.D. url
|
|
v0.03 May 1999 typos, reinstall Windows, clarity, removed D.D. url
|
|
v0.02 Apr. 1999 /proc/... doesn't show hdw config (except pci)
|
|
v0.01 Mar. 1999 serial PnP spec, PCI interrupts, no DMA on PCI,
|
|
dumpregs for pnpdump , Bus Mastering DMA, clarity rewrites, pciutils
|
|
kernel 2.2 /proc tree, IO range check, Windows may not update ESCD
|
|
v0.00 Nov. 1998
|
|
-->
|
|
<abstract>
|
|
Help with understanding and dealing with the complex Plug-and-Play
|
|
(PnP) issue. How to get PnP to work on your PC (if it doesn't already).
|
|
It doesn't cover what's called "Universal Plug and Play"
|
|
(UPnP). See <ref id="UPnP_" name="Universal Plug and Play (UPnP)"
|
|
</abstract>
|
|
<toc>
|
|
|
|
<sect> Introduction
|
|
|
|
<sect1>1. Copyright, Trademarks, Disclaimer, & Credits
|
|
|
|
<sect2> Copyright
|
|
<p> Copyright (c) 1998-2003 by David S. Lawyer <url url="mailto:dave@lafn.org">
|
|
<!-- license.D begin -->
|
|
|
|
Please freely copy and distribute (sell or give away) this document
|
|
in any format. Send any corrections and comments to the document
|
|
maintainer. You may create a derivative work and distribute it
|
|
provided that you:
|
|
|
|
<enum>
|
|
<item> If it's not a translation: Email a copy of your derivative work
|
|
(in a format LDP accepts) to the author(s) and maintainer (could be
|
|
the same person). If you don't get a response then email the LDP
|
|
(Linux Documentation Project): submit@en.tldp.org.
|
|
<item>License the derivative work in the spirit of this license or use
|
|
GPL. Include a copyright notice and at least a pointer to the
|
|
license used.
|
|
<item>Give due credit to previous authors and major contributors.
|
|
</enum>
|
|
|
|
If you're considering making a derived work other than a
|
|
translation, it's requested that you discuss your plans with the
|
|
current maintainer.
|
|
|
|
<sect2>Disclaimer
|
|
<p> While I haven't intentionally tried to mislead you, there are
|
|
likely a number of errors in this document. Please let me know about
|
|
them. Since this is free documentation, it should be obvious that I
|
|
cannot be held legally responsible for any errors.
|
|
|
|
<sect2>Trademarks.
|
|
<p> Any brand names (starts with a capital letter such as MS Windows)
|
|
should be assumed to be a trademark). Such trademarks belong to their
|
|
respective owners. <!-- license.D end -->
|
|
|
|
|
|
<sect2> Credits
|
|
<p>
|
|
<itemize>
|
|
<item> Daniel Scott proofread this in March 2000 and found many
|
|
typos, etc.
|
|
<item> Pete Barrett gave a workaround to prevent Windows from zeroing
|
|
PCI IRQs.
|
|
</itemize>
|
|
|
|
<sect1> Future Plans; You Can Help
|
|
<p> Please let me know of any errors in facts, opinions, logic,
|
|
spelling, grammar, clarity, links, etc. But first, if the date is
|
|
over a couple of months old, check to see that you have the latest
|
|
version. Please send me any info that you think belongs in this
|
|
document.
|
|
|
|
I haven't studied the code used by various Linux drivers to implement
|
|
Plug-and-Play. Nor have I looked into the details of how the kernel
|
|
deals with it. Thus this HOWTO is still incomplete. It needs to
|
|
explain more about the PCI bus and about "hot swapping". It likely
|
|
has some inaccuracies (let me know where I'm wrong). In this HOWTO
|
|
I've sometimes used ?? to indicate that I don't really know the
|
|
answer.
|
|
|
|
<sect1> New Versions of this HOWTO
|
|
<p> New versions of the Plug-and-Play-HOWTO should appear every few
|
|
months or so and will be available to browse and/or download at LDP
|
|
mirror sites. For a list of mirror sites see: <url
|
|
url="http://tldp.org/mirrors.html">. Various formats are
|
|
available. If you only want to quickly check the date of the latest
|
|
version look at: <url
|
|
url="http://tldp.org/HOWTO/Plug-and-Play-HOWTO.html">. The
|
|
version you are now reading is: v1.07, August 2003 .
|
|
|
|
<sect1> New in Recent Versions
|
|
<p> For a full revision history going back to the first version see
|
|
the source file (in linuxdoc format) at <url
|
|
url="http://www.ibiblio.org/pub/linux/docs/HOWTO/other-formats/sgml/Plug-and-Play-HOWTO.sgml.gz">.
|
|
|
|
v1.07 August 2003: New M$ url, reserve resources for isa-pnp, lspci+,
|
|
scanport may not find hdw, finding dev. and config.
|
|
v1.06 September 2002: Revised about telling the BIOS if the OS is
|
|
PnP<newline>
|
|
v1.05 July 2002 typos: or => of, and => an, A Allocate => Allocate,
|
|
programs => program; Dell PCs: "Plug and Play Configuration Error",
|
|
clarity on telling BIOS if your OS is PnP, "Intro to PnP" had truncated
|
|
sentence, routing IRQs on PCI clarified, Change of emphasis in entire
|
|
doc: Linux is now a PnP OS (sort of), PCI has almost replaced
|
|
ISA<newline>
|
|
|
|
The version 1.0 (Nov. 2000) was long overdue and recognized that the
|
|
kernel is doing more in helping device drivers set up PnP. Kernel 2.4
|
|
is significantly improved in this respect. There's still a lot of
|
|
improvement needed in both this HOWTO and the way that Linux does
|
|
PnP.
|
|
|
|
<sect1> General Introduction. Do you need this HOWTO?
|
|
<p> Plug-and-play (PnP) is a system which automatically detects
|
|
devices such as disks, sound cards, ethernet cards, modems, etc. It
|
|
also does some low-level configuring of them. To be detected by PnP, the
|
|
device must be designed for PnP. Non-PnP devices (or PnP devices which
|
|
have been correctly PnP-configured), can often be detected by
|
|
non-PnP methods. The modern PCI bus is inherently PnP while the old
|
|
ISA bus originally wasn't PnP but had PnP support added to it later.
|
|
So often PnP is used to only mean PnP for the old ISA bus. In this
|
|
HOWTO, PnP means PnP for both the ISA and the PCI bus.
|
|
|
|
As time goes by the Linux kernel is becoming better at supporting PnP.
|
|
In the 20th century, one could say that Linux was not really a PnP OS.
|
|
But it's becoming a PnP OS even thought it still doesn't have a fully
|
|
centralized plug-and-play system. It does provide programs that
|
|
device drivers can call on to do their own plug-and-play. The kernel
|
|
also reads all configuration registers of all devices and maintains a
|
|
table of them that device drivers can consult. Many drivers take
|
|
advantage of this and find your PnP devices OK. The BIOS hardware of
|
|
your PC likely may also do some plug-and-play work. Thus if
|
|
everything works OK PnP-wise, you can use your computer without
|
|
needing to know anything about plug-and-play. But if some devices
|
|
which are supported by Linux don't work (because they're not discovered
|
|
or configured correctly by PnP) then you may need to read some of this
|
|
HOWTO. You'll learn not only about PnP but also learn about how
|
|
communication takes place inside the computer.
|
|
|
|
If you're having problems with a device, watch the messages displayed
|
|
at boot-time (go back thru them using Shift-PageUp). Check to see that you
|
|
have the right driver for a device, and that the driver is being found
|
|
and used. If the driver is a module, type "lsmod" (as the root user)
|
|
to see it it's loaded (in use). If it's not a module then it should
|
|
be built into the kernel. There should be a file somewhere that tells
|
|
what drivers are built into the kernel: (such as: /boot/config-2.4-20
|
|
in Debian). Sometimes a device name (such as /dev/eth0) doesn't get a
|
|
driver assigned to it unless the assignment is found in the file:
|
|
/etc/modules.conf: For example, to assign the "tulip" driver to eth0
|
|
you add a line to this file: "alias eth0 tulip".
|
|
|
|
This HOWTO doesn't cover the problem of finding and installing device
|
|
drivers. Perhaps it should. One problem is that a certain brand of a
|
|
card (or other physical device) may not say what kind of chips are
|
|
used in it. The driver name is often the same as the chip name and
|
|
not the brand name. One way to start to check on a driver is to see
|
|
if it is discussed in the kernel documentation, in another HOWTO, or
|
|
on the Internet. Warning: Such documentation may be out of date.
|
|
|
|
In this document I mention so many things that can go wrong that one
|
|
who believes in Murphy's Law (If something can go wrong it will) may
|
|
become quite alarmed. But for PnP for most people: If something can
|
|
go wrong it usually doesn't. Remember that sometimes problems which
|
|
seem to be PnP related are actually due to defective hardware or to
|
|
hardware that doesn't fully conform to PnP specs.
|
|
|
|
<sect> What PnP Should Do: Allocate "Bus-Resources"
|
|
<sect1> What is Plug-and-Play (PnP)?
|
|
<p> If you don't understand this section, read the next section
|
|
<ref id="find_dev" name="How a Computer Finds Devices (and
|
|
conversely)">
|
|
|
|
<p> Oversimplified, Plug-and-Play automatically tells the software
|
|
(device drivers) where to find various pieces of hardware (devices)
|
|
such as modems, network cards, sound cards, etc. Plug-and-Play's task
|
|
is to match up physical devices with the software (device drivers)
|
|
that operates them and to establish channels of communication between
|
|
each physical device and its driver. In order to achieve this, PnP
|
|
allocates the following "bus-resources" to both drivers and hardware:
|
|
I/O addresses, memory regions, IRQs, DMA channels (ISA bus only).
|
|
These 4 things are sometimes called "1st order resources" or just
|
|
"resources". If you don't understand what these 4 bus-resources are,
|
|
read the following subsections of this HOWTO: I/O Addresses, IRQs, DMA
|
|
Channels, Memory Regions. An article in Linux Gazette regarding 3 of
|
|
these bus-resources is <htmlurl
|
|
url="http://www.linuxgazette.com/issue38/blanchard.html"
|
|
name="Introduction to IRQs, DMAs and Base Addresses">. Once these
|
|
bus-resources have been assigned (and if the correct driver is
|
|
installed), the "files" for such devices in the /dev directory are
|
|
ready to use.
|
|
|
|
This PnP assignment of bus-resources is sometimes called "configuring"
|
|
but it is only a low level type of configuring. The /etc directory
|
|
has many configuration files but most of them are not for PnP
|
|
configuring. So most of the configuring of hardware devices has
|
|
nothing to do with PnP or bus-resources. For, example the
|
|
initializing of a modem by an "init string" or setting it's speed is
|
|
not PnP. Thus when talking about PnP, "configuring" means only a
|
|
certain type of configuring. While other documentation (such a for MS
|
|
Windows) simply calls bus-resources "resources", I have used the term
|
|
"bus-resources" so as to distinguish it from the multitude of other
|
|
kinds of resources.
|
|
|
|
<sect1> How a Computer Finds Devices (and conversely) <label
|
|
id="find_dev">
|
|
<p> A computer consists of a CPU/processor to do the computing and RAM
|
|
memory to store programs and data (for fast access). In addition,
|
|
there are a number of devices such as various kinds of disk-drives, a
|
|
video card, a keyboard, network cards, modem cards, sound cards, the
|
|
USB bus, serial and parallel ports, etc. There is also a power supply
|
|
to provide electric energy, various buses on a motherboard to connect
|
|
the devices to the CPU, and a case to put all this into.
|
|
|
|
In olden days most all devices had their own plug-in cards (printed
|
|
circuit boards). Today, in addition to plug-in cards, many "devices"
|
|
are small chips permanently mounted on the "motherboard".
|
|
Furthermore, cards which plug into the motherboard may contain more
|
|
than one device. Memory chips are also sometimes considered to be
|
|
devices but are not plug-and-play in the sense used in this HOWTO.
|
|
|
|
For the computer system to work right, each device must be under the
|
|
control of its "device driver". This is software which is a part of
|
|
the operating system (perhaps loaded as a module) and runs on the CPU.
|
|
Device drivers are associated with "special files" in the /dev
|
|
directory although they are not really files. They have names such as
|
|
hda3 (third partition on hard drive a), ttyS1 (the second serial port),
|
|
eth0 (the first ethernet card), etc.
|
|
|
|
To make matters more complicated, the particular device driver
|
|
selected, say for example eth0, may depend on the type of ethernet
|
|
card you have. Thus eth0 can't just be assigned to any ethernet
|
|
driver. It must be assigned to a certain driver that will work for
|
|
the type of ethernet card you have installed. If the driver is a
|
|
module, some of these assignments might be found in /etc/modules.conf
|
|
(called "alias") while others may reside in an internal kernel table.
|
|
For example, if you have an ethernet card that uses the "tulip" chip
|
|
put "alias eth0 tulip" into /etc/modules.conf so that when your
|
|
computer asks for eth0 it finds the tulip driver. Other device names
|
|
may have a standard driver associated with them so the above isn't
|
|
always required.
|
|
|
|
To control a device, the CPU (under the control of the device driver)
|
|
sends commands and data to, and reads status and data from the
|
|
various devices. In order to do this each device driver must know the
|
|
address of the device it controls. Knowing such an address is
|
|
equivalent to setting up a communication channel, even though the
|
|
physical "channel" is actually the data bus inside the PC which is
|
|
shared with almost everything else.
|
|
|
|
This communication channel is actually a little more complex than
|
|
described above. An "address" is actually a range of addresses so
|
|
that sometimes the word "range" is used instead of "address". There
|
|
could even be more that one range (with no overlapping) for a single
|
|
device. Also, there is a reverse part of the channel (known as
|
|
interrupts) which allows devices to send an urgent "help" request to
|
|
their device driver.
|
|
|
|
<sect1> Addresses
|
|
<p> PCs have 3 address spaces: I/O, main memory (IO memory), and
|
|
configuration (except that the old ISA bus lacks a genuine
|
|
"configuration" address space). All of these 3 types of addresses
|
|
share the same bus inside the PC. But the presence or absence of
|
|
voltage on certain dedicated wires on the PC's bus tells which "space"
|
|
an address is in: I/O, main memory, (see <ref id="mem_" name="Memory
|
|
Ranges">), or configuration. See <ref id="address_details"
|
|
name="Address Details"> for more details. Only two of these 3 address
|
|
spaces are used for device I/O: I/0 and main memory. I/O stands for
|
|
Input-Output.
|
|
|
|
<sect1> I/O Addresses and Allocating Them
|
|
<p> Devices were originally located in I/O address space but today
|
|
they may use space in main memory. An I/0 address is sometimes just
|
|
called "I/O", "IO", "i/o" or "io". The terms "I/O port" or "I/O
|
|
range" are also used. Don't confuse these IO ports with "IO memory"
|
|
located in main memory. There are two main steps to allocate the I/O
|
|
addresses (or some other bus-resources such as interrupts on the ISA
|
|
bus):
|
|
|
|
<enum>
|
|
<item> Set the I/O address, etc. on the card (in one of its registers)
|
|
<item> Let its device driver know what this I/O address, etc. is
|
|
</enum>
|
|
|
|
Often, the device driver does both of these.
|
|
The two step process above is something like the two part problem of
|
|
finding someone's house number on a street. Someone must install a
|
|
number on the front of the house so that it may be found and then you
|
|
must obtain (and write down) this house number so that you can find
|
|
the house. In computers the device hardware must first get the
|
|
address it will use set a special register and then the device driver
|
|
must obtain this address. Both of these must be done, either
|
|
automatically by software or by entering the data manually into files.
|
|
Problems may occur when only one of them gets done (or is attempted).
|
|
|
|
For manual PnP configuration some people make the mistake of doing
|
|
only one of these and then wonder why the computer can't find the
|
|
device. For example, they may use "setserial" to assign an address
|
|
to a serial port without realizing that this only tells the driver an
|
|
address. It doesn't set the address in the serial port hardware
|
|
itself. If the serial port hardware doesn't have the address you told
|
|
setserial (or doesn't have any address set in it) then you're in
|
|
trouble.
|
|
|
|
An obvious requirement is that before the device driver can use an
|
|
address it must be first set in the physical device (such as a card).
|
|
Since device drivers often start up soon after you start the computer,
|
|
they sometimes try to access a card (to see if it's there, etc.)
|
|
before the address has been set in the card by a PnP configuration
|
|
program. Then you see an error message that they can't find the card
|
|
even though it's there (but doesn't yet have an address).
|
|
|
|
What was said in the last few paragraphs regarding I/O addresses applies
|
|
with equal force to most other bus-resources: <ref id="mem_" name="Memory
|
|
Ranges">, <ref id="interrupt_over" name="IRQs --Overview"> and <ref
|
|
id="dma_" name="DMA Channels">. What these are will be explained in
|
|
the next 3 sections. The exception is that IRQs on the PCI bus are
|
|
not set by a card register but are set by a special routing chip on
|
|
the motherboard.
|
|
|
|
<sect1> Memory Ranges <label id="mem_">
|
|
<p> Many devices are assigned address space in main memory. It's
|
|
sometimes called "shared memory" or "memory-mapped IO" or "IO memory".
|
|
This memory is physically located in the device. When discussing
|
|
bus-resources it's often just called "memory", "mem", or "iomem". In
|
|
addition to using such "memory", such a device might also use
|
|
conventional IO address space. To see what mem is in use on your
|
|
computer, look at /proc/iomem. This "file" includes the memory range
|
|
used by your ordinary RAM memory chips but this really not strictly a
|
|
part of iomem.
|
|
|
|
When you insert a card that uses iomem, you are in effect also
|
|
inserting a memory module for main memory. A high address is selected
|
|
for it by PnP so that it doesn't conflict with main memory chips.
|
|
This memory can either be ROM (Read Only Memory) or shared memory.
|
|
Shared memory is shared between the device and the CPU (running the
|
|
device driver) just as IO address space is shared between the device
|
|
and the CPU. This shared memory serves as a means of data "transfer"
|
|
between the device and main memory. It's IO but it's not done in IO
|
|
space. Both the card and the device driver need to know where it is.
|
|
|
|
ROM is different. It is likely a program (perhaps a device driver)
|
|
which will be used with the device. It could be initialization code
|
|
so that a device driver is still required. Hopefully, it will work
|
|
with Linux and not just MS Windows. It may need to be shadowed
|
|
which means that it is copied to your main memory chips in order to
|
|
run faster. Once it's shadowed it's no longer "read only".
|
|
|
|
<sect1> IRQs --Overview <label id="interrupt_over">
|
|
<p> After reading this you may read <ref id="interrupt_detail" name=
|
|
"Interrupts --Details"> for many more details. The following is
|
|
intentionally oversimplified: Besides the address, there is also an
|
|
interrupt number to deal with (such as IRQ 5). It's called an IRQ
|
|
(Interrupt ReQuest) number or just an "irq" for short. We already
|
|
mentioned above that the device driver must know the address of a card
|
|
in order to be able to communicate with it.
|
|
|
|
But what about communication in the opposite direction? Suppose the
|
|
device needs to tell its device driver something immediately? For
|
|
example, the device may have just received a lot of bytes destined for
|
|
main memory and the device needs to tell its driver to fetch these
|
|
bytes at once and transfer them from the device's nearly full buffer
|
|
into main memory. Another example is to signal the driver that the
|
|
device has finished sending out a bunch of bytes and is now waiting
|
|
for some more bytes from the driver so it can send them too.
|
|
|
|
How should the device rapidly signal its driver? It may not be able
|
|
to use the main data bus since it's likely already in use. Instead it
|
|
puts a voltage on a dedicated interrupt wire (part of the bus) which
|
|
is often reserved for that device alone. This voltage signal is
|
|
called an Interrupt ReQuest (IRQ) or just an "interrupt" for short.
|
|
There are the equivalent of 16 such wires in a PC and each wire leads
|
|
(indirectly) to a certain device driver. Each wire has a unique IRQ
|
|
(Interrupt ReQuest) number. The device must put its interrupt on the
|
|
correct wire and the device driver must listen for the interrupt on
|
|
the correct wire. Which wire the device sends help requests on is
|
|
determined by the IRQ number stored in the device. This same IRQ
|
|
number must be known to the device driver so that the device driver
|
|
knows which IRQ line to listen on.
|
|
|
|
Once the device driver gets the interrupt from the device it must find
|
|
out why the interrupt was issued and take appropriate action to
|
|
service the interrupt. On the ISA bus each device usually needs its
|
|
own unique IRQ number. For the PCI bus and other special cases the
|
|
sharing of IRQs is allowed and the IRQ assignment is determined by a
|
|
programmable routing chip. See <ref id="interrupt_detail" name=
|
|
"Interrupts --Details"> for how this works.
|
|
|
|
<sect1> DMA Channels <label id="dma_"> (ISA bus only)
|
|
<p> DMA channels are only for the ISA bus. DMA stands for "Direct Memory
|
|
Access". This is where a device is allowed to take over the main
|
|
computer bus from the CPU and transfer bytes directly to main memory.
|
|
Normally the CPU would make such a transfer in a two step process:
|
|
<enum>
|
|
<item>reading from the I/O memory space of the device and putting these
|
|
bytes into the CPU itself
|
|
<item> writing these bytes from the CPU to main memory
|
|
</enum>
|
|
<enum>
|
|
<item> With DMA it's usually a one step process of sending the bytes
|
|
directly from the device to memory
|
|
</enum>
|
|
The device must have such capabilities built into its hardware and
|
|
thus not all devices can do DMA. While DMA is going on the CPU can't
|
|
do too much since the main bus is being used by the DMA transfer.
|
|
|
|
The PCI bus doesn't really have any DMA but instead it has something
|
|
even better: bus mastering. It works something like DMA and is
|
|
sometimes called DMA (for example, hard disk drives that call
|
|
themselves "UltraDMA"). It allows devices to temporarily become bus
|
|
masters and to transfer bytes almost like the bus master was the CPU.
|
|
It doesn't use any channel numbers since the organization of the PCI
|
|
bus is such that the PCI hardware knows which device is currently the
|
|
bus master and which device is requesting to become a bus master.
|
|
Thus there is no resource allocation of DMA channels for the PCI bus.
|
|
|
|
When a device on the ISA bus wants to do DMA it issues a DMA-request
|
|
using dedicated DMA request wires much like an interrupt request. DMA
|
|
actually could have been handled by using interrupts but this would
|
|
introduce some delays so it's faster to do it by having a special type
|
|
of interrupt known as a DMA-request. Like interrupts, DMA-requests
|
|
are numbered so as to identify which device is making the request.
|
|
This number is called a DMA-channel. Since DMA transfers all use the
|
|
main bus (and only one can run at a time) they all actually use the
|
|
same channel but the "DMA channel" number serves to identify who is
|
|
using the "channel". Hardware registers exist on the motherboard
|
|
which store the current status of each "channel". Thus in order to
|
|
issue a DMA-request, the device must know its DMA-channel number which
|
|
must be stored in a special register on the physical device.
|
|
|
|
<sect1> "Resources" for both Device and Driver
|
|
<p> Thus device drivers must be "attached" in some way to the hardware
|
|
they control. This is done by allocating bus-resources (I/O, Memory,
|
|
IRQ's, DMA's) to both the physical device and the device driver
|
|
software. For example, a serial port uses only 2 (out of 4 possible)
|
|
resources: an IRQ and an I/O address. Both of these values must be
|
|
supplied to the device driver and the physical device. The driver
|
|
(and its device) is also given a name in the /dev directory (such as
|
|
ttyS1). The address and IRQ number is stored by the physical device
|
|
in configuration registers on its card (or in a chip on the
|
|
motherboard). For the case of jumpers, it's the location of the
|
|
jumpers themselves that store the bus-resource configuration in the
|
|
device hardware (on the card, etc.). For the case of PnP, the
|
|
configuration register data is usually lost when the PC is powered
|
|
down (turned off) so that the bus-resource data must be supplied to
|
|
each device anew each time the PC is powered on.
|
|
|
|
<sect1> The Problem
|
|
<p> The architecture of the PC provides only a limited number of
|
|
IRQ's, DMA channels, I/O address, and memory regions. If there were
|
|
only several devices and they all had standardized bus-resource data
|
|
(such as unique I/O addresses and IRQ numbers) there would be no
|
|
problem of attaching device drivers to devices. Each device would
|
|
have a fixed resources which would not conflict with any other device
|
|
on your computer. No two devices would have the same addresses, there
|
|
would be no IRQ conflicts, etc. Each driver would be programmed with
|
|
the unique addresses, IRQ, etc. hard-coded into the program. Life
|
|
would be simple.
|
|
|
|
But it's not. Not only are there so many different devices today that
|
|
conflicts are frequent, but one sometimes needs to have more than one of
|
|
the same type of device. For example, one may want to have a few
|
|
different disk-drives, a few network cards, etc. For these reasons
|
|
devices need to have some flexibility so that they can be set to
|
|
whatever address, IRQ, etc. is needed to avoid conflicts. But some
|
|
IRQ's and addresses are pretty standard such as the ones for the clock
|
|
and keyboard. These don't need such flexibility.
|
|
|
|
Besides the problem of conflicting allocation of bus-resources, there
|
|
is a problem of making a mistake in telling the device driver what the
|
|
bus-resources are for the case of manual configuration. For example,
|
|
suppose that you enter IRQ 4 in a configuration file when the device
|
|
is actually set at IRQ 5. This is another type of bus-resource
|
|
allocation error.
|
|
|
|
The allocation of bus-resources, if done correctly, establishes
|
|
channels of communication between physical hardware and their device
|
|
drivers. For example, if a certain I/O address range (resource) is
|
|
allocated to both a device driver and a piece of hardware, then this
|
|
has established a one-way communication channel between them. The
|
|
driver may send commands and other info to the device. It's actually a
|
|
little more than one-way since the driver may get information from the
|
|
device by reading its registers. But the device can't initiate any
|
|
communication this way. To initiate communication the device needs an
|
|
IRQ so it can send interrupts to its driver. This creates a two-way
|
|
communication channel where both the driver and the physical device
|
|
can initiate communication.
|
|
|
|
<sect1> PnP Finds Devices Plugged Into Serial Ports
|
|
<p> External devices that connect to the serial port via a cable (such
|
|
as external modems) can also be called Plug-and-Play. Since only the
|
|
serial port itself needs bus-resources (an IRQ and I/O address) there are
|
|
no bus-resources to allocate to such plug-in devices. In this case,
|
|
PnP is used only to identify the modem (read it's model code number).
|
|
This could be important if the modem is a software modem (linmodem)
|
|
and requires a special driver. There is a special PnP specification
|
|
for such external serial devices (something connected to the serial
|
|
port).
|
|
|
|
Linux doesn't support this yet ?? For a hardware modem, the ordinary
|
|
serial driver will work OK so there's little need for using the
|
|
special serial PnP to find a driver. You still need to tell the
|
|
communications program what port (such as /dev/ttyS1) the modem is on.
|
|
With PnP you wouldn't need to even do this. With the advent of
|
|
software modems that have Linux drivers (linmodems), it would be nice
|
|
to have the appropriate driver install itself automatically via PnP.
|
|
|
|
<sect> The Plug-and-Play (PnP) Solution
|
|
<sect1> Introduction to PnP
|
|
<p> The term Plug-and-Play (PnP) has various meanings. In the broad
|
|
sense it is just auto-configuration where one just plugs in a device
|
|
and it configures itself. In the sense used in this HOWTO, the
|
|
configuration is only that of configuring PnP bus-resources and letting
|
|
the device drivers know about it. In a narrower sense it is just
|
|
setting bus-resources in the hardware devices. For the case of Linux,
|
|
it is often just a driver giving a command to set the bus-resources in
|
|
it's device or determining how the BIOS has set them. "PnP" often
|
|
means just PnP on the ISA bus so the message from isapnp: "No Plug and
|
|
Play device found" just means that no ISA PnP devices were found. The
|
|
standard PCI specifications (which are not called "PnP") provide the
|
|
equivalent of PnP for the PCI bus.
|
|
|
|
PnP matches up devices with their device drivers and specifies their
|
|
communication channels. On the ISA bus before Plug-and-Play, the
|
|
bus-resources were formerly set in hardware devices by jumpers or
|
|
switches. Software drivers were assigned bus-resources by
|
|
configuration files (or the like) or by probing the for the device at
|
|
addresses where it's expected to reside. The PCI bus was PnP-like
|
|
from the beginning but at first it wasn't called PnP (and often still
|
|
isn't called PnP). While the PCI bus specifications don't use the
|
|
term PnP, it supports in hardware what today is called PnP.
|
|
|
|
<sect1> How It Works (simplified)
|
|
<p> Here's how PnP should work in theory. The PnP
|
|
configuration program finds all PnP devices and asks each what
|
|
bus-resources it needs. Then it checks what bus-resources (IRQs,
|
|
etc.) it has to give away. Of course, if it has reserved
|
|
bus-resources used by non-PnP (legacy) devices (if it knows about
|
|
them) it doesn't give these away. Then it uses some criteria (not
|
|
specified by PnP specifications) to give out the bus-resources so that
|
|
there are no conflicts and so that all devices get what they need (if
|
|
possible). It then tells each physical device what bus-resources are
|
|
assigned to it and the devices set themselves up to use only the
|
|
assigned bus-resources. Then the device drivers somehow find out what
|
|
bus-resources their devices use and are thus able to communicate
|
|
effectively with the devices they control.
|
|
|
|
For example, suppose a card needs one interrupt (IRQ number) and 1 MB
|
|
of shared memory. The PnP program reads this request from the card.
|
|
It then assigns the card IRQ5 and 1 MB of memory addresses space,
|
|
starting at address 0xe9000000. It then informs the device driver of
|
|
what it's done (except the BIOS can't do this). It's not always this
|
|
simple as the card (or routing table for PCI) may specify that it can
|
|
only use certain IRQ numbers or that the 1 MB of memory must lie
|
|
within a certain range of addresses. The details are different for
|
|
the PCI and ISA buses with more complexity on the ISA bus.
|
|
|
|
One way commonly used to allocate resources is to start with one
|
|
device and allocate it bus-resources. Then do the same for the next
|
|
device, etc. Then if finally all devices get allocated resources
|
|
without conflicts, then all is OK. But if allocating a needed
|
|
resource would create a conflict, then it's necessary to go back and
|
|
try to make some changes in previous allocations so as to obtain the
|
|
needed bus-resource. This is called rebalancing. Linux doesn't do
|
|
rebalancing but MS Windows does in some cases. For Linux, all this is
|
|
done by the BIOS and/or kernel and/or device drivers. In Linux the
|
|
device driver doesn't allocate any resources until the driver starts
|
|
up, so one way to avoid conflicts is just not to start any device that
|
|
might cause a conflict.
|
|
|
|
There are some shortcuts that PnP software may use. One is to keep
|
|
track of how it assigned bus-resources at the last configuration (when the
|
|
computer was last used) and reuse this. Windows9x (and later) and
|
|
PnP BIOSs do this but standard Linux doesn't. Windows9x (and later)
|
|
stores this info in its "Registry" on the hard disk and a PnP BIOS
|
|
stores it in non-volatile memory in your PC (known as ESCD; see <ref
|
|
id="escd_" name="The BIOS's ESCD Database">).
|
|
|
|
While MS Windows (starting with Windows 95) is a PnP OS, Linux was not
|
|
originally a PnP OS but has been gradually becoming a PnP OS. PnP
|
|
originally worked in Linux because a PnP BIOS would configure the
|
|
bus-resources and the device drivers would find out (using programs
|
|
supplied by the Linux kernel) what the BIOS has done. Today, most
|
|
drivers can issue commands to do their own bus-resource configuring
|
|
and don't need to rely on the BIOS. Unfortunately a driver might take
|
|
a bus-resource which another device will need later on. Some device
|
|
drivers may store the last configuration they used in a configuration
|
|
file and use it the next time the computer is powered on.
|
|
|
|
If the device hardware remembered their previous configuration, then
|
|
there wouldn't be any hardware to configure at the next boot-time, but
|
|
they seem to forget their configuration when the power is turned off.
|
|
Some devices contain a default configuration (but not necessarily the
|
|
last one used). Thus a PnP device needs to be re-configured each time
|
|
the PC is powered on. Also, if a new device has been added, then it
|
|
too needs to be configured. Allocating bus-resources to this new
|
|
device might involve taking some bus-resources away from an existing
|
|
device and assigning the existing device alternative bus-resources
|
|
that it can use instead. At present, Linux can't allocate with this
|
|
sophistication (and MS Windows XP may not be able to do it either).
|
|
|
|
<sect1> Starting Up the PC
|
|
<p> When the PC is first turned on the BIOS chip runs its program to
|
|
get the computer started (the first step is to check out the
|
|
hardware). If the operating system is stored on the hard-drive (as it
|
|
normally is) then the BIOS must know about the hard-drive. If the
|
|
hard-drive is PnP then the BIOS may use PnP methods to find it. Also,
|
|
in order to permit the user to manually configure the BIOS's CMOS and
|
|
respond to error messages when the computer starts up, a screen (video
|
|
card) and keyboard are also required. Thus the BIOS must always
|
|
PnP-configure devices needed to load the operating system from the
|
|
hard-drive.
|
|
|
|
Once the BIOS has identified the hard-drive, the video card, and the
|
|
keyboard it is ready to start booting (loading the operating system
|
|
into memory from the hard-disk). If you've told the BIOS that you
|
|
have a PnP operating system (PnP OS), it should start booting the PC
|
|
as above and let the operating system finish the PnP configuring.
|
|
Otherwise, a PnP-BIOS will (prior to booting) likely try to do the
|
|
rest of the PnP configuring of devices (but not inform their
|
|
drivers of what it did).
|
|
|
|
<sect1> Buses
|
|
<p> ISA is the old bus of the old IBM PCs while PCI is a newer and
|
|
faster bus from Intel. The PCI bus was designed for what is today
|
|
called PnP. This makes it easy (as compared to the ISA bus) to find out
|
|
how PnP bus-resources have been assigned to hardware devices. To see
|
|
what's on the PCI bus type <tt/lspci/. Or type <tt/scanpci/ but it's
|
|
not as easy to read. The -v option will show more detail. And/or
|
|
look at the "file" <tt>/proc/pci</tt>. The boot-up messages on your
|
|
display show devices which have been found on various buses (use
|
|
shift-PageUp to back up thru them). See <ref id="boot_time_msgs"
|
|
name="Boot-time Messages">
|
|
|
|
For the ISA bus there was a real problem with implementing PnP since no
|
|
one had PnP in mind when the ISA bus was designed and there are almost
|
|
no I/O addresses available for PnP to use for sending configuration info
|
|
to a physical device. As a result, the way PnP was shoehorned onto the
|
|
ISA bus is very complicated. Whole books have been written about it.
|
|
See <ref id="pnp_book" name="PnP Book">. Among other things, it
|
|
requires that each PnP device be assigned a temporary "handle" by the
|
|
PnP program so that one may address it for PnP configuring. Assigning
|
|
these "handles" is call "isolation". See <ref id="isolation_"
|
|
name="ISA Isolation"> for the complex details.
|
|
|
|
Eventually, the ISA bus should become extinct. When this happens, PnP
|
|
will be a little easier since it will be easier to find out how the
|
|
BIOS has configured the hardware. There will still be the need to
|
|
match up device drivers with devices and also a need to configure
|
|
devices that are added when the PC is up and running.
|
|
|
|
<sect1> How Linux Does PnP <label id="how_linux_pnps">
|
|
<p> Linux has had serious problems dealing with PnP and still has a
|
|
problem but it's not as severe as it once was. It's debatable
|
|
whether or not Linux is really a PnP operating system. It seems to
|
|
mainly rely on and device drivers and the PnP BIOS to configure
|
|
bus-resources for devices.
|
|
|
|
But the kernel provides help for the drivers in the form of programs
|
|
they may call on that do PnP. In many cases, the device driver, with
|
|
the help of such programs, does all the needed configuring. In some
|
|
cases the BIOS may configure and then the device driver may find out
|
|
how the BIOS has configured it. The kernel provides the drivers with
|
|
some functions (program code) that the drivers may use to find out if
|
|
their device exists, how it's been configured, and functions to modify
|
|
the configuration. Kernel 2.2 could do this only for the PCI bus but
|
|
Kernel 2.4 has this feature for both the ISA and PCI buses (provided
|
|
that the PNP options have been selected when compiling the kernel).
|
|
This by no means guarantees that all drivers will fully and correctly
|
|
use these features.
|
|
|
|
In addition, the kernel helps avoid resource conflicts by not allowing
|
|
two devices to use the same bus-resources at the same time.
|
|
Originally this was only for IRQs, and DMAs but now it's for address
|
|
resources as well. For PCI, it allocates address resources while
|
|
booting.
|
|
|
|
Prior to Kernel 2.4, the standalone program: isapnp was often run to
|
|
configure and/or get info from PnP devices on the ISA bus. isapnp is
|
|
still needed for cases where the device driver is not fully PnP for
|
|
the ISA bus.. There was at least one attempt to make Linux a true PnP
|
|
operating system. See <url
|
|
url="http://www.astarte.free-online.co.uk">. But it never was put
|
|
into the kernel.
|
|
|
|
To see what help the kernel may provide to device drivers see the
|
|
directory /usr/.../.../Documentation where one of the ... contains the
|
|
word "kernel-doc" or the like. Use the "locate" command to find it.
|
|
In this documentation directory see pci.txt ("How to Write Linux PCI
|
|
Drivers") and the file: /usr/include/linux/pci.h. Unless you are a
|
|
driver guru and know C Programming, these files are written so tersely
|
|
that they will not actually teach you how to write a driver. But it
|
|
will give you some idea of what PnP type functions are available for
|
|
drivers to use. For the ISA bus see isapnp.txt and possibly (for
|
|
kernel 2.4) /usr/include/linux/isapnp.h.
|
|
|
|
When the PC starts up you may note from the messages on the screen
|
|
that some Linux device drivers often find their hardware devices (and
|
|
the bus-resources the BIOS has assigned them). But there are a number
|
|
of things that a real PnP operating system could handle better:
|
|
|
|
<itemize>
|
|
<item>Allocate bus-resources when they are in short supply
|
|
<item>Deal with more than one driver for a physical device
|
|
<item>Find a driver for a detected device (instead of making
|
|
drivers do the searching)
|
|
<item>Central allocation of bus-resources would ease the job of
|
|
programmers of device drivers
|
|
</itemize>
|
|
|
|
The "shortage of bus-resources" problem is becoming less of a problem
|
|
for two reasons: One reason is that the PCI bus is replacing the ISA
|
|
bus. Under PCI there is no shortage of IRQs since IRQs may be shared
|
|
(even though sharing is less efficient). Also, PCI doesn't use DMA
|
|
resources (although it does the equivalent of DMA without needing such
|
|
resources).
|
|
|
|
The second reason is that more and more physical devices
|
|
are using main memory addresses instead of IO address space. On
|
|
32-bit PCs there is 4GB of main memory address space and much of this
|
|
bus-resource is available for device IO (unless you have 4GB of main
|
|
memory installed). Compare this to the IO address space which is
|
|
limited to 64KB. So the memory space for device IO is not (yet ?) in
|
|
short supply.
|
|
|
|
<sect> Setting up a PnP BIOS <label id="conf_pnp_bios">
|
|
<p> When the computer is first turned on, the BIOS runs before the
|
|
operating system is loaded. Modern BIOSs are PnP and can configure
|
|
some or all of the PnP devices. Old PCI BIOS will only configure for
|
|
the PCI bus. Here are some of the choices which may exist in your
|
|
BIOS's CMOS menu:
|
|
|
|
<itemize>
|
|
<item> <ref id="bios_pnp_os" name="Do you have a PnP operating
|
|
system?">
|
|
<item> <ref id="bios_resources" name="How are bus-resources to be controlled?">
|
|
<item> <ref id="bios_reset" name="Reset the configuration?">
|
|
</itemize>
|
|
|
|
<sect1> Do you have a PnP operating system? <label id="bios_pnp_os">
|
|
<p> In any case the PnP BIOS will PnP-configure the hard-drive, video
|
|
card, and keyboard to make the system bootable. If you said you had a
|
|
PnP OS it will leave it up to the operating system (or device drivers)
|
|
to finish the configuration job. If you said no PnP OS then the BIOS
|
|
should configure everything. If you only run Linux on your PC, you
|
|
should probably tell it that you don't have a PnP operating system.
|
|
If you also run MS Windows on your PC and said it was a PnP OS when
|
|
you installed Windows, then you might try saying that you have a PnP
|
|
OS to keep Windows 95/98 happy (but it might cause problems for Linux.
|
|
For Windows 2000 it's claimed that Windows worked OK even if you say
|
|
you don't have a PnP OS. In this case Windows 2000 will report
|
|
finding new hardware (even though it already knew about the hardware
|
|
but didn't know how the BIOS Pnp-configured it).
|
|
|
|
If you say you have a PnP OS then you rely on the Linux device drivers
|
|
and possibly the program isapnp to take care of the bus-resource
|
|
configuring. This often works OK but sometimes doesn't. Doing it
|
|
this way has sometimes actually fixed problems. This could be because
|
|
the BIOS didn't do it's job right but Linux did.
|
|
|
|
If you tell the BIOS you don't have a PnP OS, then the BIOS will do
|
|
the configuring itself. Unless you have added new PnP devices, it
|
|
should use the configuration which it has stored in its non-volatile
|
|
memory (ESCD). See <ref id="escd_" name="The BIOS's ESCD Database">.
|
|
If the last session on your computer was with Linux, then there should
|
|
be no change in configuration. See <ref id="bios_conf" name= "BIOS
|
|
Configures PnP">. But if the last session was with Windows9x (which
|
|
is PnP) then Windows could have modified the ESCD. It supposedly does
|
|
this only if you "force" a configuration or install a legacy device.
|
|
See <ref id="W9x_ESCD" name="Using Windows to set ESCD">. Device
|
|
drivers that do configuring may modify what the BIOS has done. So
|
|
will the isapnp or PCI Utilities programs.
|
|
|
|
<sect2> Interoperability with Windows
|
|
<p> If you are running both Linux and Windows on the same PC, how do
|
|
you answer the BIOS's question: Do you have a PnP OS? In the 1990's
|
|
Windows suggested a yes answer and since Linux wasn't much of a PnP OS
|
|
your could say no for Linux. Having different answers for Windows and
|
|
Linux means that you would have to set up the BIOS's CMOS menu
|
|
manually each time you want to switch OSs. This is a lot of bother,
|
|
so it's best to have the same answer to the question for both Linux
|
|
and Windows.
|
|
|
|
In the 21st century, Windows 2000 and XP both suggest that you say no,
|
|
it's not a PnP OS. But Linux has become more PnP-like so you may want
|
|
to say yes. The situation is now sort of reversed from what it was.
|
|
If you have no idea what to say, you might as well just say no (it's
|
|
not a PnP OS). Then if you have problems you might change the no to a
|
|
yes. Both Windows 2000/XP and Linux have become more tolerant about
|
|
this and in many cases everything will work fine regardless of how you
|
|
answer. But if you want the BIOS to configure for Linux (and
|
|
Windows), you would say no.
|
|
|
|
<sect2> I have a PnP OS
|
|
<p>If you say that you have a PnP OS, then Linux may work OK if all
|
|
the drivers and isapnp (if you use it) are able to configure OK.
|
|
Perhaps updating of the Linux OS and/or drivers will help. Windows
|
|
95 and 98 should work OK too. Windows 2000 and XP will probably work
|
|
OK too, but they might not.
|
|
|
|
<sect2> I don't have a PnP OS: Windows 2000 and XP
|
|
<p>See the next section for Window 9x. If you have Windows 2000 or XP
|
|
it should work out OK (even if you said it was a
|
|
PnP-OS when you first installed Windows 2000). When you change to
|
|
"not a PnP-OS", Windows 2000 (and XP ??) will automatically
|
|
PnP-reconfigure it's devices and tell you that it's finding new
|
|
hardware and installing new devices. What it really means is that
|
|
it's finding hardware which is already configured by the BIOS whereas
|
|
before it found hardware that wasn't configured by the BIOS. Perhaps
|
|
it considers the hardware to be "new" since Windows 2000 may be
|
|
finding it at a different address/irq than it has recorded in its
|
|
registry.
|
|
|
|
<sect2> I don't have a PnP OS: Windows 95/98:
|
|
<p> Now you are fibbing to Windows9x. Since one might expect Windows
|
|
be more sophisticated at handling PnP than Linux, one would expect
|
|
Windows9x to be able to cope with with hardware that has been fully
|
|
configured by the BIOS. But it can't (although Windows 2000/XP can).
|
|
|
|
What Windows9x seems to do when it finds hardware that is already
|
|
configured by the BIOS is to just leave it alone and not reconfigure
|
|
it. Now Windows9x keeps a record of the bus-resource configuration in
|
|
its registry. If the BIOS configuration is different, it should
|
|
either correct what's in its registry to conform to what the BIOS has
|
|
set or reconfigure everything per what's in the registry. Bad news.
|
|
It seems to do neither.
|
|
|
|
So it seems that Windows9x may just tell its device drivers what has
|
|
been stored in the Windows Registry but this info may be wrong. The
|
|
actual hardware configuration (done by the BIOS) is what was stored in
|
|
the ESCD and may not be the same as the Registry. This means trouble.
|
|
So for Windows to work OK you need to get the Registry to contain the
|
|
bus-resource configuration which the BIOS creates from the ESCD.
|
|
|
|
One way to try to get the Registry and the ESCD the same is to install
|
|
(or reinstall) Windows when the BIOS is set for "not a PnP OS". This
|
|
should present Windows with hardware configured by the BIOS. If this
|
|
configuration is without conflicts, Windows will hopefully leave it
|
|
alone and save it in it's Registry. Then the ESCD and the registry
|
|
are in sync.
|
|
|
|
Another method is to remove devices that are causing problems in
|
|
Windows by clicking on "remove" in the Device Manager. Then reboot with
|
|
"Not a PnP OS" (set it in the CMOS as you start to boot). Windows
|
|
will then reinstall the devices, hopefully using the bus-resource
|
|
settings configured by the BIOS. Be warned that Windows will likely
|
|
ask you to insert the Window installation CD since it sometimes can't
|
|
find the driver files (and the like) even though they are still
|
|
there. A workaround for this is to select "skip file" and continue.
|
|
|
|
As a test I "removed" a NIC card which used a Novell compatible
|
|
driver. Upon rebooting, Windows reinstalled it with Microsoft
|
|
Networking instead of Novell. This meant that the Novell Client
|
|
needed to be reinstalled --a lot of unnecessary work. So it may be
|
|
better to not fib to Windows95/98 but instead to get Linux to
|
|
configure bus-resources.
|
|
|
|
<sect1> How are bus-resources to be controlled? <label
|
|
id="bios_resources"> <p> Unless you have old non-pnp ISA cards, just
|
|
set this to "auto". If set to manual, you manually reserve some
|
|
IRQ's, etc. for use on "legacy" (non-pnp) ISA cards. The BIOS may or
|
|
may not otherwise know about such legacy cards. The BIOS will only
|
|
know about these legacy cards if you ran ICU (or the like) under
|
|
Windows to tell the BIOS about them. If the BIOS knows about them,
|
|
then try using "auto". If it doesn't know about them, then manually
|
|
reserve the IRQ's needed for the legacy ISA cards and let the rest be
|
|
for the BIOS PnP to allocate.
|
|
|
|
<sect1> Reset the configuration? <label id="bios_reset">
|
|
<p> Don't try this unless... This will erase the BIOSs ESCD data-base
|
|
of how your PnP devices should be configured as well as the list of
|
|
how legacy (non-PnP) devices are configured. Never do this unless you
|
|
are convinced that this data-base is wrong and needs to be remade. It
|
|
was stated somewhere that you should do this only if you can't get
|
|
your computer to boot. If the BIOS loses the data on legacy ISA
|
|
devices, then you'll need to run ICA again under DOS/Windows to
|
|
reestablish this data.
|
|
|
|
<sect> How to Deal with PnP Cards
|
|
<sect1> Introduction to Dealing with PnP Cards
|
|
<p> Today most all new internal boards (cards) are Plug-and-Play
|
|
(PnP). The configuring of bus-resources is normally done by the
|
|
various device drivers using pnp support provided by modules or built
|
|
into the kernel. If this doesn't work, there are 4 other methods
|
|
listed below to cope with PnP (but some may not be feasible in your
|
|
situation). If the BIOS configures it, you hope that the driver can
|
|
find out what the BIOS did, otherwise you may need to tell the driver
|
|
this in a configuration file or the like.
|
|
|
|
<itemize>
|
|
<item> <ref id="dev_d_conf" name="Device Driver Configures">
|
|
<item> <ref id="bios_conf" name= "BIOS Configures"> (For the PCI bus
|
|
you only need a PCI BIOS, otherwise you need a PnP BIOS)
|
|
<item> <ref id="disable_pnp" name="ISA cards only: Disable PnP"> by jumpers or
|
|
DOS/Windows software (but many cards can't do this)
|
|
<item> <ref id="isapnp_" name="Isapnp"> is a program you can always
|
|
use to configure PnP devices on the ISA bus only
|
|
<item> <ref id="pciutils_" name="PCI Utilities"> is for configuring the PCI
|
|
bus but the device driver should handle it
|
|
<item> <ref id="windows_conf" name="Windows Configures"> and then you
|
|
boot Linux from within Windows/DOS. Use as a last resort
|
|
</itemize>
|
|
|
|
Any of the above will set the bus-resources in the hardware but only
|
|
the first one tells the driver what has been done. How the driver gets
|
|
informed depends on the driver. You may need to do something to
|
|
inform it. See <ref id="tell_driver_config" name="Tell the Driver the
|
|
Configuration">
|
|
|
|
<sect1> Device Driver Configures, Reserving Resources <label id="dev_d_conf">
|
|
<p> Many device drivers (with the help of code provided by the kernel)
|
|
will use PnP methods to set the bus-resources in the hardware but only
|
|
for the device that they control. Since the driver has done the
|
|
configuring, it obviously knows the configuration and there is no need
|
|
for you to tell it this info. This is obviously the easiest way to do
|
|
it since you don't have to do anything if the driver does it all.
|
|
|
|
If you have old pre-pnp ISA hardware, the Linux Pnp software may not
|
|
know about it and the bus-resources it requires. So it might
|
|
erroneously allocate the resources that this old hardware needs to
|
|
some other device. The result is a resource conflict but there's a way
|
|
to try to avoid it. You can reserve the resources that the old ISA
|
|
card needs by giving arguments to the isa-pnp module or to the kernel
|
|
(if the pnp is built into the kernel). For example, to reserve irq 5
|
|
give this argument to the isa-pnp module (or to the kernel):
|
|
isapnp_reserve_irq=5. See BootPrompt-HOWTO. Instead of ..._irq there
|
|
are also _io, _dma, and _mem. Is this clever enough to prevent a PCI
|
|
device from using such reserved resources ??
|
|
|
|
For PCI devices, most drivers will configure PnP but for ISA devices
|
|
it's problematical. This is because PCI has always been inherently
|
|
PnP (called "PCI Configuration"). For ISA, the kernel provided
|
|
no functions for PnP configuring until version 2.4. So if you have a
|
|
modern version of both the kernel and the driver then the driver is more
|
|
likely to configure ISA PnP (bus-resources). But if you have older
|
|
versions (or if the driver maintainer failed to add PnP support to it)
|
|
then the driver may not configure ISA PnP.
|
|
|
|
Unfortunately, a driver may grab bus-resources that are needed by other
|
|
devices (but not yet allocated to them by the kernel). Thus a true
|
|
PnP Linux kernel would be better where the kernel did the allocation
|
|
after all requests were in. See <ref id="how_linux_pnps" name="How
|
|
Linux Does PnP">.
|
|
|
|
<sect1> BIOS Configures <label id="bios_conf">
|
|
<sect2> Intro to Using the BIOS to Configure PnP
|
|
<p> If you have a PnP BIOS, it can configure the hardware. If the
|
|
driver can't do it, the BIOS probably can. This means that your BIOS
|
|
reads the resource requirements of all devices and configures them
|
|
(allocates bus-resources to them). It is a substitute for a PnP OS
|
|
except that the BIOS doesn't match up the drivers with their devices
|
|
nor tell the drivers how it has done the configuring. It should
|
|
normally use the configuration it has stored in its non-volatile
|
|
memory (ESCD). If it finds a new device or if there's a conflict, the
|
|
BIOS should make the necessary changes to the configuration and may
|
|
not use the same configuration as was in the ESCD. In this case it
|
|
should update the ESCD to reflect the new situation.
|
|
|
|
Your BIOS needs to support such configuring and there have been cases
|
|
where it doesn't do it correctly or completely. The BIOS also
|
|
needs to be told via the CMOS menu that it's not a PnP OS. While
|
|
many device drivers will be able to automatically detect what the
|
|
BIOS has done, in some cases you may need to determine it (not always
|
|
easy). See <ref id="current_config" name="What Is My Current
|
|
Configuration?"> A possible advantage to letting the BIOS do it is
|
|
that it does its work before Linux starts so it all gets done early in
|
|
the boot process.
|
|
|
|
According to MS it's only optional (not required) that a PnP BIOS be
|
|
able to PnP-configure the devices (without help from MS Windows). But
|
|
it seems that most of the ones made after 1996 ?? or so can do it. We
|
|
should send them thank-you notes if they do it right. They configure
|
|
both the PCI and ISA buses, but it has been claimed that some older
|
|
BIOSs can only do the PCI. To try to find out more about your BIOS,
|
|
look on the Web. Please don't ask me as I don't have data on this.
|
|
The details of the BIOS that you would like to know about may be hard
|
|
to find (or not available). Some BIOSs may have minimal PnP
|
|
capabilities and seemingly expect the operating system to do it
|
|
right. If this happens you'll either have to find another method or
|
|
try to set up the ESCD database if the BIOS has one. See the next
|
|
section.
|
|
|
|
<sect2> The BIOS's ESCD Database <label id="escd_">
|
|
<p> The BIOS maintains a non-volatile database containing a
|
|
PnP-configuration that it will try to use (if you claim that it's not
|
|
a PnP OS). It's called the ESCD (Extended System Configuration Data).
|
|
Again, the provision of ESCD is optional but most PnP-BIOSs have it.
|
|
The ESCD not only stores the resource-configuration of PnP devices but
|
|
also stores configuration information of non-PnP devices (and marks
|
|
them as such) so as to avoid conflicts. The ESCD data is usually
|
|
saved on a chip and remains intact when the power is off, but
|
|
sometimes it's kept on a hard-drive??
|
|
|
|
The ESCD is intended to hold the last used configuration, but if you
|
|
use a program such as Linux's isapnp or pci utilities (which doesn't
|
|
update the ESCD) then the ESCD will not know about this and will not
|
|
save this configuration in the ESCD. A good PnP OS might update the
|
|
ESCD so you can use it later on for a non-PnP OS (like standard
|
|
Linux). MS Windows9x does this only in special cases. See <ref
|
|
id="W9x_ESCD" name="Using Windows to set ESCD">.
|
|
|
|
To use what's set in ESCD be sure you've set "Not a PnP OS" or the
|
|
like in the BIOS's CMOS. Then each time the BIOS starts up (before
|
|
the Linux OS is loaded) it should configure things this way. If the
|
|
BIOS detects a new PnP card which is not in the ESCD, then it must
|
|
allocate bus-resources to the card and update the ESCD. It may even
|
|
have to change the bus-resources assigned to existing PnP cards and
|
|
modify the ESCD accordingly.
|
|
|
|
If each device saved its last configuration in its hardware, hardware
|
|
configuring wouldn't be needed each time you start your PC. But it
|
|
doesn't work this way. So all the ESCD data needs to be kept correct
|
|
if you use the BIOS for PnP. There are some BIOSs that don't have an
|
|
ESCD but do have some non-volatile memory to store info regarding
|
|
which bus-resources have been reserved for use by non-PnP cards. Many
|
|
BIOSs have both.
|
|
|
|
<sect2> Using Windows to set the ESCD <label id="W9x_ESCD">
|
|
<p> If the BIOS doesn't set up the ESCD the way you want it (or the
|
|
way it should be) then it would be nice to have a Linux utility to
|
|
set the ESCD. As of early 1999 there wasn't any and now in 2002
|
|
no one has told me about any. Thus one may resort to attempting to
|
|
use Windows (if you have it on the same PC) to do this.
|
|
|
|
There are three ways to use Windows to try to set/modify the ESCD. One
|
|
way is to use the ICU utility designed for DOS or Windows 3.x. It
|
|
should also work OK for Windows 9x/2k ?? Another way is to set up
|
|
devices manually ("forced") under Windows 9x/2k so that Windows will
|
|
put this info into the ESCD when Windows is shut down normally. The
|
|
third way is only for legacy devices that are not plug-and-play. If
|
|
Windows knows about them and what bus-resources they use, then Windows
|
|
should put this info into the ESCD.
|
|
|
|
If PnP devices are configured automatically by Windows without the
|
|
user "forcing" it to change settings, then such settings probably will
|
|
not make it into the ESCD. Of course Windows may well decide on its
|
|
own to configure the same as what is set in the ESCD so they could
|
|
wind up being the same by coincidence.
|
|
|
|
Windows 9x are PnP operating systems and automatically PnP-configure
|
|
devices. They maintain their own PnP-database deep down in the
|
|
Registry (stored in binary Windows files). There is also a lot of
|
|
other configuration stuff in the Registry besides PnP-bus-resources.
|
|
There is both a current PnP resource configuration in memory and
|
|
another (perhaps about the same) stored on the hard disk. To look at
|
|
this in Windows98 or to force changes to it you use the Device Manager.
|
|
|
|
In Windows98 there are 2 ways to get to the Device Manager: 1. My
|
|
Computer --> Control Panel --> System Properties --> Device Manager.
|
|
2. (right-click) My Computer --> Properties --> Device Manager. Then
|
|
in Device Manager you select a device (sometimes a multi-step process
|
|
if there are a few devices of the same class). Then click on
|
|
"Properties" and then on "Resources". To attempt to change the
|
|
resource configuration manually, uncheck "Use automatic settings" and
|
|
then click on "Change Settings". Now try to change the setting, but
|
|
it may not let you change it. If it does let you, you have "forced" a
|
|
change. A message should inform you that it's being forced. If you
|
|
want to keep the existing setting shown by Windows but make it
|
|
"forced" then you will have to force a change to something else and
|
|
then force it back to its original setting.
|
|
|
|
To see what has been "forced" under Windows98 look at the "forced
|
|
hardware" list: Start --> Programs --> Accessories --> System Tools
|
|
--> System Information --> Hardware Resources --> Forced Hardware.
|
|
When you "force" a change of bus-resources in Windows, it should put
|
|
your change into the ESCD (provided you exit Windows normally).
|
|
From the "System Information" window you may also inspect how IRQs and
|
|
IO ports have been allocated under Windows.
|
|
|
|
Even if Windows shows no conflict of bus-resources, there may be a
|
|
conflict under Linux. That's because Windows may assign bus-resources
|
|
differently than the ESCD does. In the the rare case where all
|
|
devices under Windows are either legacy devices or have been "forced",
|
|
then Windows and the ESCD configurations should be identical.
|
|
|
|
<sect2> Adding a New Device (under Linux or Windows)
|
|
<p> If you add a new PnP device and have the BIOS set to "not a PnP
|
|
OS", then the BIOS should automatically configure it and store the
|
|
configuration in ESCD. If it's a non-PnP legacy device (or one made
|
|
that way by jumpers, etc.) then here are a few options to handle it:
|
|
|
|
You may be able to tell the BIOS directly (via the CMOS setup menus)
|
|
that certain bus-resources it uses (such as IRQs) are reserved and are
|
|
not to be allocated by PnP. This does not put this info into the
|
|
ESCD. But there may be a BIOS menu selection as to whether or not to
|
|
have these CMOS choices override what may be in the ESCD in case of
|
|
conflict. Another method is to run ICU under DOS/Windows. Still
|
|
another is to install it manually under Windows 9x/2k and then make
|
|
sure its configuration is "forced" (see the previous section). If
|
|
it's "forced" Windows should update the ESCD when you shut down the
|
|
PC.
|
|
|
|
<sect1> ISA cards only: Disable PnP ? <label id="disable_pnp">
|
|
<p> PCI devices are inherently PnP so it can't be disabled. But a few
|
|
ISA devices had options for disabling PnP by jumpers or by running a
|
|
Windows program that comes with the device (jumperless configuration).
|
|
If the device driver can't configure it, this will avoid the possibly
|
|
complicated task of doing PnP configuring. Don't forget to tell the
|
|
BIOS that these bus-resources are reserved. There are also some
|
|
reasons why you might not want to disable PnP:
|
|
|
|
<enum>
|
|
<item> If you have MS Windows on the same machine, then you may want
|
|
to allow PnP to configure devices differently under Windows from what
|
|
it does under Linux.
|
|
<item> The range of selection for IRQ numbers (or port addresses) etc.
|
|
may be quite limited unless you use PnP.
|
|
<item> You might have a Linux device driver that uses PnP methods to
|
|
search for the device it controls.
|
|
<item> If you need to change the configuration in the future, it may
|
|
be easier to do this if it's PnP (no setting of jumpers or running a
|
|
Dos/Windows program).
|
|
</enum>
|
|
|
|
Once configured as non-PnP devices, they can't be configured by PnP
|
|
software or a PnP-BIOS (until you move jumpers and/or use the
|
|
Dos/Windows configuration software again).
|
|
|
|
<sect1> Isapnp (part of isapnptools) <label id="isapnp_">
|
|
|
|
<p> The <tt/isapnp/ standalone program is only for PnP devices on the
|
|
ISA bus (non-PCI). It was much needed prior to the 2.4 kernels.
|
|
After the 2.4 kernel, which provided functionality to allow drivers
|
|
deal with ISA PnP, the isapnp standalone program is less significant.
|
|
But the isa-pnp module (or the equivalent built into the kernel) is now
|
|
very significant. This module is called on by various device drivers
|
|
to do configure bus-resources.
|
|
|
|
In some cases Linux distributions have been set up to run isapnp
|
|
automatically at startup. If you need to set it up yourself much of
|
|
the documentation for isapnp is difficult to understand unless
|
|
you know the basics of PnP. This HOWTO should help you understand it
|
|
as well the FAQ that comes with it. Running the Linux program
|
|
"isapnp" at boot-time will configure such devices to the resource
|
|
values specified in /etc/isapnp.conf. Its possible to create this
|
|
configuration file automatically but you then should edit it manually
|
|
to choose between various options.
|
|
|
|
With isapnp there's a danger that a device driver which is built into
|
|
the kernel may run too early before isapnp has set the address, etc.
|
|
in the hardware. This results in the device driver not being able to
|
|
find the device. The driver tries the right address but the address
|
|
hasn't been set yet in the hardware.
|
|
|
|
If your Linux distribution automatically installed isapnptools, isapnp
|
|
may already be running at startup. In this case, all you need to do
|
|
is to edit /etc/isapnp.conf per "<tt/man isapnp.conf/". Note that
|
|
this is like manually configuring PnP since you make the decisions as
|
|
to how to configure as you edit the configuration file.
|
|
|
|
If the configuration file is wrong or doesn't exist, you can use
|
|
the program "pnpdump" to help create the configuration file. It
|
|
almost creates a configuration file for you but you must skillfully
|
|
edit it a little before using it. It contains some comments to help
|
|
you edit it. While the BIOS may also configure the ISA devices (if
|
|
you've told it that you don't have a PnP OS), isapnp will redo it.
|
|
|
|
The terminology used in the /etc/isapnp.conf file may seem odd at
|
|
first. For example for an I0 address of 0x3e8 you might see "(IO 0
|
|
(BASE 0x3e8))" instead. The "IO 0" means this is the first (0th) IO
|
|
address-range that this device uses. Another way to express all this
|
|
would be: "IO[0] = 0x3e8" but isapnp doesn't do it this way. "IO 1"
|
|
would mean that this is the second IO address range used by this
|
|
device, etc. "INT 0" has a similar meaning but for IRQs (interrupts).
|
|
A single card may contain several physical devices but the above
|
|
explanation was for just one of these devices.
|
|
|
|
<sect1> PCI Utilities <label id="pciutils_">
|
|
<p> The package PCI Utilities (= pciutils, sometimes called
|
|
"pcitools"), should let you manually PnP-configure the PCI bus.
|
|
"lspci" or "scanpci" (Xwindows) lists bus-resources while "setpci"
|
|
sets resource allocations in the hardware devices. It appears that
|
|
setpci is mainly intended for use in scripts and presently one needs to
|
|
know the details of the PCI configuration registers in order to use it.
|
|
That's a topic not explained here nor in the manual page for setpci.
|
|
|
|
People have used this to configure PCI devices where the driver failed
|
|
to do it. An example is found in my Modem-HOWTO and Serial-HOWTO in
|
|
the subsection "PCI: Enabling a disabled port". However, enabling a
|
|
device is of no use unless you have a working driver for the device.
|
|
|
|
<sect1> Windows Configures <label id="windows_conf">
|
|
<p> This method uses MS Windows to configure and should be used only
|
|
if all else fails. If you have Windows9x (or 2k) on the same PC, then
|
|
just start Windows and let it configure PnP. Then start Linux from
|
|
Windows (or DOS). But there may be a problem with IRQs for PCI
|
|
devices. As Windows shuts down to make way for Linux, it may erase
|
|
(zero) the IRQ which is stored in one of the PCI device's
|
|
configuration registers. Linux will complain that it has found an IRQ
|
|
of zero.
|
|
|
|
The above is reported to happen if you start Linux using a shortcut
|
|
(PIF file). But a workaround is reported where you still use the
|
|
shortcut PIF. A shortcut is something like a symbolic link in Linux
|
|
but it's more than that since it may be "configured". To start Linux
|
|
(from DOS you create a batch file (script) which starts Linux. (The
|
|
program that starts Linux is in the package called "loadlin"). Then
|
|
create a PIF shortcut to that batch file and get to the "Properties"
|
|
dialog box for the shortcut. Select "Advanced" and then check "MS-DOS
|
|
mode" to get it to start in genuine MS-DOS.
|
|
|
|
Now here's the trick to prevent zeroing the PCI IRQs. Chick "Specify
|
|
a new MS-DOS configuration". Then either accept the default
|
|
configuration presented to you or click on "Configuration" to change
|
|
it. Now when you start Linux by clicking on the shortcut, new
|
|
configuration files (Config.sys and Autoexec.bat) will be created per
|
|
your new configuration.
|
|
|
|
The old files are stored as "Config.wos and Autoexec.wos". After you
|
|
are done using Linux and shut down your PC then you'll need these
|
|
files again so that you can run DOS the next time you start your PC.
|
|
You need to ensure that the names get restored to *.sys and *.bat.
|
|
When you leave Windows/DOS to enter Linux, Windows is expecting that
|
|
when you are done using Linux you will return to Windows so that
|
|
Windows can automatically restore these files to their original names.
|
|
But this doesn't happen since when you exit Linux you shut down your
|
|
PC and don't get back to Windows. So how do you get these files
|
|
renamed? It's easy, just put commands into your "start-Linux" batch
|
|
file to rename these files to their *.bat and *.sys names. Put these
|
|
renaming commands into your batch file just before the line that loads
|
|
Linux.
|
|
|
|
Also it's reported that you should click on the "General" tab (of the
|
|
"Properties" dialog of your shortcut) and check "Read-only".
|
|
Otherwise Windows may reset the "Advanced Settings" to "Use current
|
|
MS-DOS configuration" and PCI IRQs get zeroed. Thus Windows erases
|
|
the IRQs when you use the current MS-DOS configuration but doesn't
|
|
erase when you use a new configuration (which may actually configure
|
|
things identical to the old configuration). Windows does not seem to
|
|
be very consistent.
|
|
|
|
|
|
<sect1> PnP Software/Documents <label id="sw_and_docs">
|
|
<p><itemize>
|
|
<item><url url="http://www.roestock.demon.co.uk/isapnptools/"
|
|
name="Isapnptools homepage">
|
|
<item><url url="http://www.astarte.free-online.co.uk" name="Proposal
|
|
for a Configuration Manager for Linux"> (Never got into kernel.)
|
|
<item> <url url="http://www.io.com/~cdb/mirrors/lpsg/pnp-linux.html"
|
|
name="Failed PnP driver project">
|
|
<item <url url="http://www.microsoft.com/hwdev/tech/pnp/default.asp"
|
|
name="PnP Specs. from Microsoft">
|
|
<item> Book: PCI System Architecture, 4th ed. by Tom Shanley +,
|
|
MindShare 1999. Covers PnP-like features on the PCI bus.
|
|
<item> <label id="pnp_book"> Book: Plug and Play System Architecture,
|
|
by Tom Shanley, Mind Share 1995. Details of PnP on the ISA bus. Only
|
|
a terse overview of PnP on the PCI bus.
|
|
<item> Book: Programming Plug and Play, by James Kelsey, Sams 1995.
|
|
Details of programming to communicate with a PnP BIOS. Covers ISA,
|
|
PCI, and PCMCIA buses.
|
|
</itemize>
|
|
|
|
<sect> Tell the Driver the Configuration <label id="tell_driver_config">
|
|
<sect1> Introduction
|
|
|
|
<p>A modern driver for a device will find out the bus-resource
|
|
configuration without you having to tell it anything. It may even set
|
|
the bus-resources in the hardware using PnP methods. Some drivers
|
|
have more than one way to find out how their physical device is
|
|
configured. In the worst case you must hard-code the bus-resources
|
|
into the kernel (or a module) and recompile.
|
|
|
|
In the middle are cases such as where you run a program to give the
|
|
bus-resource info to the driver or put the info in a configuration
|
|
file. In some cases the driver may probe for the device at addresses
|
|
where it suspects the device resides (but it will never find a PnP
|
|
device if it hasn't been enabled by PnP methods). It may then try to
|
|
test various IRQs to see which one works. It may or may not
|
|
automatically do this. In other cases the driver may use PnP methods
|
|
to find the device and how the bus-resources have been set by the
|
|
BIOS, etc. but will not actually set them. It may also look at some
|
|
of the "files" in the /proc directory.
|
|
|
|
One may need to "manually" tell a driver what bus-resources it should
|
|
use. You give such bus-resources as a parameter to the kernel or to a
|
|
loadable module. If the driver is built into the kernel, you pass the
|
|
parameters to the kernel via the "boot-prompt". See The
|
|
Boot-Prompt-HOWTO which describes some of the bus-resource and other
|
|
parameters. Once you know what parameters to give to the kernel, one
|
|
may put them into a boot loader configuration file. For example, put
|
|
append="...". into the lilo.conf file and then use the lilo command to
|
|
get this info into the lilo kernel loader.
|
|
|
|
If the driver is loaded as a module, in many cases the module will
|
|
find the bus-resources needed and then set them in the device. In other
|
|
cases (mostly for older PCs) you may need to give bus-resources as
|
|
parameters to the module. Parameters to a module (including ones that
|
|
automatically load) may be specified in /etc/modules.conf. There are
|
|
usually tools used to modify this file which are
|
|
distribution-dependent. Comments in this file should help regarding
|
|
how to modify it. Also, any module your put in /etc/modules will get
|
|
loaded along with its parameters.
|
|
|
|
While there is great non-uniformity about how drivers find out about
|
|
bus-resources, the end goal is the same. If you're having problems
|
|
with a driver you may need to look at the driver documentation (check
|
|
the kernel documentation tree). Some brief examples of a few drivers
|
|
is presented in the following sections:
|
|
|
|
<sect1> Serial Port Driver Example
|
|
<p> For PCI serial ports (and for newer 2.4 kernels for ISA), the
|
|
serial driver detects the type of serial port and PnP configures it.
|
|
Unfortunately, there may be some PCI serial ports that are not
|
|
supported yet.
|
|
|
|
For the standard ISA serial port with older versions of the kernel and
|
|
serial driver (not for multiport cards) you use setserial to inform
|
|
the driver. Using setserial is also a must for non-pnp serial ports.
|
|
Setserial is often run from a start-up file. In newer versions there
|
|
is a /etc/serial.conf file that you "edit" by simply using the
|
|
setserial command in the normal way and what you set using
|
|
<tt/setserial/ is saved in the <tt>serial.conf</tt> configuration
|
|
file. The <tt>serial.conf</tt> file should be consulted when the
|
|
<tt/setserial/ command runs from a start-up file. Your distribution
|
|
may or may not set this up for you.
|
|
|
|
There are two different ways to use <tt/setserial/ depending on the
|
|
options you give it. One way is used to manually tell the driver the
|
|
configuration. The other way is to probe at a given address and
|
|
report if a serial port exists there. It can also probe this address
|
|
and try to detect what IRQ is used for this port. The driver runs
|
|
something like <tt/setserial/ at start-up but it doesn't probe for
|
|
IRQs, it just assigns the "standard" IRQ which may be wrong. It does
|
|
probe for the existence of a port. See Serial-HOWTO for more details.
|
|
|
|
<sect1> Some Sound Card Driver Examples
|
|
|
|
<sect2> OSS-Lite
|
|
<p> You must give the IO, IRQ, and DMA as parameters to a module
|
|
or compile them into the kernel. But some PCI cards will get
|
|
automatically detected. RedHat supplies a program "sndconfig" which
|
|
detects ISA PnP cards and automatically sets up the modules for
|
|
loading with the detected bus-resources.
|
|
|
|
<sect2> OSS (Open Sound System) and ALSA
|
|
<p> These will detect the card by PnP methods and then select the
|
|
appropriate driver and load it. It will also set the bus-resources on an
|
|
ISA-PnP card. You may need to manually intervene to avoid conflicts.
|
|
For the ALSA driver, support for ISA-PnP is optional and you may use
|
|
isapnp tools if you want to.
|
|
|
|
<sect>How Do I Find Devices and How Are They Configured? <label id="current_config">
|
|
|
|
<sect1>Finding and How-Configured Are Related
|
|
<p>Once you find your hardware, the same program that found it usually
|
|
tells you how it's configured. So finding out how it's configured is
|
|
usually the same procedure as finding the hardware.
|
|
|
|
<sect1>Devices Have Two "Configurations"
|
|
<p> Here "configuration" means the assignment of PnP bus-resources
|
|
(addresses, IRQs, and DMAs). For each device, there are two parts to
|
|
the configuration question:
|
|
<enum>
|
|
<item> What does the driver think the hardware configuration is?
|
|
<item> What configuration (if any) is actually set in the device hardware?
|
|
</enum>
|
|
Each part should have the same answer (the same configuration).
|
|
|
|
The configuration of the device hardware and its driver should be the
|
|
same (and usually is). But if things are not working right, it could
|
|
be because there's a difference. This means the the driver has
|
|
incorrect information about the actual configuration of the hardware.
|
|
This spells trouble. If the software you use doesn't adequately tell
|
|
you what's wrong (or automatically configure it correctly) then you
|
|
need to investigate how your hardware devices and their drivers are
|
|
configured. While Linux device drivers should "tell all" in some
|
|
cases it may not be easy to determine what has been set in the
|
|
hardware.
|
|
|
|
Another problem is that when you view configuration messages on the
|
|
screen, it's sometimes not clear whether the reported configuration is
|
|
that of the device driver, the device hardware, or both. If the
|
|
device driver has either set the configuration in the hardware or has
|
|
otherwise checked the hardware then the driver should have the correct
|
|
information.
|
|
|
|
But sometimes the driver has been provided incorrect resources by a
|
|
script, by incorrect resource parameters given to a module, or perhaps
|
|
just hasn't been told what the resources are and tries to use
|
|
incorrect default resources. For example, one can uses "setserial" to
|
|
tell the serial port driver an incorrect resource configuration and the
|
|
driver accepts it without question. But the serial port doesn't work
|
|
right (if at all).
|
|
|
|
<sect1>Finding Hardware
|
|
<p>A common problem is that the software doesn't detect your device
|
|
and/or determine the right driver for it. For PnP devices, detecting
|
|
them is easy via PnP software. This means that since the PCI bus is
|
|
inherently PnP, there are no hidden devices. Even though PnP devices
|
|
are easy to find by PnP methods, if the driver doesn't use PnP methods
|
|
but uses the old method of probing for them at likely address, they
|
|
may not be found. This is because that until the resources are set in
|
|
a PnP device (by the BIOS or Linux), the device may have no address at
|
|
all so probing at likely address yields nothing. For the old ISA
|
|
bus, some of the devices may be non-PnP and thus the old probing
|
|
methods may find them. So many drivers still probe, in addition to
|
|
using PnP methods.
|
|
|
|
Ways to Find Hardware Devices (and their configurations): (follow link
|
|
to more details)
|
|
<itemize>
|
|
<item>Watch the <ref id="boot_time_msgs" name="Boot-time Messages">
|
|
on the screen
|
|
<item>Look in <ref id="proc_dir" name="The /proc Directory Tree">
|
|
<item> PCI: <ref id="pci_" name="PCI Bus Inspection">
|
|
<item> ISA Bus: <ref id="isa_bus" name="ISA Bus Introduction">
|
|
<item> ISA Bus: <ref id="isa_pnp" name="PnP cards">
|
|
<item> ISA Bus: For <ref id="non_pnp" name="Non-PnP Cards">
|
|
<item> ISA Bus: For <ref id="jumpers_" name="Cards with jumpers">,
|
|
<item> ISA Bus: If <ref id="neither_" name="Neither PnP nor jumpers">,
|
|
<item> <ref id="check_ms" name="Use MS Windows">
|
|
</itemize>
|
|
|
|
<sect1> Boot-time Messages <label id="boot_time_msgs">
|
|
<p> Some info on configuration may be obtained by reading the messages
|
|
from the BIOS and from Linux that appear on the screen when you first
|
|
start the computer. These messages often flash by too fast to read
|
|
but once they stop type Shift-PageUp a few times to scroll back to
|
|
them. To scroll forward thru them type Shift-PageDown. Typing
|
|
"dmesg" at any time to the shell prompt will show only the Linux
|
|
kernel messages and may miss some of the most important ones (including
|
|
ones from the BIOS). The messages from Linux may sometimes only show
|
|
what the device driver thinks the configuration is, perhaps as told it
|
|
via an incorrect configuration file. Checking log files in /var/log
|
|
may also be useful.
|
|
|
|
For the PCI bus, the notation: 00:1a:0 means the PCI bus 00 (the main
|
|
PCI bus), PCI card (or chip) 1a, and function 0 (the first device) on
|
|
the card or chip. The 2nd device on card (or chip) 08 would be:
|
|
00:08:1.
|
|
|
|
The BIOS messages display first and will show the actual hardware
|
|
configuration at that time, but isapnp, or pci utilities, or device
|
|
drivers may change it later. As an alternative to eventually using
|
|
Shift-PageUp to read them, try freezing them by hitting the "Pause"
|
|
key. Press any key to resume. But once the messages from Linux start
|
|
to appear, it's too late to use "Pause" since it will not freeze the
|
|
messages from Linux.
|
|
|
|
Messages from the BIOS at boot-time tell you how the hardware
|
|
configuration was then. For the case where only the BIOS does the
|
|
configuring, then it should still be the same. Messages from Linux
|
|
may be from drivers that used kernel PnP functions to inspect and/or
|
|
set bus-resources. These should be correct, but beware of messages
|
|
that only show what the driver was told from a configuration file.
|
|
It could be wrong. Of course, if the device works fine, then it's
|
|
likely configured the same as the driver.
|
|
|
|
<sect1> The /proc Directory Tree <label id="proc_dir">
|
|
<p> The /proc directory tree is useful for finding configuration and
|
|
devices. It seems that there are many files buried deep in this tree
|
|
that contain bus-resource info. Only a couple of them will be
|
|
mentioned here. /proc/ioports shows the I/O addresses that the active
|
|
drivers use (or try if it's wrong). They might not be set this way in
|
|
hardware.
|
|
|
|
/proc/interrupts shows only interrupts currently in use. Many
|
|
interrupts that have been allocated to drivers don't show here at all
|
|
since they're not currently being used. For example, even though your
|
|
floppy drive has a floppy disk in it and is ready to use, the
|
|
interrupt for it will not show unless its in use. Again, just because
|
|
an interrupt shows up here doesn't mean that it exists in the
|
|
hardware. A clue that it doesn't exist in hardware will be if it
|
|
shows that 0 interrupts have been issued by this interrupt. Even if
|
|
it shows a few interrupts have been issued there is no guarantee that
|
|
they came from the device shown. It could be that some other device
|
|
which is not currently in use has issued them. A device not in use
|
|
(per the kernel) may still issue some interrupts for various reasons.
|
|
|
|
<sect1>PCI Bus Inspection <label id="pci_">
|
|
<p> It's easy to find out what bus-resources have been assigned to
|
|
devices on the PCI bus with the "lspci" and/or "scanpci" commands or
|
|
look at <tt>/proc/pci</tt>. The option -v will show more detail.
|
|
<tt>/proc/buspci/devices</tt> shows a cryptic display so you probably
|
|
want to avoid it. Note that IRQs for <tt>/proc/pci</tt> are in
|
|
hexadecimal.
|
|
|
|
In most cases, for PCI you will only see how the hardware is now
|
|
configured and not what resources are required. In some cases you
|
|
only see the base addresses (the starting addresses of the range) but
|
|
not the ending addresses. If you see the entire range then you can
|
|
determine how many bytes of address resources are needed.
|
|
|
|
<sect1>ISA Bus Introduction <label id="isa_bus">
|
|
<p>For cards on the ISA bus, it's not as simple as for the PCI bus
|
|
which is inherently PnP. Newer ISA cards are PnP but older ones are
|
|
not. Also, some cards that are PnP have had their PnP disabled by
|
|
special software which runs only on MS. The non PnP cards are
|
|
configured by jumpers on the card or by MS software.
|
|
|
|
<sect1>ISA PnP cards <label id="isa_pnp">
|
|
<p>If it's a PnP card you may try running <tt>pnpdump --dumpregs</tt>
|
|
but it's not a sure thing. The results may be seem cryptic but they
|
|
can be deciphered. Don't confuse the read-port address which
|
|
<tt/pnpdump/ uses for communication with PnP cards with the I/O
|
|
address of the found device. They are not the same.
|
|
|
|
<sect1>Non-PnP Cards <label id="non_pnp">
|
|
<p>In contrast to PnP cards, non-PnP cards always have their resources
|
|
set in the hardware. That is they always have an address and IRQ.
|
|
Sometimes this can be found by probing done by the device driver or by
|
|
other software that does probing. For example "scanport" (Debian only
|
|
??) probes most IO port address and may find ISA devices. But be
|
|
warned that it might hang your PC. Sometimes it will fail to find
|
|
hardware that's actually there (since the hardware has the default
|
|
0xff in it's registers). Even if It finds the hardware it will not
|
|
show the IRQ nor will it positively identify the hardware.
|
|
|
|
So one way to try to find such hardware is to start a driver, which
|
|
may probe for such hardware. By looking at the boot-time messages, you
|
|
might see a driver start and find the hardware. Otherwise, you may
|
|
need to find a driver and start it (for example, by having it load as
|
|
a module).
|
|
|
|
Finding the right driver may be difficult. Sometimes there just isn't
|
|
any driver since some devices aren't supported by Linux (yet ?). To
|
|
determine which driver you need, look at any documentation which might
|
|
identify the card. If this fails, look on the card itself, including
|
|
important names/numbers on the chips. But the identification of the
|
|
driver module you need may not be anywhere on the card. You could
|
|
find the FCC id on the card and then search the Internet with the FCC
|
|
id number to try to find more information about the card (or the chips
|
|
on it).
|
|
|
|
<sect1>Non-PnP Cards with jumpers <label id="jumpers_">
|
|
<p>If the card has jumpers to set the resources (configuration) then
|
|
one may look at how the jumpers are set. There are some cards that had
|
|
both PnP and jumpers. They worked like jumper cards if PnP was
|
|
somehow disabled. Sometimes a card has labels on it showing how the
|
|
jumpers are set (or at least giving some clue). You may need the
|
|
documentation that came with the card (either printed or on a floppy
|
|
disk). Perhaps you can find it on the Internet.
|
|
|
|
<sect1>Neither PnP nor jumpers <label id="neither_">
|
|
<p>One the most difficult cases is where software running under MS has
|
|
been used to configure either a non-PnP card or a PnP card where PnP
|
|
has been disabled by the same MS software. So you can't configure it
|
|
by PnP nor by jumpers. In this case your only hope is to probe for
|
|
addresses as described in <ref id="non_pnp" name="Non-PnP Cards">.
|
|
|
|
<sect1>Use MS Windows <label id="check_ms">
|
|
<p>Some people have attempted to use Windows to see how bus-resources
|
|
have been set up. Unfortunately, since PnP hardware forgets its
|
|
bus-resource configuration when powered down, the configuration may
|
|
not be the same under Linux. For non PnP hardware (or where someone
|
|
has disabled PnP inside the device by jumpers or Windows software),
|
|
then using Windows should work OK. Even for PnP, it often turns
|
|
out to be the same because in many cases both Windows and Linux simply
|
|
accept what the BIOS has set. But where Windows and/or Linux do the
|
|
configuring, they may do it differently. So don't count on PnP
|
|
devices being configured the same.
|
|
|
|
<sect>Error Messages
|
|
<sect1> Unexpected Interrupt
|
|
<p> This means that an interrupt happened that no driver expected.
|
|
It's unlikely that the hardware issued an interrupt by mistake. It's
|
|
more likely that the software has a minor bug and doesn't realize that
|
|
some software did something to cause the interrupt. In many cases you
|
|
can safely ignore this error message, especially if it only happens
|
|
once or twice at boot-time. For boot-time messages, look at the
|
|
messages which are nearby for a clue as to what is going on. For
|
|
example, if probing is going on, perhaps a probe for a physical device
|
|
caused that device to issue an interrupt that the driver didn't
|
|
expect. Perhaps the driver wasn't listening for the correct IRQ
|
|
number.
|
|
<sect1> Plug and Play Configuration Error (Dell BIOS)
|
|
<p>The BIOS was unable to configure bus-resource. There may be an
|
|
interrupt conflict which can't be avoided. Dell suggests that you
|
|
remove some of your non-essential cards and see if it goes away. In
|
|
one case this problem was due to a defective motherboard.
|
|
|
|
<sect>Appendix
|
|
<sect1> Universal Plug and Play (UPnP) <label id="UPnP_">
|
|
<p> This is actually a sort of network plug-and-play developed by
|
|
Microsoft but usable by Linux. You plug something into a network and
|
|
that something doesn't need to be configured provided it will only
|
|
communicate with other UPnP enabled devices on the network. Here
|
|
"configure" is used in the broad sense and doesn't mean just
|
|
configuring bus-resources. One objective is to allow people who know
|
|
little about networks or configuring to install routers, gateways,
|
|
network printers, etc. A major use for UPnP would be in wireless
|
|
networking.
|
|
|
|
UPnP uses:
|
|
<itemize>
|
|
<item> Simple Service Discovery Protocol to find devices
|
|
<item> General Event Notification Architecture
|
|
<item> Simple Object Access Protocol for controlling devices
|
|
</itemize>
|
|
|
|
This HOWTO doesn't cover UPnP. UPnP for Linux is supported by Intel
|
|
which has developed software for it. There are other programs which
|
|
do about the same thing as UPnP. A comparison of some of them is at
|
|
<url url="http://www.cs.umbc.edu/~dchakr1/papers/mcommerce.html">
|
|
|
|
<sect1> Address Details <label id="address_details">
|
|
<p> There are three types of addresses: main memory addresses, I/O
|
|
addresses (ports) and configuration addresses. On the PCI bus,
|
|
configuration addresses constitute a separate address space just like
|
|
I/O addresses do. Except for the complicated case of ISA
|
|
configuration addresses, whether or not an address on the bus is a
|
|
memory address, I/O address, or configuration address depends only on
|
|
the voltage on other wires (traces) of the bus. For the ISA
|
|
configuration addresses see <ref id="isa_conf_addresses" name="ISA Bus
|
|
Configuration Addresses (Read-Port etc.)"> for details
|
|
|
|
<sect2> Address ranges
|
|
<p> The term "address" is sometimes used in this document to mean a
|
|
contiguous range of addresses. Since addresses are in units of bytes,
|
|
a single address is only the location of a single byte but I/O (and
|
|
main memory) addresses need more than this. So a range of say 8 bytes
|
|
is often used for I/O address while the range for main memory
|
|
addresses allocated to a device is much larger. For a serial port (an
|
|
I/O device) it's sufficient to give the starting I/O address of the
|
|
device (such as 3F8) since it's well known that the range of addresses
|
|
for serial port is only 8 bytes. The starting address is known as the
|
|
"base address". Sometimes just the word "range" is used to mean
|
|
"address range".
|
|
|
|
<sect2> Address space
|
|
<p> For ISA, to access both I/O and (main) memory address "spaces"
|
|
the same address bus is used (the wires used for the address are
|
|
shared). How does the device know whether or not an address which
|
|
appears on the address bus is a memory address or I/O address? Well,
|
|
there are 4 dedicated wires on the bus that convey this information
|
|
and more. If a certain one of these 4 wires is asserted, it says that
|
|
the CPU wants to read from an I/O address, and the main memory ignores
|
|
the address on the bus. The other 3 wires serve similar purposes.
|
|
Thus read and write wires exist for both main memory and I/O addresses
|
|
(4 wires in all).
|
|
|
|
For the PCI bus it's the same basic idea (also using 4 wires) but it's
|
|
done a little differently. Instead of only one of the four wires
|
|
being asserted, a binary number is put on the wires (16 different
|
|
possibilities). Thus more info may be conveyed. Four of these 16
|
|
numbers serve the I/O and memory spaces as in the above paragraph. In
|
|
addition there is also configuration address space which uses up two
|
|
more numbers. Ten extra numbers are left over for other purposes.
|
|
|
|
<sect2> Range Check (ISA Testing for IO Address Conflicts)
|
|
<p> On the ISA bus, there's a method built into each PnP card for
|
|
checking that there are no other cards that use the same I/O address.
|
|
If two or more cards use the same IO address, neither card is likely
|
|
to work right (if at all). Good PnP software should assign
|
|
bus-resources so as to avoid this conflict, but even in this case a
|
|
legacy card might be lurking somewhere with the same address.
|
|
|
|
The test works by a card putting a known test number in its own IO
|
|
registers. Then the PnP software reads it and verifies that it reads
|
|
the same test number. If not, something is wrong (such as another
|
|
card with the same address. It repeats the same test with another
|
|
test number. Since it actually checks the range of IO addresses
|
|
assigned to the card, it's called a "range check". It could be better
|
|
called an address-conflict test. If there is an address conflict you
|
|
get an error message and need to resolve it yourself.
|
|
|
|
<sect2> Communicating Directly via Memory
|
|
<p> Traditionally, most I/O devices used only I/O memory to
|
|
communicate with the CPU. For example, the serial port does this.
|
|
The device driver, running on the CPU would read and write data
|
|
to/from the I/O address space and main memory. A faster way would be
|
|
for the device itself to put the data directly into main memory. One
|
|
way to do this is by using <ref id="dma_" name="DMA Channels"> or bus
|
|
mastering. Another way is to allocate some space in main memory to
|
|
the device. This way the device reads and writes directly to main
|
|
memory without having to bother with DMA or bus mastering. Such
|
|
a device may also use IO addresses.
|
|
|
|
<sect1> ISA Bus Configuration Addresses (Read-Port etc.)
|
|
<label id="isa_conf_addresses">
|
|
<p> These addresses are also known as the "Auto-configuration Ports".
|
|
For the ISA bus, there is technically no configuration address space,
|
|
but there is a special way for the CPU to access PnP configuration
|
|
registers on the PnP cards. For this purpose 3 @ I/O addresses are
|
|
allocated and each addresses only a single byte (there is no "range").
|
|
This is not 3 addresses for each card but 3 addresses shared by all
|
|
ISA-PnP cards.
|
|
|
|
These 3 addresses are named read-port, write-port, and address-port.
|
|
Each port is just one byte in size. Each PnP card has many
|
|
configuration registers so that just 3 addresses are not even
|
|
sufficient for the configuration registers on a single card. To solve
|
|
this problem, each card is assigned a card number (handle) using a
|
|
technique called "isolation". See <ref id="isolation_" name="ISA
|
|
Isolation"> for the complex details.
|
|
|
|
Then to configure a certain card, its card number (handle) is sent
|
|
out via the write-port address to tell that card that it is to listen
|
|
at its address port. All other cards note that this isn't their card
|
|
number and thus don't listen. Then the address of a configuration
|
|
register (for that card) is sent to the address-port (for all cards
|
|
--but only one is listening). Next, data transfer takes place with
|
|
that configuration register on that card by either doing a read on the
|
|
read-port or a write on the write-port.
|
|
|
|
The write-port is always at A79 and the address-port is always at 279
|
|
(hex). The read-port is not fixed but is set by the configuration
|
|
software at some address (in the range 203-3FF) that will hopefully
|
|
not conflict with any other ISA card. If there is a conflict, it will
|
|
change the address. All PnP cards get "programmed" with this address.
|
|
Thus if you use say isapnp to set or check configuration data it must
|
|
determine this read-port address.
|
|
|
|
<sect1> Interrupts --Details <label id="interrupt_detail">
|
|
<p> Interrupts convey a lot of information but only indirectly. The
|
|
interrupt request signal (a voltage on a wire) just tells a chip
|
|
called the interrupt controller that a certain device needs attention.
|
|
The interrupt controller then signals the CPU. The CPU then
|
|
interrupts whatever it was doing, finds the driver for this device and
|
|
runs a part of it known as an "interrupt service routine" (or
|
|
"interrupt handler"). This "routine" tries to find out what has
|
|
happened and then deals with the problem. For example, bytes may need
|
|
to be transferred from/to the device. This program (routine) can
|
|
easily find out what has happened since the device has registers at
|
|
addresses known to the the driver software (provided the IRQ number
|
|
and the I/O address of the device has been set correctly). These
|
|
registers contain status information about the device . The software
|
|
reads the contents of these registers and by inspecting the contents,
|
|
finds out what happened and takes appropriate action.
|
|
|
|
Thus each device driver needs to know what interrupt number (IRQ) to
|
|
listen to. On the PCI bus (and for some special cases on the ISA bus)
|
|
it's possible for two (or more) devices to share the same IRQ number.
|
|
When such an interrupt is issued, the CPU runs all interrupt service
|
|
routines for all devices using that interrupt. The first thing the
|
|
first service routine does is to check its device registers to see if
|
|
an interrupt actually happened for its device. If it finds that its
|
|
device didn't issue an interrupt (a false alarm) it likely will
|
|
immediately exit and the service routine begins for the second device
|
|
using that same interrupt, etc, etc.
|
|
|
|
The putting of a voltage on the IRQ line is only a request that the
|
|
CPU be interrupted so it can run a device driver. In almost all cases
|
|
the CPU is interrupted per the request. But interrupts may be
|
|
temporarily disabled or prioritized so that in rare cases the actual
|
|
interrupt doesn't happen (or gets delayed). Thus what was above
|
|
called an "interrupt" is more precisely only an interrupt request
|
|
and explains why IRQ stands for Interrupt ReQuest.
|
|
|
|
<sect1> PCI Interrupts
|
|
<p> There are two newer developments in PCI interrupts that are not
|
|
covered here. They are especially important for cases of more than
|
|
one CPU per computer. One is the Advanced Programmable Interrupt
|
|
Controller (APIC). See the file "IO-APIC" in the i386 directory of
|
|
the kernel documentation. Another new development is Message
|
|
Signalled Interrupts (MSI) where the interrupt is just a message sent
|
|
to a special address over the main computer bus (no interrupt lines
|
|
needed). But the device that sends such a message must first gain
|
|
control of the main bus so that it can send the interrupt message.
|
|
Such a message contains more info than just "I'm sending an
|
|
interrupt".
|
|
|
|
Ordinary PCI interrupts are different than ISA interrupts, but since
|
|
they are normally mapped to IRQs they behave in about the same way.
|
|
One major difference is that the BIOS does this mapping. Under Linux
|
|
it's not feasible to change it ?? unless the CMOS menu will let you do
|
|
it. But if you have the advanced APIC then there's a way to specify
|
|
it.
|
|
|
|
Another major difference is that PCI interrupts may be shared.
|
|
For example IRQ5 may be shared between two PCI devices. This sharing
|
|
ability is built into the hardware and all device drivers are supposed
|
|
to support it. Note that you can't share the same interrupt between
|
|
the PCI and ISA bus. However, illegal sharing will work provided the
|
|
devices which are in conflict are not in use at the same time. "In
|
|
use" here means that a program is running which "opened" the device in
|
|
its C programming code.
|
|
|
|
Here are some of the details of the PCI interrupt system. Each PCI
|
|
card (and device mounted on the motherboard) has 4 possible
|
|
interrupts: INTA#, INTB#, INTC#, INTD#. From now on we will call them
|
|
just A, B, C, and D. Each has its own pin on the edge connector of a
|
|
PCI card. Thus for a 7-slot system (for 7 cards) there could be 7 x 4
|
|
= 28 different interrupt lines for the cards. But the specs permit a
|
|
fewer number of interrupt lines, so many PCI buses seem to be made
|
|
with only 4 interrupt lines. This is not too restrictive since
|
|
interrupts may be shared. Call these lines (wires or traces) W, X, Y,
|
|
Z. There is an "interrupt router" chip that routes W, X, Y, Z to
|
|
selected IRQs. This routing can be changed by the BIOS or software.
|
|
For example, W may be routed to IRQ5. Suppose we designate the B
|
|
interrupt from slot 3 as interrupt 3B. Then interrupt 3B could be
|
|
permanently connected to W which is routed to IRQ5.
|
|
|
|
One simple method of connecting (hard-wiring) these lines from PCI
|
|
devices (such as 3B) to the interrupts W, etc. would be to connect all
|
|
A interrupts (INTA#) to line W, all B's to X, etc. This method was
|
|
once used many years ago but it is not a good solution. Here's
|
|
why. If a card only needs one interrupt, it's required that it use A.
|
|
If it needs two interrupts, it must use both A and B, etc. Thus INTA#
|
|
is used much more often than INTD#. So one winds up with an excessive
|
|
number of interrupts sharing the first line (W connected to all the
|
|
INTA#). To overcome this problem one may connect them in a more
|
|
complicated way so that each of the 4 interrupt lines (W, X, Y, Z)
|
|
will share about the same number of actual PCI interrupts.
|
|
|
|
One method of doing this would be to have wire W share interrupts 1A,
|
|
2B, 3C, 4D, 5A, 6B, 7C. This is done by physically connecting wire W
|
|
to wires 1A, 2B, etc. Likewise wire X could be connected to wires 1B,
|
|
2C, 3D, 4A, 5B, 6C, 7D, etc. Then on startup, the BIOS maps the X, W,
|
|
Y, Z to IRQs. After that it writes the IRQ that each device uses into
|
|
a hardware configuration register in each device. From then on, any
|
|
program interrogating this register can find out what IRQ the device
|
|
uses. Note that writing the IRQ in a register on a PCI card doesn't
|
|
in any way set the IRQ for that device.
|
|
|
|
A card in a slot may have up to 8 devices on it but there are only 4
|
|
PCI interrupts for it (A, B, C, D). This is OK since interrupts may
|
|
be shared so that each of the 8 devices (if they exist) can have an
|
|
interrupt. The PCI interrupt letter of a device is often fixed and
|
|
hardwired into the device. The assignment of interrupts is done by
|
|
the BIOS mapping the PCI interrupts to the ISA interrupts as mentioned
|
|
above. If there are only 4 lines (W, X, Y, and Z) as in the above
|
|
example, the mapping choices that the PCI BIOS has are limited. Some
|
|
motherboards may use more lines and thus have more choices. The BIOS
|
|
knows about how this is wired.
|
|
|
|
On the PCI bus, the BIOS assigns IRQs (interrupts) so as to avoid
|
|
conflicts with the IRQs it knows about on the ISA bus. Sometimes
|
|
the CMOS BIOS menu may allow one to assign IRQs to PCI cards or to
|
|
tell the BIOS what IRQs are to be reserved for ISA devices.
|
|
Also, a PnP operating system (for example MS Windows) could attempt to
|
|
assign IRQs after first finding out what the BIOS has done. The
|
|
assignments are known as a "routing table". If MS Windows makes such
|
|
IRQ assignment dynamically (such as a docking event) it's called
|
|
"IRQ steering". The BIOS may support it's own IRQ steering (which
|
|
Linux could use). Thus if Windows 9x changes what the BIOS set and you
|
|
use Linux after Windows without turning off your PC, the IRQs may be
|
|
different. Windows 2000 and XP doesn't change what the BIOS has set,
|
|
but it may add a new device (with a new IRQ).
|
|
|
|
You might think that since the PCI is using IRQs (designed for the ISA
|
|
bus) it might be slow since the ISA bus is slow. Not really. The ISA
|
|
Interrupt Controller Chip(s) has a direct interrupt wire going to the
|
|
CPU so it can get immediate attention. While signals on the ISA
|
|
address and data buses may be slow to get to the CPU, the IRQ
|
|
interrupt signals get there almost instantly.
|
|
|
|
<sect1> ISA Isolation <label id="isolation_">
|
|
<p> This is only for the ISA bus. Isolation is a complex method of
|
|
assigning a temporary handle (id number or Card Select Number = CSN)
|
|
to each PnP device on the ISA bus. Since there are more efficient
|
|
(but more complex) ways to do this, some might claim that it's a
|
|
simple method. Only one write address is used for PnP writes to all
|
|
PnP devices so that writing to this address goes to all PnP device
|
|
that are listening. This write address is used to send (assign) a
|
|
unique handle to each PnP device. To assign this handle requires that
|
|
only one device be listening when the handle is sent (written) to this
|
|
common address. All PnP devices have a unique serial number which
|
|
they use for the process of isolation. Doing isolation is something
|
|
like a game. It's done using the equivalent of just one common bus
|
|
wire connecting all PnP devices to the isolation program.
|
|
|
|
For the first round of the "game" all PnP devices listen on this wire
|
|
and send out simultaneously a sequence of bits to the wire. The
|
|
allowed bits are either a 1 (positive voltage) or an "open 0" of no
|
|
voltage (open circuit or tri-state). To do this, each PnP device just
|
|
starts to sequentially send out its serial number on this wire,
|
|
voltage (open circuit or tri-state). To do this, each PnP device just
|
|
starts to sequentially send out its serial number on this wire,
|
|
bit-by-bit, starting with the high-order bit. If any device sends a
|
|
1, a 1 will be heard on the wire by all other devices. If all devices
|
|
send an "open 0" nothing will be heard on the wire. The object is to
|
|
eliminate (by the end of this first round) all but highest serial
|
|
number device. "Eliminate" means to drop out of this round of the
|
|
game and thus temporarily cease to listen anymore to the wire. (Note
|
|
that all serial numbers are of the same length.) When there remains
|
|
only one device still listening, it will be given a handle (card
|
|
number).
|
|
|
|
First consider only the high-order bit of the serial number which is
|
|
put on the wire first by all devices which have no handle yet. If any
|
|
PnP device sends out a 0 (open 0) but hears a 1, this means that some
|
|
other PnP device has a higher serial number, so it temporarily drops
|
|
out of this round. Now the devices remaining in the game (for this
|
|
round) all have the same leading digit (a 1) so we may strip off this
|
|
digit and consider only the resulting "stripped serial number" for
|
|
future participation in this round. Then go to the start of this
|
|
paragraph and repeat until the entire serial number has been examined
|
|
for each device (see below for the all-0 case).
|
|
|
|
Thus it's clear that only cards with the lower serial number get
|
|
eliminated during a round. But what happens if all devices in the
|
|
game all send out a 0 as their high-order bit? In this case an "open
|
|
0" is sent on the line and all participants stay in the game. If they
|
|
all have a leading 0 then this is a tie and the 0's are stripped off
|
|
just like the 1's were in the above paragraph. The game then
|
|
continues as the next digit (of the serial number) is sent out.
|
|
|
|
At the end of the round (after the low-order bit of the serial number
|
|
has been sent out) only one PnP device with the highest serial number
|
|
remains in the game. It then gets assigned a handle and drops out of
|
|
the game permanently. Then all the dropouts from the previous round
|
|
(that don't have a handle yet) reenter the game and a new round begins
|
|
with one less participant. Eventually, all PnP devices are assigned
|
|
handles. It's easy to prove that this algorithm works. The actual
|
|
algorithm is a little more complex than that presented above since
|
|
each step is repeated twice to ensure reliability and the repeats are
|
|
done somewhat differently (but use the same basic idea).
|
|
|
|
Once all handles are assigned, they are used to address each PnP
|
|
device for sending/reading configuration data. Note that these
|
|
handles are only used for PnP configuration and are not used for
|
|
normal communication with the PnP device. When the computer starts
|
|
up a PnP BIOS will often do such an isolation and then a PnP
|
|
configuration. After that, all the handles are "lost" so that if one
|
|
wants to change (or inspect) the configuration again, the isolation
|
|
must be done over again.
|
|
|
|
END OF Plug-and-Play-HOWTO
|
|
</article>
|
|
|