mirror of https://github.com/tLDP/LDP
2844 lines
153 KiB
Plaintext
2844 lines
153 KiB
Plaintext
<!doctype linuxdoc system>
|
|
<article>
|
|
<title> Plug-and-Play-HOWTO
|
|
<author>David S. Lawyer
|
|
<tt><url url="mailto:dave@lafn.org"></tt>
|
|
<date> v1.15, August 2007
|
|
<!--
|
|
Revision history:
|
|
v1.15 Aug. 2007 Revised interrupt sections. Removed 2
|
|
redundant and confusing paragraphs containing a mystery function "h()"
|
|
v1.14 Feb. 2006: Revised "How Linux Does PnP"; LPC was intended to be
|
|
config. by the BIOS. Balancing IRQs. Linux can find drivers for
|
|
detected devices. Fixed typos "the the"
|
|
v1.13 July 2005: IRQ conflicts. Better clarity in resource
|
|
descriptions. /proc/bus. PCI configuration space accessed via IO
|
|
address space. More hardware detection tools. "Can't allocate
|
|
region" error message.
|
|
v1.12 Mar. 2005: /dev/eth0 doesn't exist anymore. Info in /sys and
|
|
/proc changed for kernel 2.6. PCI Config. address space is
|
|
"geographic". scanpci may find a device that lspci can't. Kernel may
|
|
assign addresses at boot-time.
|
|
v1.11 Nov. 2004: LPC bus. Format error (text in contents)
|
|
v1.10 August 2004: sysfs not yet as useful as claimed, obsolete card info
|
|
moved to "Historical" section.
|
|
v1.09 August 2004: Edited per long email from Ross Boylan
|
|
<ross@biostat.ucsf.edu>. Clarity re telling BIOS if it's a PnP OS.
|
|
/proc/isapnp covered. Typos fixed. sysfs in kernel 2.6.
|
|
v1.08 June 2004: Edited all except appendix for more clarity and to
|
|
correct some obsolete statements in view of the increasing PnP
|
|
abilities of Linux. Added brief info on "hot plug" and USB.
|
|
More I/0 space on PCI bus.
|
|
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>
|
|
Explains in detail low-level resources such as addresses, interrupts,
|
|
etc. Covers both the PCI bus, which is inherently Plug and Play (PnP)
|
|
and PnP on the old ISA bus. If PnP did it's job right, you wouldn't
|
|
need this howto. But in case it doesn't, or if you have old hardware
|
|
that doesn't use PnP for all the cards, then this HOWTO should help.
|
|
It doesn't cover what's called "Universal Plug and Play" (UPnP).
|
|
</abstract>
|
|
<toc>
|
|
|
|
<sect> Introduction
|
|
<sect1>1. Copyright, Trademarks, Disclaimer, & Credits
|
|
|
|
<sect2> Copyright
|
|
<p> Copyright (c) 1998-2007 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> March 2000: Daniel Scott proofread this and found many
|
|
typos, etc.
|
|
<item> June 2000: Pete Barrett gave a workaround to prevent Windows
|
|
from zeroing PCI IRQs.
|
|
<item> August 2004: Ross Boylan found typos, etc. and pointed out lack
|
|
of clarity in telling the BIOS if it's a PnP OS
|
|
</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 several 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 and the
|
|
kernel to implement Plug-and-Play. But I have sampled a little of it
|
|
(especially some of the comments). Thus this HOWTO is still incomplete.
|
|
It needs to explain more about "hot swapping", "hot-plug" and about
|
|
the new PnP software for kernel 2.6. The history of Linux PnP is
|
|
not well covered. Also, it doesn't cover firewire. 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 year
|
|
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.15, August 2007 .
|
|
|
|
<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://cvsview.tldp.org/index.cgi/LDP/howto/linuxdoc/Plug-and-Play-HOWTO.sgml">
|
|
|
|
<itemize>
|
|
<item>v1.15 Aug. 2007 Revised interrupt sections. Removed 2
|
|
redundant and confusing paragraphs containing a mystery function "h()"
|
|
<item>v1.14 Feb. 2006: Revised "How Linux Does PnP"; LPC was intended to be
|
|
config. by the BIOS. Balancing IRQs. Linux can find drivers for
|
|
detected devices.
|
|
<item>v1.13 July 2005: IRQ conflicts. Better clarity in resource
|
|
descriptions. /proc/bus. PCI configuration space accessed via IO
|
|
address space. More hardware detection tools. "Can't allocate
|
|
region" error message.
|
|
<item>v1.12 March 2005: /dev/eth0 doesn't exist anymore. Info in /sys and
|
|
/proc changed for kernel 2.6. PCI Config. address space is
|
|
"geographic". scanpci may find a device that lspci can't. Kernel may
|
|
assign addresses at boot-time.
|
|
</itemize>
|
|
|
|
<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
|
|
finds all devices on the PCI bus and all devices that support PnP on
|
|
the old ISA bus. Before PnP, many devices were automatically
|
|
searched for by non-PnP methods, but were sometimes not found. PnP
|
|
provides a way to find all devices that support PnP. It also does
|
|
some low-level configuring of them. Non-PnP devices (or PnP devices
|
|
which have not been correctly PnP-configured), can often be detected
|
|
by non-PnP methods. The PCI bus is inherently PnP while the old ISA
|
|
bus originally wasn't PnP but had PnP support added to it later. So
|
|
sometimes PnP is used to only mean PnP for the old ISA bus. For
|
|
example, when you see a boot-time message from "isapnp" and it reads:
|
|
"Plug & Play device" it only means an ISA Plug & Play device. In
|
|
this HOWTO, PnP means PnP for both the ISA and the PCI bus.
|
|
|
|
As time goes by the Linux kernel is became better at supporting PnP.
|
|
In the late 20th century, one could say that Linux was not really a
|
|
PnP OS. But the claim is made that with version 2.6 of the kernel,
|
|
Linux is now fully PnP (provided the kernel is built with appropriate
|
|
PnP support). While the PnP system is not centralized like it is in
|
|
MS Windows (with its registry) the decentralized Linux PnP seems to
|
|
work OK.
|
|
|
|
Linux does keep track of resource assignments requested by device
|
|
drivers and refuses any request if it thinks it would cause a
|
|
conflict. The kernel also provides programs that device drivers can
|
|
call on to do their own plug-and-play. The kernel also reads all
|
|
configuration registers of all PnP devices and maintains tables of
|
|
them that device drivers can consult. This table helps drivers find
|
|
their hardware. Kernel 2.6 provides better support for "hot plug".
|
|
|
|
The BIOS hardware of your PC likely does some plug-and-play work too.
|
|
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
|
|
something about how communication takes place inside the computer.
|
|
If you have a modern computer with a PCI bus but no ISA bus, you may
|
|
skip over or skim the parts about the ISA bus.
|
|
|
|
If you're having problems with a device, watch the messages displayed
|
|
at boot-time (go back thru them using Shift-PageUp). If this doesn't
|
|
also display early messages from the BIOS use the "Pause" key. See
|
|
<ref id="pause_" name="Pause">
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
The PCI bus computers (no ISA bus) have significantly reduced the
|
|
number of things that can go wrong. For the ISA bus and the lack of
|
|
kernel support for ISA Pnp (before kernel 2.4), there was much more
|
|
that could go wrong. 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="dev_commun" name="Hardware Devices and Communication with
|
|
them">
|
|
|
|
<p> Oversimplified, Plug-and-Play 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 and
|
|
sets the following "bus-resources" in hardware: I/O addresses, memory
|
|
regions, IRQs, DMA channels (LPC and ISA buses only). These 4 things
|
|
are sometimes called "1st order resources" or just "resources". Pnp
|
|
maintains a record of what it's done and allows device drivers to get
|
|
this information. 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 actual driver and the "files" for it 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 all 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 as for MS
|
|
Windows) simply calls bus-resources "resources", I sometimes use the
|
|
term "bus-resources" instead of just "resources" so as to distinguish
|
|
it from the multitude of other kinds of resources.
|
|
|
|
PnP is a process which is done by various software and hardware. If
|
|
there was just one program that handled PnP in Linux, it would be simple.
|
|
But with Linux each device driver does it's own PnP, using software
|
|
supplied by the kernel. The BIOS hardware of the PC does PnP when a
|
|
PC is first powered up. And there's a lot more to it than this.
|
|
|
|
<sect1> Hardware Devices and Communication with them<label id="dev_commun">
|
|
<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 devices, modem cards, sound devices, the
|
|
USB bus, serial and parallel ports, etc. In olden days most devices
|
|
were on cards inserted into slots in the PC. Today, many devices that
|
|
were formerly cards, are now on-board since they are contained in chips
|
|
on the motherboard. 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.
|
|
|
|
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.
|
|
|
|
The eth0 device is for an ethernet card (nic card). Formerly it was /dev/eth0
|
|
but it's now just a virtual device in the kernel. What eth0 refers to depends
|
|
on the type of ethernet card you have. If the driver is a module, this
|
|
assignment is likely in an internal kernel table but might be found in
|
|
/etc/modules.conf (called "alias"). For example, if you have an ethernet card
|
|
that uses the "tulip" chip you could put "alias eth0 tulip" into
|
|
/etc/modules.conf so that when your computer asks for eth0 it finds the tulip
|
|
driver. However, modern kernels can usually find the right driver module so
|
|
that you seldom need to specify it yourself.
|
|
|
|
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 many other
|
|
devices.
|
|
|
|
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> The PCI bus has 3 address spaces: I/O, main memory (IO memory),
|
|
and configuration. The old ISA bus lacks a genuine "configuration"
|
|
address space. Only the I/0 and IO memory spaces are used for device
|
|
IO. Configuration addresses are fixed and can't be changed so they
|
|
don't need to be allocated. For more details see <ref id="pci_conf"
|
|
name="PCI Configuration Address Space">
|
|
|
|
When the CPU wants to access a device, it puts the device's
|
|
address on a major bus of the computer (for PCI: the address/data
|
|
bus). All types of addresses (such as both I/O and main memory) share
|
|
the same bus inside the PC. But the presence or absence of voltage on
|
|
certain dedicated wires in the PC's bus tells which "space" an address
|
|
is in: I/O, main memory, (see <ref id="mem_" name="Memory Ranges">),
|
|
or configuration (PCI only). This is a little oversimplified since
|
|
telling a PCI device that it's a configuration space access is
|
|
actually more complex than described above. See <ref id="pci_conf"
|
|
name="PCI Configuration Address Space"> for details. See <ref
|
|
id="address_details" name="Address Details"> for more details on
|
|
addressing in general.
|
|
|
|
The addresses of a device are stored in it's registers in the physical
|
|
device. They can be changed by software and they can be disabled so
|
|
that the device has no address at all. Except that the PCI
|
|
configuration address can't be changed or disabled.
|
|
|
|
<sect1> I/O Addresses (principles relevant to other resources too)
|
|
<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. in the hardware (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 (sort of). The device
|
|
driver doesn't actually need to set an I/O address if it finds out
|
|
that the address has been previously set (perhaps by the BIOS) and is
|
|
willing to accept that address. Once the driver has either found out
|
|
what address has been previously set or sets the address itself, then
|
|
it obviously knows what the address is so there is no need to let the
|
|
driver know the address --it already knows it.
|
|
|
|
The two step process above (1. Set the address in the hardware. 2.
|
|
Let the driver know it.) 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
|
|
people who might want to go to this address must obtain (and write
|
|
down) this house number so that they can find the house. For
|
|
computers, the device hardware must first get its address put into a
|
|
special register in its hardware (put up the house number) and then
|
|
the device driver must obtain this address (write the house number in
|
|
its address book). Both of these must be done, either automatically
|
|
by software or by entering the data manually into configuration files.
|
|
Problems may occur when only one of them gets done right.
|
|
|
|
For manual PnP configuration some people make the mistake of doing
|
|
only one of these two steps 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 you told the driver wrong then you're in trouble.
|
|
Another way to tell the driver is to give the address as an option to
|
|
a kernel module (device driver). If what you tell it is wrong, there
|
|
could be problems. A smart driver may detect how the hardware is
|
|
actually set and reject the incorrect information supplied by the
|
|
option (or at least issue an error message).
|
|
|
|
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 yet).
|
|
|
|
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 interrupts on the PCI bus are
|
|
not set by card registers but are instead routed (mapped) to IRQs by a
|
|
chip on the motherboard. Then the IRQ a PCI card is routed to is
|
|
written into the card's register for information purposes only.
|
|
|
|
To see what IO addresses are used on your PC, look at the /proc/ioports
|
|
file.
|
|
|
|
<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 inside the physical device but the
|
|
computer accesses it just like it would access memory on memory chips.
|
|
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
|
|
used by your ordinary RAM memory chips so it shows memory allocation
|
|
in general and not just iomem allocation. If you see a strange number
|
|
instead of a name, it's likely the number of a PCI device which you
|
|
can verify by typing "lspci".
|
|
|
|
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 the main memory modules
|
|
(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 Input-Output (IO)
|
|
but it's not done in IO space. Both the card and the device driver
|
|
need to know the memory range.
|
|
|
|
ROM (Read Only Memory) on cards is a different kind of iomem. 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 want to 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 be receiving a lot of bytes destined for
|
|
main memory and its buffer used to store these bytes is almost full.
|
|
Thus the device needs to tell its driver to fetch these bytes at once
|
|
before the buffer overflows from the incoming flow of bytes. 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 that 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 (also called line or
|
|
trace) 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 (or 24, etc.) 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
|
|
such "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 (two or more PCI devices may have the same
|
|
IRQ number). Also, for PCI, each PCI device has a fixed "PCI
|
|
Interrupt" wire. But a programmable routing chip maps the PCI wires
|
|
to ISA-type interrupts. See <ref id="interrupt_detail" name=
|
|
"Interrupts --Details"> for details on how all the above works.
|
|
|
|
<sect1> DMA (Direct Memory Access) or Bus Mastering <label id="dma_">
|
|
<p>For the PCI bus, DMA and Bus Mastering mean the same thing. Prior
|
|
to the PCI bus, Bus Mastering was rare and DMA worked differently and
|
|
was slow. Direct Memory Access (DMA) is where a device is allowed to
|
|
take over the main computer bus from the CPU and transfer bytes
|
|
directly to main memory or to some other device. Normally the CPU
|
|
would make a transfer from a device to main memory in a two step
|
|
process: <enum> <item>reading a chunk of bytes from the I/O memory
|
|
space of the device and putting these bytes into CPU itself <item>
|
|
writing these bytes from the CPU to main memory </enum>
|
|
|
|
With DMA it's a one step process of sending the bytes directly from
|
|
the device to memory. The device must have DMA 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 old ISA bus can do slow DMA while the PCI bus does "DMA" by
|
|
Bus Mastering. The LPC bus has both the old DMA and the new DMA (bus
|
|
mastering). On the PCI bus, what more precisely should be called "bus
|
|
mastering" is often called "Ultra DMA", "BM-DNA", "udma", or just
|
|
"DMA", Bus mastering 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 and no
|
|
dma channel resources exist for this bus. The LPC (Low Pin Count) bus
|
|
is supposed to be configured by the BIOS so users shouldn't need to
|
|
concern themselves with its DMA channels.
|
|
|
|
<sect1> DMA Channels (not for PCI bus) <label id="dma_isa">
|
|
<p>This is only for the LPC bus and the old ISA bus. When a device
|
|
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 for data
|
|
flow 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 letting the device
|
|
driver to find out about it. For example, a serial port uses only 2
|
|
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). Old hardware (in the mid 1990's) used switches (or
|
|
jumpers) to physically set the IRQ and address in the hardware.
|
|
This setting remained fixed until someone remover the computer's cover
|
|
and moved the jumpers.
|
|
|
|
But for the case of PnP (no jumpers), 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> Resources are Limited
|
|
<sect2> Ideal Computers
|
|
<p> The architecture of the PC provides only a limited number of
|
|
resources: IRQ's, DMA channels, I/O address, and memory regions. If
|
|
there were only a limited number devices and they all used
|
|
standardized bus-resources values (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 on the ISA
|
|
bus, etc. Each driver would be programmed with the unique addresses,
|
|
IRQ, etc. hard-coded into the program. Life would be simple.
|
|
|
|
Another way to prevent address conflicts would be to have each card's
|
|
slot number included as part of the address. Thus there could be no
|
|
address conflict between two different cards (since they are in
|
|
different slots). Card design would not allow address conflicts
|
|
between different functions of the card. It turns out that the
|
|
configuration address space (used for resource inquiry and assignment)
|
|
actually does this. But it's not done for I/O addresses nor memory
|
|
regions. Sharing IRQs as on the PCI bus also avoids conflicts but may
|
|
cause other problems.
|
|
|
|
<sect2> Real Computers
|
|
<p>But PC architecture has conflict problems. The increase in the
|
|
number of devices (including multiple devices of the same type) has
|
|
tended to increase potential conflicts. At the same time, the
|
|
introduction of the PCI bus, where two or more devices can share the
|
|
same interrupt and the introduction of more interrupts, has tended to
|
|
reduce conflicts. The overall result, due to going to PCI, has been a
|
|
reduction in conflicts since the scarcest resource is IRQs. However,
|
|
even on the PCI bus it's more efficient to avoid IRQ sharing. In some
|
|
cases where interrupts happen in rapid succession and must be acted on
|
|
fast (like audio) sharing can cause degradation in performance. So
|
|
it's not good to assign all PCI devices the same IRQ, the assignment
|
|
needs to be balanced. Yet some people find that all their PCI devices
|
|
are on the same IRQ.
|
|
|
|
So devices need to have some flexibility so that they can be set to
|
|
whatever address, IRQ, etc. is needed to avoid any conflicts and
|
|
achieve balancing. 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. This is more likely to happen for the case of
|
|
old-fashioned manual configuration where the user types in the
|
|
resources used into a configuration file stored on the harddrive.
|
|
This often worked OK when resources were set by jumpers on the cards
|
|
(provided the user knew how they were set and made no mistakes in
|
|
typing this data to configuration files). But with resources being
|
|
set by PnP software, they may not always get set the same and this
|
|
may mean trouble for any manual configuration where the user types in
|
|
the values of bus-resources that were set by PnP.
|
|
|
|
The allocation of bus-resources, if done correctly, establishes
|
|
non-conflicting 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 more than one-way communications 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> Second 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, PnP means
|
|
the configuring PnP bus-resources (setting them in the physical
|
|
devices) and letting the device drivers know about it. For the case
|
|
of Linux, it is often just a driver determining how the BIOS has set
|
|
bus-resources and if necessary, the driver giving a command to change
|
|
(reset) the bus-resources. "PnP" often just means PnP on the ISA
|
|
bus so that the message from isapnp: "No Plug and Play device found"
|
|
just means that no ISA PnP devices were found. The standard PCI
|
|
specifications (which were invented before coining the term "PnP")
|
|
provide the equivalent of PnP for the PCI bus.
|
|
|
|
PnP matches up devices with their device drivers and specifies their
|
|
communication channels (by allocating bus-resources). It
|
|
electronically communicates with configuration registers located
|
|
inside the physical devices using a standardized protocol. On the ISA
|
|
bus before Plug-and-Play, the bus-resources were formerly set in
|
|
hardware devices by jumpers or switches. Sometimes the bus-resources
|
|
could be set into the hardware electronically by a driver (usually
|
|
written only for a MS OS but in rare cases supported by a Linux
|
|
driver). This was something like PnP but there was no standardized
|
|
protocol used so it wasn't really PnP. Some cards had jumper setting
|
|
which could be overridden by such software. For Linux before PnP,
|
|
most software drivers were assigned bus-resources by configuration
|
|
files (or the like) or by probing the for the device at addresses
|
|
where it was expected to reside. But these methods are still in use
|
|
today to allow Linux to use old non-PnP hardware. And sometimes these
|
|
old methods are still used today on PnP hardware (after say the BIOS
|
|
has assigned resources to hardware by PnP methods).
|
|
|
|
The PCI bus was PnP-like from the beginning, but it's not usually
|
|
called PnP or "plug and play" with the result that PnP often means PnP
|
|
on the ISA bus. But PnP in this documents usually means PnP on either
|
|
the ISA or PCI bus.
|
|
|
|
<sect1> How Pnp Works (simplified)
|
|
<p> Here's how PnP should work in theory. The hypothetical 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 indirectly 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
|
|
configuration registers on the card. It then assigns the card IRQ5
|
|
and 1 MB of memory addresses space, starting at address 0xe9000000.
|
|
The PnP program also reads identifying information from the card telling
|
|
what type of device it is, its ID number, etc. Then it directly or
|
|
indirectly tells the appropriate device driver what it's done. If
|
|
it's the driver itself that is doing the PnP, then there's no need to
|
|
find a driver for the device (since it's driver is already running).
|
|
Otherwise a suitable device driver needs to be found and sooner or
|
|
later told how it's device is configured.
|
|
|
|
It's not always this simple since 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 get it's final allocation of resources until the
|
|
driver starts up, so one way to avoid conflicts is just not to start
|
|
any device that might cause a conflict. However, the BIOS often
|
|
allocates resources to the physical device before Linux is even booted
|
|
and the kernel checks PCI devices for addresses conflicts at boot-time.
|
|
|
|
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. BIOSs do this as does MS
|
|
Windows and this but standard Linux doesn't. But in a way it does
|
|
since it often uses what the BIOS has done. Windows stores this info
|
|
in its "Registry" on the hard disk and a PnP/PCI BIOS stores it in
|
|
non-volatile memory in your PC (known as ESCD; see <ref id="escd_"
|
|
name="The BIOS's ESCD Database">). Some say that not having a
|
|
registry (like Linux) is better since with Windows, the registry may
|
|
get corrupted and is difficult to edit. But PnP in Linux has problems
|
|
too.
|
|
|
|
While MS Windows (except for Windows 3.x and NT4) were PnP, Linux was
|
|
not originally a PnP OS but has been gradually becoming a PnP OS. PnP
|
|
originally worked for 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 always rely on the BIOS. Unfortunately a driver
|
|
could grab 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 its previous configuration, then
|
|
there wouldn't be any hardware to PnP configure at the next boot-time.
|
|
But hardware seems to forget its 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 too. 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
|
|
motherboard 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 the device
|
|
drivers of what it did). But the drivers can still find out this by
|
|
utilizing functions available in the Linux kernel.
|
|
|
|
<sect1> Buses
|
|
|
|
<p>To see what's on the PCI bus type <tt/lspci/ or <tt/lspci -vv/.
|
|
Or type <tt/scanpci -v/ for the same information in the numeric code
|
|
format where the device is shown by number (such as: "device 0x122d"
|
|
instead of by name, etc. In rare cases, <tt/scanpci/ will find a
|
|
device that <tt/lspci/ can't find.
|
|
|
|
The boot-time 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">
|
|
|
|
ISA is the old bus of the old IBM-compatible 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.
|
|
|
|
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.
|
|
|
|
As the ISA bus becomes extinct, PnP will be a little easier. It will
|
|
then not only be easier to find out how the BIOS has configured the
|
|
hardware, but there will be less conflicts since PCI can share
|
|
interrupts. 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. The serious problem of some devices not
|
|
being supported by Linux will remain.
|
|
|
|
<sect1> How Linux Does PnP <label id="how_linux_pnps">
|
|
<p> Linux has had serious problems in the past in dealing with PnP but
|
|
most of those problems have now been solved (as of mid 2004). Linux
|
|
has gone from a non-PnP system originally, to one that can be PnP if
|
|
certain options are selected when compiling the kernel. The BIOS may
|
|
assign IRQs but Linux may also assign some of them or even reassign
|
|
what the BIOS did. The configuration part of ACPI (Advance
|
|
Configuration and Power Interface) is designed to make it easy for
|
|
operating systems to do their own configuring. Linux can use ACPI if
|
|
it's selected when the kernel is compiled.
|
|
|
|
In Linux, it's traditional for each device driver to do it's own low
|
|
level configuring. This was difficult until Linux supplied software
|
|
in the kernel that the drivers could use to make it easier on them.
|
|
Today (2005) it has reached the point where the driver simply calls
|
|
the kernel function: pci_enable_device() and the device gets
|
|
configured by being enabled and having both an irq (if needed) and
|
|
addresses assigned to the device. This assignment could be what was
|
|
previously assigned by the BIOS or what the kernel had previously
|
|
reserved for it when the pci or isapnp device was detected by the
|
|
kernel. There's even an ACPI option for Linux to assign all devices
|
|
IRQs at boot-time.
|
|
|
|
So today, in a sense, the drivers are still doing the configuring but
|
|
they can do it by just telling Linux to do it (and Linux may not need
|
|
to do much since it sometimes is able to use what has already been set
|
|
by the BIOS or Linux). So it's really the non-device-driver part of
|
|
the Linux kernel that is doing most of the configuring. Thus, it may
|
|
be correct to call Linux a PnP operating system, at least for common
|
|
computer architectures.
|
|
|
|
Then when a device driver finds its device, it asks to see what
|
|
addresses and IRQ have been assigned (by the BIOS and/or Linux) and
|
|
normally just accepts them. But if the driver wants to do so, it can
|
|
try to change the addresses, using functions supplied by the kernel. But
|
|
the kernel will not accept addresses that conflict with other devices
|
|
or ones that the hardware can't support. When the PC starts up, you
|
|
may note messages on the screen showing that some Linux device drivers
|
|
have found their hardware devices and what the IRQ and address ranges
|
|
are.
|
|
|
|
Thus, the kernel provides the drivers with 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 if needed.
|
|
Kernel 2.2 could do this only for the PCI bus but Kernel 2.4 had this
|
|
feature for both the ISA and PCI buses (provided that the appropriate
|
|
PNP and PCI options have been selected when compiling the kernel).
|
|
Kernel 2.6 came out with better utilization of ACPI. This by no means
|
|
guarantees that all drivers will fully and correctly use these
|
|
features. And legacy devices that the BIOS doesn't know about, may
|
|
not get configured until you (or some configuration utility) puts its
|
|
address, irq, etc. into a configuration file.
|
|
|
|
In addition, the kernel helps avoid resource conflicts by not allowing
|
|
two devices that it knows about 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.
|
|
|
|
If your have an old ISA bus, the program isapnp should run at boottime to
|
|
find and configure pnp devices on the ISA bus. Look at the messages
|
|
with "dmesg".
|
|
|
|
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. Warning: documentation here tends to
|
|
be out-of-date so to get the latest info you would need to read
|
|
messages on mailing lists sent by kernel developers and possibly the
|
|
computer code that they write including comments. In this kernel
|
|
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 enable you to write a driver. But it will give
|
|
you some idea of what PnP type functions are available for drivers to
|
|
use.
|
|
|
|
For kernel 2.4 see isapnp.txt. For kernel 2.6, isapnp.txt is replaced
|
|
by pnp.txt which is totally different than isapnp.txt and also deals
|
|
with the PCI bus. Also see the O'Reilly book: Linux Device Drivers, 3rd
|
|
ed., 2005. The full text is on the Internet.
|
|
|
|
<sect1> Problems with Linux PnP
|
|
<p>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 by
|
|
reallocation of resources if necessary
|
|
<item>Deal with choosing a driver when there is more than one driver
|
|
for a physical device
|
|
</itemize>
|
|
|
|
Since it's each driver for itself, a driver could grab bus-resources
|
|
that are needed by other devices (but not yet allocated to them by the
|
|
kernel). Thus a more sophisticated PnP Linux kernel would be better,
|
|
where the kernel did the allocation after all requests were in.
|
|
Another alternative would be a try to reallocate resources already
|
|
assigned if a devices couldn't get the resources it requested.
|
|
|
|
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 a little 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 address space is available for device
|
|
I/0. While the conventional I/O address space of the ISA bus was
|
|
limited to 64KB, the PCI bus has 4GB of it. Since more physical
|
|
devices are using main memory addresses instead of IO address space,
|
|
there is still more space available, even on the ISA bus. 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).
|
|
|
|
There was at least one early attempt to make Linux a truly PnP
|
|
operating system. See <url
|
|
url="http://www.astarte.free-online.co.uk">. While developed around
|
|
1998 it never was put into the kernel (but probably should have been).
|
|
|
|
<sect> Setting up a PnP BIOS <label id="conf_pnp_bios">
|
|
<p> When the computer is first turned on, the BIOS program runs before
|
|
the operating system is loaded. Modern BIOSs are PnP and can
|
|
configure most of the PnP devices. Some old PCI BIOSs will only
|
|
configure 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="escd_resources" name="How are bus-resources
|
|
to be controlled?">
|
|
<item> <ref id="escd_reset" name="Reset the configuration?">
|
|
</itemize>
|
|
|
|
<sect1> Do you have a PnP operating system? <label id="bios_pnp_os">
|
|
<p> Regardless of how you answer this to the BIOS, the PnP BIOS will
|
|
PnP-configure the hard-drive, floppy, video card, and keyboard to make
|
|
the system bootable as well as configure the LPC bus (if you have
|
|
one). If you said no PnP OS then the BIOS should configure
|
|
everything.
|
|
|
|
How should you answer this question to your BIOS? If you have at
|
|
at least the 2.4 kernel you could answer it either way and Linux will
|
|
usually work fine. Even if you have Windows 2000 or XP on the
|
|
same PC, it will usually work OK either way. This is because both
|
|
Windows and Linux are supposedly PnP OS's and if the OS is PnP it
|
|
should be able to also handle the case where the BIOS has configured
|
|
everything (if you said it wasn't PnP). But I still suggest saying
|
|
that it's not a PnP OS unless there is a known reason to say
|
|
otherwise.
|
|
|
|
<sect2>Linux prior to the 2.4 kernel <label id="prior_2.4">
|
|
<p>It's not often clear whether to say yes or no. If isapnp was used
|
|
by Linux, then Linux does the configuring and it was claimed that it's
|
|
best to say it's a PnP OS. Why isapnp would have trouble when
|
|
presented with devices already configured by the BIOS isn't clear, but
|
|
such trouble sometimes happened and was fixed by stopping the BIOS
|
|
from configuring (saying yes, it's a PnP OS). There were a few cases
|
|
where saying no fixed a problem. So if isapnp is doing it's job OK,
|
|
you should probably say it's PnP. If isapnp isn't used, no is usually
|
|
best. The Linux device drivers for PCI devices should configure PCI
|
|
devices OK. But for the case of PCI devices driven by non-PCI
|
|
drivers, then you may say it's not PnP to get the BIOS to configure
|
|
them.
|
|
|
|
<sect2> Windows 2000 and XP
|
|
<p>If you also run these Windows OS's on the same PC, you should say
|
|
that you don't have a PnP OS. That's what MS suggests you do.
|
|
Perhaps MS hopes that the BIOS will do a better job at configuring
|
|
than Windows will. That makes sense because the BIOS should be
|
|
designed for the particular idiosyncrasies of the motherboard,
|
|
especially today when many devices are built into the motherboard.
|
|
PnP OS = no should also be OK for Linux kernels 2.4 and higher. But
|
|
for Linux kernel prior to 2.4, it's not clear which is best.
|
|
(see the above subsection). So if you have problems with Linux you
|
|
might try saying you have a PnP OS to satisfy Linux but this is going
|
|
against what MS suggest (but will probably work OK anyway).
|
|
|
|
When the BIOS configures a device different from what Windows has in
|
|
it's registry, Windows will tell you that it's finding new hardware.
|
|
What it's really doing is finding old hardware that has been
|
|
configured differently so it thinks it's new hardware. At any rate,
|
|
it records the configuration that the BIOS has used in its registry
|
|
and the device should work OK from now on.
|
|
|
|
<sect2> MS Windows 95, 98 (and Me ?)
|
|
<p>For Windows9x, MS suggest that you tell the BIOS that you have a
|
|
PnP OS (the exact opposite of the case for Windows 2000 and XP). This
|
|
should also be OK for Linux if you have kernel 2.4 or later. But if
|
|
you have a Linux kernel prior to 2.4 then it's best for Linux to say that
|
|
it's not a PnP OS. One way to resolve this dilemma is to set it up
|
|
for the OS you use more frequently. Then when you boot the other OS,
|
|
manually go into the BIOS and change the setting. This is a lot of
|
|
bother but it's feasible if you almost never use one of the OS's.
|
|
Otherwise there are better ways to resolved this dilemma.
|
|
|
|
The second way to resolve this dilemma is to get Linux to
|
|
resource-configure everything. See <ref id="prior_2.4" name="Linux
|
|
prior to the 2.4 kernel">. Then you tell the BIOS it's a PnP OS.
|
|
|
|
The third way to resolve this dilemma is to tell the BIOS it's not a
|
|
PnP OS. This is going against what MS says you should do, but it's
|
|
possible to get MS Windows9x to work OK if you understand what to do
|
|
(and why). If you tell the BIOS it's not a PnP OS, shouldn't MS
|
|
Windows detect how the BIOS has configured things and change it if it
|
|
doesn't like what the BIOS has done? It should, but unfortunately, it
|
|
doesn't seem to work this way.
|
|
|
|
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 and thinks the actual configuration is the same
|
|
as in the registry when in fact it's different.
|
|
|
|
But if the registry happens to contain a bus-resource configuration
|
|
that is exactly the same as how the BIOS configures things, then
|
|
everything will obviously work OK. A device will thus work fine if
|
|
the BIOS has configured it the same as recorded in the registry.
|
|
So the way to get MS Windows to work OK is to get the registry in sync
|
|
with how the BIOS configures. As mentioned previously, the BIOS
|
|
configures things per its ESCD (which is something like the registry
|
|
for the BIOS). See <ref id="escd_" name="The BIOS's ESCD Database">.
|
|
So we need to get the registry in sync with the BIOS's ESCD so that
|
|
the registry and the ESCD contain the same configuration. In some
|
|
cases, these two just happen to be in sync and you don't need to do
|
|
anything.
|
|
|
|
One question you may think of is: how did the BIOS's ESCD and Windows
|
|
registry ever get out of sync in the first place? Here's one
|
|
scenario. You install Windows with the BIOS set to a PnP OS. Then
|
|
Windows configures most everything and saves that configuration in its
|
|
registry. Then later on you change the BIOS setting to not a PnP OS.
|
|
Then upon booting, the BIOS configures everything and it doesn't do it
|
|
exactly like Windows did it. Thus the actual configuration of the
|
|
hardware and what Windows has in its registry are now different.
|
|
|
|
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 BIOS's CMOS as you start to boot).
|
|
Windows will then reinstall the devices, hopefully using the
|
|
bus-resource settings as 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"
|
|
which will avoid installing the file from a CD. If the file is still
|
|
on the HD, then the driver will hopefully find it OK even though the
|
|
Window's install program requested you install it from a CD (which you
|
|
skipped doing).
|
|
|
|
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 in a case
|
|
like this it may be better to not fib to Windows95/98 but instead to
|
|
get Linux to configure bus-resources.
|
|
|
|
When using a Window-Linux PC (dual boot) you might notice a change in
|
|
the way the BIOS configures due to Windows9x (and other versions of
|
|
Windows ??) modifying 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 as will the isapnp or
|
|
PCI Utilities programs if you run them.
|
|
|
|
<sect1> Assigning Resources by the BIOS <label
|
|
id="escd_resources">
|
|
<p>Modern BIOSs allow you to manually allocate resources, primarily
|
|
IRQs. There is usually an option to set the an allocation to "auto"
|
|
so that the BIOS decides how to allocate the resource. "Auto" is
|
|
often a good choice unless you have old legacy non-pnp ISA cards.
|
|
|
|
If you have such non-PnP cards, then it may be important to reserve
|
|
resources (such as IRQ's) for these in the BIOS. Otherwise the BIOS
|
|
may use these resources for some other device and create conflicts.
|
|
An exception is that for some common legacy devices (such as parallel
|
|
and serial ports, disk drives), the BIOS may find them (look at the
|
|
screen at boot-time) so you don't need to reserve resources for them.
|
|
If you've used Windows on your PC, it might be true that Windows has
|
|
already told the BIOS about them by running the ICU utility (or the
|
|
like) under Windows.
|
|
|
|
For PCI, the BIOS may let you assign IRQs to card slots 1, 2, 3, 4,
|
|
etc. If you do this, you should know what card is in what slot.
|
|
Actually, each slot has 4 PCI IRQs: A, B, C, and D. If the BIOS menu
|
|
doesn't say which of these (A, B, C, D) is being assigned to an IRQ
|
|
number, it's likely that it's only assigning the IRQ number to PCI IRQ
|
|
A. But many PCI cards only use IRQ A so it's then just like assigning
|
|
an IRQ to a slot. See <ref id="pci_int" name="PCI Interrupts">
|
|
|
|
<sect1> Reset the configuration? <label id="escd_reset">
|
|
<p> This is a little risky to do. It 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 Devices
|
|
<p> Today almost all new internal boards (cards) are Plug-and-Play
|
|
(PnP). Thus, the configuring of bus-resources should, in almost all
|
|
cases be entirely automatic. If a device is not working, see if it
|
|
was detected, possibly by rebooting. If the device driver can't
|
|
resource-configure it, then hopefully one or more of methods 2-6 will:
|
|
|
|
<enum>
|
|
<item> <ref id="dev_d_conf" name="Device Driver Configures">
|
|
<item> <ref id="sys_" name="/sys User Interface Configures"> kernel
|
|
2.6 + (not for PCI yet, other severe limitations)
|
|
<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="ISA Bus: Isapnp"> is a program you can always
|
|
use to configure ISA PnP devices
|
|
<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
|
|
</enum>
|
|
|
|
Any of the above will set the bus-resources in the hardware but only
|
|
the first one (and possibly the second) 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>Device drivers (with the help of code provided by the kernel)
|
|
can be written to use PnP methods to set the bus-resources in the
|
|
hardware but only for the device that they control. But many device
|
|
drivers just accept what the BIOS or Linux has configured and use code
|
|
provided by the kernel to find out how this device has been
|
|
configured. Since the driver has checked the configuration and
|
|
possibly reconfigured it, 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 configuring the BIOS at boot-time (usually), 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.
|
|
|
|
For PCI devices, most drivers will configure PnP. Unfortunately, a
|
|
driver could grab bus-resources that are needed by other devices (but
|
|
not yet allocated to them by the kernel). Thus a more sophisticated
|
|
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> /sys User Interface Configures <label id="sys_">
|
|
<p>Starting with kernel 2.6 there's supposedly a new way for the user
|
|
to resource configure using the /sys directory tree. But as of Aug.
|
|
2004, it can't be used for configuring in most cases. See <ref
|
|
id="sys_dir" name="The /sys Directory Tree">.
|
|
|
|
<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 may need
|
|
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.
|
|
|
|
Most BIOS made after about 1996 ?? can resource-configure both the PCI
|
|
and ISA buses. But it's been claimed that some older BIOSs can only
|
|
do the PCI. And of course, for PCs with only the PCI bus, the BIOS
|
|
only needs to do 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 old BIOS's 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 since
|
|
Linux can change how devices are configured (including the user using
|
|
isapnp or pci utilities) 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">. Starting with
|
|
kernel 2.6, Linux is capable of modifying the ESCD but it's not used
|
|
yet (as of Aug. 2004).
|
|
|
|
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.
|
|
|
|
There's a program that you may use to view the contents of the ESCD.
|
|
It shows IRQs and IO addresses etc., but device names are missing
|
|
(only EISA device-ID numbers). It's at: <url
|
|
url="http://home.t-online.de/home/gunther.mayer/lsescd/" name="Index
|
|
of /home/gunther.mayer/lsescd">
|
|
|
|
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>Eventually the Linux kernel may set the ESCD. Starting with kernel
|
|
2.6, a function in the new code could do it provided the kernel has
|
|
been compiled with PNPBIOS. But it currently sits in the code unused.
|
|
|
|
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. One may resort to attempting to use Windows for this (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 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 once 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. But
|
|
since Linux support for PnP has improved, you usually don't want to
|
|
disable PnP. Here's some more arguments in favor of 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 too 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> ISA Bus: 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.
|
|
Also, the BIOS may configure ISA PnP satisfactory. But the isa-pnp
|
|
module (or the equivalent built into the kernel) is now very
|
|
significant since various ISA device drivers call on it to configure
|
|
bus-resources. Prior to kernel 2.6 it resulted a /proc/isapnp "file"
|
|
which may be used to manually configure (see isapnp.txt in the kernel
|
|
documentation).
|
|
|
|
In some cases Linux distributions have been set up to run isapnp
|
|
automatically at startup. It's still done in 2004 but it isn't really
|
|
needed if the device drivers work well. 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 isapnp. 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. Then to let the driver
|
|
know the resources, you often need to specify them as parameters to
|
|
the appropriate modules (drivers). This is done with configuration
|
|
files, often in the /etc directory. Look there for files named mod*,
|
|
etc. If the driver is built into the kernel, then they may sometimes be
|
|
given as a parameter to the kernel. See BootPrompt-HOWTO.
|
|
|
|
With isapnp there once was a problem where a device driver which is
|
|
built into the kernel may run too early before isapnp has set the
|
|
address, etc. in the hardware. This resulted 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. Is this still a
|
|
problem ??
|
|
|
|
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 IO 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"), allows one to manually PnP-configure the PCI bus (with
|
|
difficulty). "lspci" or "scanpci" lists bus-resources while "setpci"
|
|
sets resource allocations (except IRQs) in the hardware devices. It
|
|
appears that setpci is mainly intended for use in scripts and one
|
|
needs to understand 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) using, for example, loadlin.exe. But there may be a
|
|
problem with IRQs for PCI devices. As Windows shuts down (without any
|
|
messages) 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. Click "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"> 1999 (Never got into
|
|
kernel but Linux is slowly "evolving" in this direction).
|
|
<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 1999. 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 the modern case the driver should 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 much 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 ISA PnP serial ports after 2.4
|
|
kernels) 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 very old older versions of the
|
|
kernel and serial driver (not for multiport cards) the driver probes
|
|
two standard addresses for serial ports. It doesn't probe for IRQs
|
|
but it just assigns the "standard" IRQ to the first two serial ports.
|
|
This could be wrong.
|
|
|
|
For anything else the configuration file for the <tt/setserial/
|
|
program must be manually modified. See Serial-HOWTO for more
|
|
details. You use setserial to inform the driver of the IO address and
|
|
Setserial is often run from a start-up file. In newer versions there
|
|
is a /etc/serial.conf file (or /var/lib/setserial/autoconfig 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 use is used to manually tell the driver the
|
|
configuration. The other use 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.
|
|
|
|
Even with modern kernels, setserial is sometimes needed if the driver
|
|
fails to detect the serial port, or if you have very old hardware.
|
|
|
|
<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 May 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 obviously
|
|
be the same (and usually is). But if things are not working right, it
|
|
could be because there's a difference. This means that 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 you need to know 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, configuration file, 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 except for the unusual case where the
|
|
hardware has been disabled. The BIOS can sometimes be set to disable
|
|
PnP devices or a jumper/switch on the physical device itself could
|
|
disable it. In such a cases, the hardware can't be detected at all
|
|
until you either reconfigure the BIOS or change a jumper/switch.
|
|
|
|
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 at likely address, in addition to using PnP methods (= PnP
|
|
probing which is sometimes also just called "probing").
|
|
|
|
Ways to Find Hardware Devices (and their configurations): (follow link
|
|
to more details)
|
|
<itemize>
|
|
<item>Check the BIOS to make sure they are not disabled
|
|
<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> <ref id="hw_detect" name="Tools for Detecting and/or Configuring
|
|
all Hardware"> lsdev, hwinfo, discover, kudzu
|
|
<item> <ref id="hw_detect_one_type" name="Tools for Detecting and/or
|
|
Configuring One Type of Hardware">
|
|
<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>Significant info on the 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 the 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. In some cases it doesn't show devices
|
|
that the BIOS didn't configure.
|
|
|
|
<label id="pause_">If the BIOS messages don't show as you back up to
|
|
the start of the BIOS messages using Shift-PageUp, try freezing them
|
|
as they flash by, by hitting the "Pause" key as soon as the first
|
|
words flash on the screen. Press any key to resume. It's often
|
|
tricky to hit Pause exactly at the right time. Be sure to hold down
|
|
the "Shift" key before hitting "Pause" since "Pause" is a shifted key.
|
|
If you miss, hit Ctrl-Alt-Del when Linux starts booting to reboot and
|
|
try again. Once the messages from Linux start to appear, it's too
|
|
late to use "Pause" since it will not freeze the messages from Linux.
|
|
|
|
To set things in the BIOS such as IRQs reserved for legacy hardware,
|
|
serial port addresses, etc. you need to get into the BIOS (CMOS) setup
|
|
menus at boot time. Each BIOS brand has different keys you need to
|
|
hold down to do this. There are lists on the Internet. Sometimes by
|
|
freezing the BIOS messages or watching the screen, the key you need to
|
|
press will be indicated in a message such as "Press DEL for setup".
|
|
But it may flash by so fast that you miss it. Of course, you don't set
|
|
stuff in the BIOS that you don't understand, or your PC may become
|
|
disabled.
|
|
|
|
Messages from the BIOS at boot-time tell you how the hardware
|
|
configuration was then. The current configuration may still be the
|
|
same since Linux should hopefully accept what the BIOS has done if
|
|
it's OK. 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 Tree<label id="proc_dir">
|
|
<p>Starting with Kernel 2.6, in addition to the /proc directory tree,
|
|
there's also a /sys tree See <ref id="sys_dir" name="The
|
|
/sys Tree">. These trees are useful for finding resource
|
|
configurations and devices. The "files" in them represent data in the
|
|
kernel memory and don't exist at all on you harddrive. Programs such
|
|
as lspci get their info from the /proc tree so such programs should
|
|
display the results in more readable form than directly inspecting the
|
|
"files" in /proc. Here are 4 /proc "files" that show resources which
|
|
have been registered in the kernel by device drivers.
|
|
|
|
Since Linux's plug-and-play works by letting device drivers allocate
|
|
resources for their device, there may be no listing of resources used
|
|
by some of your hardware if the driver hasn't yet requested that such
|
|
resources be reserved. For the case of kernel modules (loadable
|
|
device drivers), if the module hasn't loaded yet, the kernel doesn't
|
|
know about any resources it needs. Sometimes, the module only loads
|
|
when you start an application that needs it. So if certain hardware
|
|
is missing from these "files" in /proc, it may mean that the hardware
|
|
hasn't yet been 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 up unless its in use.
|
|
|
|
/pts shows I/O addresses. If there's a mistake (wrong
|
|
address) it means trouble since the device will not get bytes sent to
|
|
it.<newline>
|
|
/proc/iomem shows registered IO memory addresses.<newline>
|
|
/proc/interrupts shows the interrupts currently in use.<newline>
|
|
/proc/dma shows the dma (Direct Memory Access) ISA dma channel allocations.
|
|
|
|
In the past, the author observed the listing of interrupts that didn't
|
|
exist. In some cases it showed that a few such interrupts were
|
|
actually sent. This could be due to the issuing of erroneous
|
|
interrupts due to hardware defects.
|
|
|
|
/proc/bus/ has subdirectories (subfolders) input/, pci/, and
|
|
isapnp/. The format of most of the files in this directory is very
|
|
cryptic, often just a copy of the bytes in the configuration space.
|
|
So, use them only as a last resort. The input/ subdirectory has
|
|
information on input devices such as the keyboard and mouse. It's not
|
|
as cryptic as the other directories under /proc/bus/ and might yield
|
|
some useful information about input devices that are PS2 or on the LPC
|
|
bus (See <ref id="lpc_" name="LPC Bus">). Unfortunately, what I've
|
|
seen doesn't say that it's on the LPC bus when it likely is. In
|
|
/pci/00/ there is one binary file for each pci device where the file
|
|
names are the pci-slot-numbers (also called pci-slot-names). The 00
|
|
means pci bus 0.
|
|
|
|
<sect1> The /sys Tree<label id="sys_dir">
|
|
<p>Starting with kernel 2.6 there's a new /sys directory for PnP
|
|
configuration. It's a sysfs type of file system and it's something
|
|
like the /proc filesystem since the "files" represent information in
|
|
the kernel memory and are not on your harddrive. But it's not as
|
|
useful as the /proc filesystem. Originally (in the 2.5 kernels) it
|
|
was called "driver file system" of type "driverfs".
|
|
|
|
In the sysfs, each device which exists on your system has it's own
|
|
directory which contains files showing the resources allocated to it.
|
|
Such device directories have names like 0000:00:12.0@ or 00:06@. What
|
|
devices are these? The first is a PCI card in "slot" 12 of your PC.
|
|
The slot may actually be labeled PCI2 inside your PC (2 instead of
|
|
12). That's because low numbered "slots" are used for built-in
|
|
devices on the motherboard that don't use any physical slots. In this
|
|
example, "slots" 1-10 would be built-in and actual slots 11-14 are
|
|
labeled 1-4. By typing "lspci" you'll be able to match the numbers
|
|
(like 0000:00:12.0) to names (like IDE interface). Type "lspci -v"
|
|
or "lspci -vv" to see more.
|
|
|
|
Well then, what is 00:06 ? It's an ISA card (or built-in device) but
|
|
it's not ISA slot 6 (like the PCI numbering). When a search was made
|
|
for ISA-PNP devices, it was the 6th one found. More precisely, it was
|
|
the 7th one found since there's a device numbered: 00:00. So how does
|
|
one identify them? Well, you could type: "cat */*" and display all
|
|
the files for all the devices, but even then you don't see the device
|
|
names (but do see info from which you can identify them). This
|
|
inconvenience will hopefully be fixed in the future.
|
|
|
|
Not only do these files supply information on the bus-resource
|
|
configuration (in somewhat cryptic format) and drivers (in "driver"
|
|
directories), but in the future, you should be able to use them to
|
|
change the resource configuration. Right now (Aug 2004) you can't
|
|
configure the PCI bus with it. A serious limitation is that per the
|
|
present "driver model" you can't change the resource of a device that
|
|
has been assigned to a driver which likely means that you'll need to
|
|
unload the driver module in order to use it. If the driver is built
|
|
in, there's no hope. These serious limitations will hopefully be
|
|
eliminated in the future. In the kernel documentation is a file:
|
|
"pnp.txt" telling how to configure. As of Aug. 2004, it was much
|
|
out-of-date but the author is working on an update. Using the /sys
|
|
tree to configure resources is known as the "Linux Plug and Play User
|
|
Interface".
|
|
|
|
The other part of "Linux Plug and Play" is the kernel interface used
|
|
by device drivers. This has changed a lot starting with kernel 2.6
|
|
but most drivers are still using the old interface (as of Aug. 2004).
|
|
It's possible also for drivers (or you) to use the "user interface"
|
|
which needs improvement.
|
|
|
|
<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
|
|
The options -v or -vv will show more detail. In some cases, "scanpci"
|
|
will find a device that "lspci" can't find. That's because "scanpci"
|
|
directly searches for devices on the pci bus (via the configuration
|
|
space) and doesn't use data obtained by the kernel (where it could be
|
|
wrong due to a kernel bug --I've just found such a case).
|
|
|
|
This info in more cryptic format is found in "files" located in the
|
|
<tt>/sys</tt> and <tt>/proc</tt> trees. In
|
|
<tt>/sys/bus/pci/devices</tt> the file <tt/vendor/ will contain the
|
|
vendor id number such as 0x4B8C, etc. In still more cryptic format
|
|
it's in <tt>/proc/bus/pci</tt>. Such information in older kernels
|
|
prior to kernel 2.6, was in <tt>/proc/pci</tt> (non-cryptic but IRQs
|
|
in hexadecimal) or in <tt>/proc/buspci/devices</tt> (cryptic display).
|
|
|
|
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. Later ISA cards were PnP but older ones were
|
|
not. Also, some cards that are PnP 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>LPC Bus <label id="lpc_">
|
|
<p>LPC (Low Pin Count) is a bus-like interface often used on laptops
|
|
and increasingly used on desktops too. To find out if you have LPC
|
|
type "lspci" and look for "LPC". There are other words next to "LPC"
|
|
such as "ISA Bridge ... LPC Interface Controller" or "LPC Bridge",
|
|
etc. LPC is not really ISA but it substitutes for an ISA bus.
|
|
|
|
The old ISA bus was slow and devices that needed more speed were put
|
|
on the newer PCI but. But devices that didn't need high speed were
|
|
often implemented by chips on the motherboard and remained on the ISA
|
|
bus even though there were no slots for any ISA cards. Then the LPC
|
|
bus came along to replace what remained of the ISA bus. LPC is much
|
|
smaller than ISA and just as fast since it runs at 4 times the clock
|
|
speed of ISA. Its multiplexed bus for data/address and control is
|
|
only 4 bits wide. To send a byte requires splitting the byte into 2
|
|
half-bytes and then putting them back together. So its clear why it's
|
|
"Low Pin Count" = LPC. There's also a few other lines in the bus.
|
|
|
|
This small LPC interface is used for slow "legacy" devices such as
|
|
serial ports, parallel ports, and floppy drives. So a computer using
|
|
LPC will have all fast devices on the PCI bus, etc. and slow (legacy)
|
|
devices on the LPC bus interface. All LPC devices will be on-board;
|
|
there are no LPC slots.
|
|
|
|
LPC has no standards for Plug-and-Play configuring but says that the
|
|
BIOS or ACPI should do the configuring. Devices on this bus sometimes
|
|
use isapnp. Linux support for LPC as of late 2004 was very much
|
|
incomplete but Linux has some support for the configuring aspects of
|
|
ACPI. Sometimes a BIOS menu lets one manually PnP-configure devices
|
|
on the LPC bus but it may not tell you that the device resides on LPC.
|
|
|
|
A major chip on the LPC bus is the superio chip which contains legacy
|
|
IO devices: serial and parallel ports, floppy controller, keyboard
|
|
controller, mice, etc. BIOS data may also reside on the LPC bus. The
|
|
keyboard and mouse (input devices) should be listed in
|
|
/proc/bus/input/devices but instead of seeing "lpc" it seems to show
|
|
"isa0060/serio0, etc. even though it's on the lpc bus and not the isa
|
|
bus.
|
|
|
|
<sect1>X-bus
|
|
<p>Before the LPC bus became popular, there was an "X-bus" (not
|
|
covered in this HOWTO) which served the same purpose as the LPC bus
|
|
but wasn't so compact as LPC. Some PCs have both LPC and an X-bus.
|
|
|
|
<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
|
|
unless there is a jumper setting, etc. for disabling the device.
|
|
Sometimes the resources used 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 (yet ?) supported by Linux. 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 to
|
|
set the jumpers (or at least gives 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">. Or
|
|
try to find the MS software that configured it.
|
|
|
|
<sect1>Tools for Detecting and/or Configuring all Hardware
|
|
<label id="hw_detect">
|
|
<p>In a duplication of effort, various major distributions of Linux
|
|
developed their own tools for detection and/or configuration of
|
|
hardware. This configuring is usually a lot more than just the
|
|
resource type configuring of Plug-and-Play. It's configuring in
|
|
general which is mostly beyond the scope of this howto.
|
|
|
|
Then other distributions, such as Debian, might obtain copies of the
|
|
tool and offer it to their users as an option, or as a troubleshooting
|
|
tool. These tools likely make use of the standard Linux tools for
|
|
detecting hardware such as "lspci". In the following list of tools,
|
|
the name of the distribution that developed it is in parentheses, but
|
|
the tool is likely available also in other distributions.
|
|
|
|
<itemize>
|
|
<item>hardinfo
|
|
<item>hwinfo (SuSE) detects move stuff than discover
|
|
<item>discover (Progeny, used by Debian)
|
|
<item>Kudzu (RedHat) detects and configures
|
|
<item>lsdev (standard Linux command)
|
|
<item>hwsetup-knoppix (Knoppix, based on Kudzu)
|
|
</itemize>
|
|
|
|
<sect1>Tools for Detecting and Configuring One Type of Hardware
|
|
<label id="hw_detect_one_type">
|
|
<p>There are various tools available to find and possibly configure
|
|
various type of devices. This configuring is configuring in general
|
|
which is not covered by this howto.
|
|
|
|
<itemize>
|
|
<item>read-edid (get-edid): gets parameters of VESA monitors (except
|
|
very old ones)
|
|
<item>sndconfig: for soundcards
|
|
<item>printtool: printers, must have X-window running
|
|
<item>pconf-detect: parallel ports
|
|
<item>gpm-mouse-test:detects and tests mice
|
|
<item>mdetect: detects and configures mice
|
|
Does it know about the mice devices in /dev/input/?
|
|
<item>
|
|
<item>nictools-pci (and nictools-nopci) for ethernet cards
|
|
<item>hdparm: configure hard drive hardware
|
|
<item>hotplug: used by kernel
|
|
<item>xvidtune: tune video for use with Xwindows (See
|
|
XFree86-Video-Timings-HOWTO)
|
|
|
|
</itemize>
|
|
|
|
<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> PCI Interrupts <label id="pci_int">
|
|
<sect1>Introduction
|
|
<p>Each PCI device that needs an interrupt comes with a fixed PCI
|
|
interrupt that can't be changed. It's designated by a slot number and
|
|
a letter A, B, C, or D. Example 3:B. But this PCI interrupt is mapped
|
|
(routed or redirected) to an interrupt number like say 21 by a chip on
|
|
the motherboard.
|
|
|
|
This routing is done by a "programmable interrupt router" = PIR.
|
|
Alternatively, an interrupt line may just routed directly (without any
|
|
PIR). If there's a PIR (router) it can be programmed by the BIOS or
|
|
by Linux. Thus a PCI device's interrupt may be sometimes be changed,
|
|
not by sending the interrupt on a different wire but by changing the
|
|
routing of the pulse on that wire by programming the PIR. When the
|
|
routing changes, the interrupt provide by this new routing is written
|
|
in a configuration register located in the device chip.
|
|
|
|
<sect1>History: From ISA to PCI Interrupts
|
|
<p>Before the PCI bus, PCs used the ISA bus and then during the
|
|
transition to the newer PCI bus, most PC computers used both the PCI
|
|
and ISA busses. The ISA bus had all interrupt lines going to every
|
|
card so any card could change its irq number just by sending out its
|
|
interrupt signal on a different line (on a different pin). All the
|
|
interrupt signals were sent to the in interrupt controller which then
|
|
signalled the CPU to temporarily stop whatever it was doing and run
|
|
driver code to service the interrupt.
|
|
|
|
When PCI first appeared, the simple solution was just to map the PCI
|
|
interrupts to available ISA interrupts that weren't being used. This
|
|
required the use of "programmable interrupt router" = PIR (hardware)
|
|
to do this mapping. But since there were only 15 such interrupts, it
|
|
was common to put many PCI devices on just the few available
|
|
interrupts. To solve this problem is simple: provide new hardware to
|
|
increase the number of interrupts. The result was the APIC. But it
|
|
was slow to be adopted since the ability of the PCI bus to share
|
|
interrupts eased the interrupt shortage problem. So APIC was mostly
|
|
used where it was needed for dual processors.
|
|
|
|
<sect1>Advanced Programmable Interrupt Controller (APIC)
|
|
<p>This can provide (depending on the model) 16, 24, 32, or 64
|
|
interrupts, etc. It also can handle the routing of interrupts from
|
|
one CPU to another for cases of multiple CPUs. See the file "IO-APIC"
|
|
in the i386 directory of the kernel documentation and the ACPI-HOWTO.
|
|
Don't confuse APIC with ACPI (Advanced Configuration and Power
|
|
Interface) which may be used by the kernel to configure the APIC.
|
|
|
|
The actual APIC controller that is connected to the interrupt lines is
|
|
an I/O APIC (or IO-APIC or IOAPIC). By using more than one IO-APIC
|
|
one may obtain more interrupts and they are numbered so as to be
|
|
unique. For example, the first controller could have input pins 0-23
|
|
and the second would call its input pins 24-47, resulting in 48
|
|
interrupts numbered 0-47. But a few people find they have high
|
|
interrupt numbers. Could it be that the second IO-APIC is starting
|
|
with a higher base number than it should, leaving a long gap of
|
|
non-existent irqs?
|
|
|
|
Besides IO-APICs there are local APICs (LAPIC) which are part of each
|
|
CPU. The IO-APIC does it work by communicating with the LAPICs
|
|
inside the CPUs.
|
|
|
|
When APIC was introduced, the old ISA PICs were also retained giving
|
|
one a choice of whether or not to use APIC or ISA's PIC (which is
|
|
sometimes just called PIC or XT-PIC in <em>/proc/interrupts</em>; the
|
|
"XT" comes from IBM's XT PC which was IBM's second model PC in 1983).
|
|
It's possible to tell the kernel (on the kernel command line) to not
|
|
use APIC in which case it will use the old XT-PIC if its available.
|
|
But since APIC can have more interrupts than the 15 provided by
|
|
XT-PIC, there could be problems ??
|
|
|
|
To see if you have PIC or APIC look at <em>/proc/interrupts</em>. If
|
|
you see <em/XT-PIC/ for just irq 2 but <em/IO-APIC/ for the others, it
|
|
may mean that you have the old XT-PIC but it isn't being currently
|
|
used. Well, irq 2 is available for communication between two old
|
|
XT-PICs just in case you might need to use them if you were to disable
|
|
APIC. There are two XT-PICs since each only supports 8 interrupts.
|
|
|
|
<sect1> Message Signalled Interrupts (MSI)
|
|
<p>Another 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". It contains an index for the
|
|
address of program that needs to be run to service the IRQ. That
|
|
index, such as 3, would mean for the cpu to find the address it must jump
|
|
to in the 3rd element of a special table that the cpu knows about.
|
|
|
|
Since cards must support MSI and many cards don't, it seems that
|
|
the conventional methods of interrupt hardware support (called INTx)
|
|
will be around for a long time.
|
|
|
|
<sect1>Sharing PCI Interrupts
|
|
<p>PCI interrupts may be shared, meaning that two or more PCI devices
|
|
will generate the same IRQ. If feasible, it's usually better not to
|
|
share. Sharing doesn't work right for: 1. very old PCI hardware
|
|
(before 1995 ??) 2. defective PCI hardware which may have a factory
|
|
defect (it was made that way). For example, if a PCI device on IRQ9
|
|
falsely claims that any IRQ9 was intended for it, then other devices
|
|
using IRQ9 may wind up having all IRQs they issue ignored since the
|
|
bad device is falsely claiming their IRQs. With no sharing, this
|
|
problem is avoided.
|
|
|
|
For an example of sharing the same IRQ between two PCI devices. see
|
|
<ref id="pci_irq_share" name="PCI interrupt sharing"> This sharing
|
|
ability is built into the hardware and all device drivers are supposed
|
|
to support it. Note that you usually can't share the same interrupt
|
|
between the PCI and ISA bus.
|
|
|
|
<sect1>Looking at Routing Tables
|
|
<p>Some info is provided by the boot-time messages which may be viewed
|
|
by typing <em/dmesg/. The following ways of looking at tables involve
|
|
software which you may not have (or doesn't exist yet). To check
|
|
routing where PCI routes to the 16 ISA interrupts use <em/pirtool/
|
|
which shows the $PIR routing table. If you have APIC with hard-wired
|
|
routing (no PIR), use <em/mptable/ to look at the MP table. For
|
|
routeable APIC, a table is accessed by ACPI _PRT methods (but is there
|
|
a command-line command to do this?)
|
|
|
|
<sect1>For More Information
|
|
<p>Detailed technical information about interrupts is at <url
|
|
url="http://people.freebsd.org/~jhb/papers/bsdcan/2007/article/article.html"
|
|
name="PCI Interrupts for x86 Machines under FreeBSD">. Microsoft
|
|
has <url url="http://www.microsoft.com/whdc/system/sysperf/apic.mspx"
|
|
name="The Importance of Implementing APIC-Based Interrupt Subsystems on
|
|
Uniprocessor PCs">
|
|
|
|
<!--
|
|
However, such illegal sharing may work provided that the PCI device is
|
|
in use only one of the two conflicting devices is in use at any given
|
|
time. "In use" here means that a program has "opened" the device (and
|
|
hasn't "closed" it) in its C programming code, even though such a
|
|
program could be temporarily sleeping, etc.
|
|
-->
|
|
|
|
<sect1>PCI Interrupt Linking
|
|
<p>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 these cards. Devices built into the motherboard also have additional interrupts. But the specs permit a
|
|
fewer number of interrupt lines, so some PCI buses seem to be made
|
|
with only 4 or 8 interrupt lines. This is not too restrictive since
|
|
interrupts may be shared. For 4 interrupt line (wires, traces, or links)
|
|
LNKA, LNKB, LNKC, LNKD there is a programmable "interrupt router"
|
|
chip that routes LNKA, LNKB, LNKC, LNKD to selected IRQs. This
|
|
routing can be changed by the BIOS or Linux. For example, LNKA may
|
|
be routed to IRQ5. Suppose we designate the B interrupt from slot 3
|
|
as interrupt 3B. Then interrupts 3B and 2A could both be permanently
|
|
connected to LNKA which is routed to IRQ5. These 2 interrupts: 3B and
|
|
2A are permanently shared by hardwiring on the motherboard.
|
|
|
|
One may type "dmesg" on the command line to see how interrupt lines
|
|
like LNKA are routed (or linked) to IRQs (*5 means that it's linked to
|
|
IRQ 5). Look for "PCI Interrupt Link". Note that "link" is used
|
|
here with two meanings: 1. the linking (routing) of PCI interrupt
|
|
lines to IRQs. 2. the label of an interrupt line such as LNKB (link
|
|
B). The interrupt line labels seem to be provided by the Bios ?? and
|
|
they may have many different names like: LNKC, LNK2, APCF, LUBA, LIDE,
|
|
etc. Question: When a large number of interrupt lines are shown
|
|
disabled, do they all physically exist on the motherboard? Or do they
|
|
just exist only in the ACPI BIOS software so that the BIOS can work
|
|
with motherboards which have more interrupt lines?
|
|
|
|
One simple method of connecting (hard-wiring) these lines from PCI
|
|
devices (such as 3B) to the interrupts LNKA, etc. would be to connect
|
|
all A interrupts (INTA#) to line LNKA, all B's to LNKB, 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 (LNKA connected
|
|
to all the INTA#). To overcome this problem one may connect them in a
|
|
more random way so that each of the 4 interrupt lines (LNKA, LNKB,
|
|
LNKC, LNKD) will share about the same number of actual PCI interrupts.
|
|
|
|
One method of doing this would be to have wire LNKA share interrupts 1A,
|
|
2B, 3C, 4D, 5A, 6B, 7C. This is done by physically connecting wire W
|
|
to wires 1A, 2B, etc. Likewise wire LNKB could be connected to wires 1B,
|
|
2C, 3D, 4A, 5B, 6C, 7D, etc. Then on startup, the BIOS maps the LNKB,
|
|
LNKA, LNKC, LNKD 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 just writing the IRQ in a
|
|
register on a PCI card doesn't in any way set the IRQ for that device.
|
|
|
|
A practical use for this info is that, as a last resort, one may change
|
|
the IRQs of a PCI card by inserting it in a different slot. In the
|
|
above example, INTA# of a PCI card will be connected to wire LNKA if the
|
|
card is inserted into slot 1 (1A maps to LNKA) but INTA# will be
|
|
connected to wire LNKB when it's inserted into slot 4 (4A maps to
|
|
LNKB).
|
|
|
|
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
|
|
shared interrupt. The PCI interrupt letter of a device is often fixed
|
|
and hardwired into the device. The assignment of interrupts is done
|
|
by either the BIOS or Linux mapping the PCI interrupts to the ISA-like
|
|
interrupts as mentioned above.
|
|
|
|
If there are only 4 lines (LNKA, LNKB, LNKC, and LNKD) 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. For
|
|
example LNKA-LNKH (8 lines). The boot-time messages (and dmesg) may
|
|
display them and how they are mapped. The BIOS knows about how they
|
|
are wired.
|
|
|
|
On the PCI bus, the BIOS (or Linux) 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. The assignments are
|
|
known as a "routing table". In MS Windows it's called "IRQ steering"
|
|
but this also covers the case of dynamic IRQ routing after boot-time.
|
|
The BIOS may support it's own IRQ steering.
|
|
|
|
If your PC uses PCI interrupts which are mapped to ISA interrupts, you
|
|
right think that interrupts might be slow since the ISA bus was 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 old ISA address and data buses are slow to get to
|
|
the CPU, the IRQ interrupt signals get there very fast.
|
|
|
|
<sect>PnP for External and Plug-in Devices
|
|
<sect1>USB Bus
|
|
<p>The USB (Universal Serial Bus) is a high speed bus on an external
|
|
cable that plugs into a PC. The external bus cable has its own
|
|
communication protocols and doesn't use any IRQs, I/0 addresses (or
|
|
other bus-resources). Communication is by packets, something like the
|
|
Internet, only there are time-slice allocations which prevent any one
|
|
device from hogging the bus if other devices need it. There are free
|
|
time slots which allow every device to send a short message to the bus
|
|
controller without any need for IRQs on the bus.
|
|
|
|
However, the USB bus controller inside the PC does have an IRQ and an
|
|
address on the PCI bus (or ISA) which are used for communication
|
|
between the CPU and all devices on the USB. Thus there's no resource
|
|
allocations needed for the individual devices on the USB. One could
|
|
also think of this as all devices on the USB sharing the one interrupt
|
|
and address. If a device is on the USB it needs a driver that
|
|
understands the USB.
|
|
|
|
But each device on the USB does have an IDs, just like cards do on the PCI
|
|
bus. So Linux likely maintains a table of these IDs so that device
|
|
drivers can check them to find their device. The USB also support
|
|
"hot plug". To find out what is on the USB bus, you could use a
|
|
general hardware detection tool like "discover" or "hwinfo".
|
|
|
|
<sect1>Hot Plug
|
|
<p>"Hot plug" is where you plug something into a PC (usually via a
|
|
cable connection) and it is instantly detected. If required, it is
|
|
configured with bus-resources. The driver for it is also started,
|
|
perhaps by loading a module for it. For this to work the hardware
|
|
used must be designed for hot plugging. One can hot plug certain PCI
|
|
cards (Cardbus), USB devices, and IEEE 1394 devices (Firewire).
|
|
|
|
When a new device is detected, it's registers are read so as to get
|
|
the ID number of the device. Then to find a driver, Linux must
|
|
maintain a table mapping ID numbers to drivers. It wasn't until
|
|
kernel 2.4 that such a table existed since Linux once shunned
|
|
centralized PnP. It's named: MODULE_DEVICE_TABLE.
|
|
|
|
<sect1>Hot Swap
|
|
<p>"Hot Swap" is where you remove an old device and then plug in a new
|
|
device to replace the old one. You have thus "swapped" devices. Now
|
|
in addition to being able to detect that a new device has been plugged
|
|
in, the removal of the old device needs to be detected too.
|
|
|
|
<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>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.
|
|
|
|
<sect1> isapnp: Write Data Register 0xa79 already used (from logs)
|
|
<p>If you use isa-pnp, the IO address 0xa79 must not ever be used by
|
|
any device. So if other hardware is using 0xa79 when you try to load
|
|
the isa-pnp module, you'll get this message in your logs and the
|
|
isa-pnp will exit. One way to try to fix this is to load the isa-pnp
|
|
module early before other hardware is initialized. For PCMCIA this
|
|
means to load isa-pnp before running cb modules and service.
|
|
|
|
<sect1>Can't allocate region (PCI)
|
|
<p>Here "region" means address range. A PCI device that needs two
|
|
addresses will have region 0 for the first address and region 1 for the
|
|
second address needed. Use the command: lspci -vv to see the various
|
|
resource regions (often just called regions) and whether the address
|
|
is of type IO or memory. In PCI jargon region 2 is "base address 2"
|
|
(or "base address register 2"), etc.
|
|
|
|
<sect>Interrupt Sharing and Interrupt Conflicts
|
|
<sect1>Introduction
|
|
<p>When two or more devices use the same interrupt line (and the same
|
|
IRQ number) it's either "Interrupt Sharing" or an "Interrupt
|
|
Conflict". The PCI bus allows all PCI devices to share interrupts
|
|
with each other so this is called "sharing". But if an ISA device (or
|
|
a LPC device ??) uses the same interrupt (IRQ) as some other device
|
|
(either PCI, ISA, or LPC ??) there is usually an interrupt conflict.
|
|
|
|
There are exceptions to what's stated above. Some very old PCI
|
|
devices (pre 1995 ??) do not allow interrupt sharing. Conversely, a
|
|
few ISA devices have been designed to share interrupts (between two
|
|
ISA devices ??) but both ISA devices must be designed this way and be
|
|
driven by software that knows about sharing interrupts. The
|
|
motherboard must support it too. The following discussion pertains to
|
|
PCs that have an ISA bus.
|
|
|
|
A conflict means that when an interrupt happens, no device driver (or
|
|
the wrong one) may be called and bad things happen like buffer
|
|
overruns (loss of data). A device may nearly ground its interrupt
|
|
line when it's not sending its interrupt, thus preventing any other
|
|
device from using that interrupt wire. That's OK if only that device
|
|
uses that interrupt. But if a second device tries to use the same
|
|
interrupt line it can't do so. If this second device also nearly
|
|
grounds the line when not sending an interrupt, then neither device
|
|
can use the interrupt. But both Linux and the two devices are unaware
|
|
of this conflict and merrily send out interrupts anyway that mostly go
|
|
nowhere and are thus lost.
|
|
|
|
Interrupt conflicts were common when the IRQs were set by jumpers on
|
|
cards (ISA bus) because the kernel often didn't know how these jumpers
|
|
were set. ISA plug-and-play (no jumpers on the cards) helped since
|
|
the software could change IRQs. The demise of ISA in favor of PCI has
|
|
nearly eliminated IRQ conflicts. Still, your PC likely has devices on
|
|
the motherboard (not on a plug-in card) on an ISA bus, a LPC bus, or
|
|
an X-bus. But the BIOS and the kernel should know how these are set
|
|
and thus avoid using them for PCI devices, thereby avoiding interrupt
|
|
conflicts. But there is still a possible interrupt problem with PCI
|
|
since it could run out of available interrupts, especially on older
|
|
PCs that only have 16 interrupts.
|
|
|
|
But IRQ sharing on the PCI bus, while eliminating the conflict
|
|
problem, has introduced another problem which is less serious: the IRQ
|
|
balancing problem. If too many high-irq-issuing devices share the
|
|
same IRQ, it may cause delays in the IRQs getting serviced and can't
|
|
even result in buffer overruns and other errors. This is not due to
|
|
congestion on the interrupt line, but it's due to the way that the
|
|
software determines which device issued the interrupt. <ref
|
|
id="pci_irq_share" name="PCI interrupt sharing">
|
|
|
|
There are two types of interrupt conflicts. One is a real conflict
|
|
as described above. In this case interrupts don't work and the device
|
|
driver keeps trying to control its device and is not aware that
|
|
interrupts are not working. The second type of interrupt conflict is
|
|
where a device driver is started but discovers that the interrupt it
|
|
needs is already in use so it issues an error message and exits. The
|
|
message could say something like "resource busy", and not clearly
|
|
state that it was an interrupt problem.
|
|
|
|
<sect1>Real Interrupt Conflict
|
|
<p>Both the BIOS and the kernel will not knowingly allow any
|
|
interrupt conflict, so how can they happen? One way is if someone
|
|
has put an incorrect IRQ into a configuration file, such as giving a
|
|
parameter to a module like: irq=9. In this example, suppose the irq
|
|
of the device is really irq5. Then when another device driver starts
|
|
up where its device is set to irq5, you have two real devices using
|
|
irq5 and a real conflict. The kernel approved of letting the second
|
|
device use irq5 since it erroneously thought that the first device was
|
|
using irq9 and that irq5 was free.
|
|
|
|
There are other cases like this where the kernel fails to know that an
|
|
irq is in use. One is when an old ISA card with an irq set by a
|
|
jumper is present, but it's driver hasn't started yet (or it may not
|
|
even have a driver). Another case is where the BIOS set an irq in the
|
|
hardware but no linux driver for that hardware ever started and Linux
|
|
doesn't know about that irq. This can happen even for a PCI card and
|
|
the irq will show up in <em/lspci -v/ but will not be in the
|
|
<em>/proc/interrupts</em> directory and thus not known by the kernel.
|
|
Is this a bug in the kernel?
|
|
|
|
What are the symptoms of an interrupt conflict. One might think that
|
|
the devices will not work at all, but since the addresses are known,
|
|
the driver does communicate. Interrupts are often used to control the
|
|
flow of data to and from the device and without interrupts, flow is not
|
|
controlled. This may mean buffer overruns or even no flow at all
|
|
since interrupt are used to initiate flow. For a serial modem, the
|
|
result is extremely slow flow with long pauses and frequent errors.
|
|
For a sound card it may mean that a word or two is heard and then
|
|
nothing more.
|
|
|
|
<sect1>No Interrupt Available
|
|
<p>This is when a device driver starts but immediately exits
|
|
in order to avoid an interrupt conflict. It should display or log an
|
|
error message something like "resource busy".
|
|
|
|
One case when an ISA device is activated but can't be assigned an
|
|
interrupt (IRQ) since none are available. Or an interrupt may be
|
|
available, but it can't be used since the hardware of the device that
|
|
needs the interrupt doesn't support the interrupt number available (or
|
|
the motherboard doesn't support it due to "routing" problems, see <ref
|
|
id="pci_int" name="PCI Interrupts">). If the ISA devices use up all
|
|
the interrupts, then one or more PCI cards may be in conflict since
|
|
they can't get any IRQs.
|
|
|
|
Normally, the BIOS will assign interrupts and will not create
|
|
conflicts. But it may be forced to create conflicts if it runs out of
|
|
IRQs. This can happen if someone has set up the BIOS to reserve certain
|
|
IRQs for legacy ISA devices that are not PnP. These settings may be
|
|
wrong and should be checked out, especially if you're having problems.
|
|
For example, someone may have reserved an IRQ for an ISA card that has
|
|
long since been removed from the PC. If you unreserved this IRQ then
|
|
this IRQ is available and the conflict disappears.
|
|
|
|
Sometimes the BIOS will solve the problem of an IRQ shortage by using
|
|
what it calls IRQ 0. There is no such IRQ available since the real
|
|
IRQ 0 is permanently assigned to the computer's timer. But IRQ 0
|
|
here means that the driver should use polling instead of IRQs. This
|
|
means that the driver frequently checks the device (polls it) to see
|
|
if the device needs servicing by the interrupt service routine. Of
|
|
course, this wastes computer time and there's more likelihood of a
|
|
buffer overrun inside a device since it might not get serviced by the
|
|
driver promptly enough.
|
|
|
|
|
|
<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"> A
|
|
UPnP project for Linux is at SourceForge: <url
|
|
url="http://sourceforge.net/projects/upnp/" name="UPnP SDK for Linux">
|
|
|
|
<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. Addresses are in units of bytes, So
|
|
for example, a serial port at I/O address range 3F8-3FF will often
|
|
just be referred to by its base address, 3F8. The 3F8 is the location
|
|
of the first byte in the range (address range). To see the address
|
|
ranges for various devices, look at /proc/iomem and /proc/ioports.
|
|
|
|
<sect2> Address space
|
|
<p>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, for ISA (for PCI
|
|
read this too), there are 4 dedicated wires on the bus that convey this
|
|
sort of information. 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. In all, 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 by these 4 wires..
|
|
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. This leaves 10 more numbers
|
|
left over for other purposes.
|
|
|
|
<sect2>PCI Configuration Address Space <label id="pci_conf">
|
|
<p>This is different from the IO and memory address spaces because
|
|
configuration address space is "geographic". Each slot for a card has
|
|
the slot number as part of the address. This way, Linux (or the BIOS)
|
|
can address a certain slot and find out what type of card is in that
|
|
slot. Each device has 64 standard byte-size registers and some of
|
|
these hold numbers which can unambiguously identify the device. Since
|
|
the number of slots is limited as are the number of PCI devices built
|
|
into motherboard, Linux (or the BIOS) only needs to check a limited
|
|
number of addresses to find all the PCI devices. If it reads all ones
|
|
(0xFF in hexadecimal) from the first register of a device, then that
|
|
means that no device is present. Since there is no card or device to
|
|
supply all these ones (0xFF) number, the PCI "host bridge" on the
|
|
motherboard supplies (spoofs) this number for all non-existent device.
|
|
|
|
The PCI slot number is called (in PCI lingo) the "Device Number" and
|
|
since a card may have up to 8 devices on it, a "Function Number" from
|
|
0-7 identifies which device it is on a PCI card. These numbers are
|
|
part of the geographic address. Linux programmers call it
|
|
"pci-slot-name". Thus what Linux calls a "device" is actually a
|
|
"function" in PCI lingo. The PCI bus number (often 00) also becomes
|
|
part of the geographic address. For example, 0000:00:0d.2 is PCI bus
|
|
0, slot 0d, function 2. For the full geographic address, one must
|
|
include the double-word number of the device's configuration
|
|
registers which one wants to access. The leading 0000 (in 1999) were
|
|
reserved for future use.
|
|
|
|
How does the CPU designate that a read or write is to a PCI
|
|
configuration space? It doesn't, at least not directly. Instead when
|
|
access to configuration space is desired it does a 32-bit
|
|
(double-word) write to 0cf8-0cfb in IO space and writes the full
|
|
geographic address there. The PCI host bridge is listening at this
|
|
address and insures that any next write of data to 0cfc-0cff is put into the
|
|
specified configuration registers of the specified device. The bridge
|
|
does this both by sending a special signal to the specified PCI card
|
|
(or the like) on a dedicated wire that goes only to the slot where the
|
|
card is plugged in. It also puts bits on the control bus saying that
|
|
what's on the address bus now is a geographic configuration space
|
|
address.
|
|
|
|
Why not make it simple and just have the CPU put bits on the control
|
|
bus to say that the address on the main bus is a geographic one for
|
|
PCI configuration? Well, most CPU's are not capable of doing this so
|
|
the PCI host bridge gets to do it instead.
|
|
|
|
<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 what it
|
|
reads is the same as the known 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.
|
|
|
|
<sect2> Communicating Directly via Memory
|
|
<p> Traditionally, most I/O devices used only I/O memory to
|
|
communicate with the CPU. The device driver, running on the CPU would
|
|
read and write data to/from the I/O address space and main memory.
|
|
Unfortunately, this requires two steps. For example, 1. read data from
|
|
a device (in IO address space) and temporarily store in the CPU; 2.
|
|
write this data to 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 ISA <ref id="dma_" name="DMA Channels"> or PCI bus
|
|
mastering. Another way is for the physical device to actually contain
|
|
some main memory (at high addresses so as not to conflict with main
|
|
memory chip addresses). This way the device reads and writes directly
|
|
to it's self-contained 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">
|
|
|
|
<sect2>Serialized Interrupts
|
|
<p>It was previously stated that there was a wire for each interrupt.
|
|
But the serialized interrupt (or serial interrupt) is an exception. A
|
|
single wire is used for all interrupt which are multiplexed on that
|
|
wire. Each interrupt has a time slot on the interrupt line. It's
|
|
used on the LPC bus and is also for the PCI bus, but it's seldom used
|
|
for PCI ??
|
|
|
|
<sect2>DMA
|
|
<p> Before going into interrupt details, there is another way for some
|
|
devices to initiate communication besides sending out an interrupt.
|
|
This method is a DMA (Direct Memory Access) request to take control of
|
|
the computer from the CPU for a limited amount of time. On the PCI
|
|
bus, it uses no "resources". Not all devices are capable of doing
|
|
DMA. See <ref id="dma_" name="DMA Channels">.
|
|
|
|
<sect2>Soft interrupts
|
|
<p>There's also another type of interrupt known as a "soft interrupt"
|
|
which is not covered in this HOWTO and doesn't use any "resources".
|
|
While a hardware interrupt is generated by hardware, a soft interrupt
|
|
is initiated by software. There are a couple of ways to do this. One
|
|
way is for software to tell the CPU to issue an interrupt (an
|
|
interrupt instruction). Another way is for the software to send
|
|
messages to other processes so as to interrupt them although it's not
|
|
clear that this should be called an interrupt. The ksoftirq process,
|
|
which you may find running on a Linux PC, is a program which does this
|
|
kind of interrupt for dealing with device drivers. The device driver
|
|
starts running due to a hardware interrupt but later on, software
|
|
interrupts are used for the "bottom half" of the driver's interrupt
|
|
service routine. Thus, the ksoftirq process is also known as
|
|
"bottom-half". For more details see the kernel documentation.
|
|
|
|
<sect2>Hardware interrupts
|
|
<p>Interrupts convey a lot of information but only indirectly. The
|
|
interrupt request signal (a voltage on a wire) sent by a device 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 code 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 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.
|
|
|
|
<label id="pci_irq_share">
|
|
Thus each device driver needs to know what interrupt number (IRQ) to
|
|
listen for. 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.
|
|
Note that you can't share a PCI interrupt with an ISA interrupt (are
|
|
there any exceptions ??). When a shared interrupt is issued, the CPU
|
|
runs all interrupt service routines sequentially for all devices using
|
|
that interrupt. The first thing such a service routine does is to
|
|
check its device's 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) then it likely will immediately exit and the next service
|
|
routine begins for the second device which uses that same interrupt.
|
|
It checks out the device like described above. This sequence is
|
|
repeated until the device is found that actually issued the interrupt.
|
|
All the interrupt routines for an interrupt are said to be
|
|
constitute a chain. So the chain is traversed until a routine on the
|
|
chain claims the interrupt by saying in effect: this interrupt was for
|
|
me. After it handles the interrupt, the interrupt service routines
|
|
further out on the chain don't run.
|
|
|
|
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 of the CPU 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>How the Device Driver Catches its Interrupt
|
|
<p>The previous statement, that device drivers listen for their
|
|
interrupt, was an oversimplification. Actually it's a chip (or part
|
|
of a chip) on the motherboard called the "interrupt controller" that
|
|
listens for all interrupts. When the interrupt controller catches an
|
|
interrupt, it sends a signal to the CPU to start the appropriate
|
|
device driver's "interrupt service routine" to handle the interrupt.
|
|
|
|
There are various types of interrupt controllers. One type is the
|
|
APIC = Advanced Programmable Interrupt Controller which usually has
|
|
input pins for many interrupts, including PCI interrupts. Older
|
|
controllers only have pins for ISA interrupts but they can still
|
|
handle PCI interrupts since there is a "programmable interrupt router"
|
|
that converts PCI interrupts to ISA interrupts and routes them to
|
|
certain pins (= certain IRQs) on the ISA interrupt controller.
|
|
|
|
<sect1> ISA Isolation <label id="isolation_">
|
|
<p> This is only for the old 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.
|
|
|
|
<sect1>Bus Mastering and DMA resources
|
|
<p>If a bus has bus mastering available, it's unlikely that any
|
|
resources will be needed for DMA on that bus. For example, the PCI bus
|
|
doesn't need DMA resources since it has "bus mastering". However, "bus
|
|
mastering" is often called DMA. But since it's not strictly DMA it
|
|
needs no DMA resources. The ISA and VESA local bus had no bus
|
|
mastering. The old MCA and EISA buses did have bus mastering.
|
|
|
|
<sect1>Historical and Obsolete
|
|
<sect2>OSS-Lite Sound Driver
|
|
<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 sound cards and automatically sets up the modules for
|
|
loading with the detected bus-resources.
|
|
|
|
<sect2> ALSA (Advanced Linux Sound Architecture) as of 2000
|
|
<p> This 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 cards or PCI cards. OSS (Open Sound System) was formerly
|
|
popular.
|
|
|
|
<sect2>MS Windows Notes <p>Windows NT4 didn't support ISAPNP but had a
|
|
PNPISA program which one could "use at your own risk". For NT4 users
|
|
were advised to set "not a PnP OS" in the BIOS so that the BIOS would
|
|
do the resource configuring. Thus both MS Windows and Linux were in
|
|
olden days dependent on the BIOS doing the configuring (and still are).
|
|
|
|
END OF Plug-and-Play-HOWTO
|
|
</article>
|
|
|