708 lines
41 KiB
HTML
708 lines
41 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.21">
|
|
<TITLE> Plug-and-Play-HOWTO: What PnP Should Do: Allocate "Bus-Resources"</TITLE>
|
|
<LINK HREF="Plug-and-Play-HOWTO-3.html" REL=next>
|
|
<LINK HREF="Plug-and-Play-HOWTO-1.html" REL=previous>
|
|
<LINK HREF="Plug-and-Play-HOWTO.html#toc2" REL=contents>
|
|
</HEAD>
|
|
<BODY>
|
|
<A HREF="Plug-and-Play-HOWTO-3.html">Next</A>
|
|
<A HREF="Plug-and-Play-HOWTO-1.html">Previous</A>
|
|
<A HREF="Plug-and-Play-HOWTO.html#toc2">Contents</A>
|
|
<HR>
|
|
<H2><A NAME="s2">2.</A> <A HREF="Plug-and-Play-HOWTO.html#toc2">What PnP Should Do: Allocate "Bus-Resources"</A></H2>
|
|
|
|
<H2><A NAME="ss2.1">2.1</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.1">What is Plug-and-Play (PnP)?</A>
|
|
</H2>
|
|
|
|
<P> If you don't understand this section, read the next section
|
|
<A HREF="#dev_commun">Hardware Devices and Communication with them</A></P>
|
|
|
|
<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
|
|
<A HREF="http://www.linuxgazette.com/issue38/blanchard.html">Introduction to IRQs, DMAs and Base Addresses</A>. 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.</P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
|
|
<H2><A NAME="dev_commun"></A> <A NAME="ss2.2">2.2</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.2">Hardware Devices and Communication with them</A>
|
|
</H2>
|
|
|
|
<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.</P>
|
|
<P>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.</P>
|
|
<P>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. </P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
|
|
<H2><A NAME="ss2.3">2.3</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.3">Addresses</A>
|
|
</H2>
|
|
|
|
<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
|
|
<A HREF="Plug-and-Play-HOWTO-11.html#pci_conf">PCI Configuration Address Space</A></P>
|
|
<P>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
|
|
<A HREF="#mem_">Memory Ranges</A>),
|
|
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
|
|
<A HREF="Plug-and-Play-HOWTO-11.html#pci_conf">PCI Configuration Address Space</A> for details. See
|
|
<A HREF="Plug-and-Play-HOWTO-11.html#address_details">Address Details</A> for more details on
|
|
addressing in general.</P>
|
|
<P>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.</P>
|
|
|
|
<H2><A NAME="ss2.4">2.4</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.4">I/O Addresses (principles relevant to other resources too) </A>
|
|
</H2>
|
|
|
|
<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):</P>
|
|
<P>
|
|
<OL>
|
|
<LI> Set the I/O address, etc. in the hardware (in one of its registers)</LI>
|
|
<LI> Let its device driver know what this I/O address, etc. is</LI>
|
|
</OL>
|
|
</P>
|
|
<P>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. </P>
|
|
<P>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.</P>
|
|
<P>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).</P>
|
|
<P>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).</P>
|
|
<P>What was said in the last few paragraphs regarding I/O addresses applies
|
|
with equal force to most other bus-resources:
|
|
<A HREF="#mem_">Memory Ranges</A>,
|
|
<A HREF="#interrupt_over">IRQs --Overview</A> and
|
|
<A HREF="#dma_">DMA Channels</A>. 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.</P>
|
|
<P>To see what IO addresses are used on your PC, look at the /proc/ioports
|
|
file.</P>
|
|
|
|
<H2><A NAME="mem_"></A> <A NAME="ss2.5">2.5</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.5">Memory Ranges </A>
|
|
</H2>
|
|
|
|
<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".</P>
|
|
<P>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.</P>
|
|
<P>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".</P>
|
|
|
|
<H2><A NAME="interrupt_over"></A> <A NAME="ss2.6">2.6</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.6">IRQs --Overview </A>
|
|
</H2>
|
|
|
|
<P> After reading this you may want to read
|
|
<A HREF="Plug-and-Play-HOWTO-11.html#interrupt_detail">Interrupts --Details</A> 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. </P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
<P>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
|
|
<A HREF="Plug-and-Play-HOWTO-11.html#interrupt_detail">Interrupts --Details</A> for details on how all the above works.</P>
|
|
|
|
<H2><A NAME="dma_"></A> <A NAME="ss2.7">2.7</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.7">DMA (Direct Memory Access) or Bus Mastering </A>
|
|
</H2>
|
|
|
|
<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:
|
|
<OL>
|
|
<LI>reading a chunk of bytes from the I/O memory
|
|
space of the device and putting these bytes into CPU itself </LI>
|
|
<LI>writing these bytes from the CPU to main memory </LI>
|
|
</OL>
|
|
</P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
|
|
<H2><A NAME="dma_isa"></A> <A NAME="ss2.8">2.8</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.8">DMA Channels (not for PCI bus) </A>
|
|
</H2>
|
|
|
|
<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.</P>
|
|
|
|
<H2><A NAME="ss2.9">2.9</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.9">"Resources" for both Device and Driver </A>
|
|
</H2>
|
|
|
|
<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.</P>
|
|
<P>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.</P>
|
|
|
|
<H2><A NAME="ss2.10">2.10</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.10">Resources are Limited</A>
|
|
</H2>
|
|
|
|
<H3>Ideal Computers</H3>
|
|
|
|
<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.</P>
|
|
<P>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.</P>
|
|
|
|
<H3>Real Computers</H3>
|
|
|
|
<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.</P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
|
|
<H2><A NAME="ss2.11">2.11</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.11">Second Introduction to PnP</A>
|
|
</H2>
|
|
|
|
<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.</P>
|
|
<P>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).</P>
|
|
<P>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.</P>
|
|
|
|
<H2><A NAME="ss2.12">2.12</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.12">How Pnp Works (simplified)</A>
|
|
</H2>
|
|
|
|
<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.</P>
|
|
<P>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. </P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
<P>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
|
|
<A HREF="Plug-and-Play-HOWTO-4.html#escd_">The BIOS's ESCD Database</A>). 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.</P>
|
|
<P>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.</P>
|
|
<P>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).</P>
|
|
|
|
<H2><A NAME="ss2.13">2.13</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.13">Starting Up the PC</A>
|
|
</H2>
|
|
|
|
<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.</P>
|
|
<P>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. </P>
|
|
|
|
<H2><A NAME="ss2.14">2.14</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.14">Buses</A>
|
|
</H2>
|
|
|
|
<P>To see what's on the PCI bus type <CODE>lspci</CODE> or <CODE>lspci -vv</CODE>.
|
|
Or type <CODE>scanpci -v</CODE> 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, <CODE>scanpci</CODE> will find a
|
|
device that <CODE>lspci</CODE> can't find. </P>
|
|
<P>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
|
|
<A HREF="Plug-and-Play-HOWTO-6.html#boot_time_msgs">Boot-time Messages</A></P>
|
|
<P>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.</P>
|
|
<P>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
|
|
<A HREF="Plug-and-Play-HOWTO-4.html#pnp_book">PnP Book</A>. 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
|
|
<A HREF="Plug-and-Play-HOWTO-11.html#isolation_">ISA Isolation</A> for the complex details.</P>
|
|
<P>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.</P>
|
|
|
|
<H2><A NAME="how_linux_pnps"></A> <A NAME="ss2.15">2.15</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.15">How Linux Does PnP </A>
|
|
</H2>
|
|
|
|
<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.</P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
<P>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. </P>
|
|
<P>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.</P>
|
|
<P>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. </P>
|
|
<P>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".</P>
|
|
<P>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.</P>
|
|
<P>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.</P>
|
|
|
|
<H2><A NAME="ss2.16">2.16</A> <A HREF="Plug-and-Play-HOWTO.html#toc2.16">Problems with Linux PnP</A>
|
|
</H2>
|
|
|
|
<P>But there are a number
|
|
of things that a real PnP operating system could handle better:</P>
|
|
<P>
|
|
<UL>
|
|
<LI>Allocate bus-resources when they are in short supply by
|
|
reallocation of resources if necessary</LI>
|
|
<LI>Deal with choosing a driver when there is more than one driver
|
|
for a physical device</LI>
|
|
</UL>
|
|
</P>
|
|
<P>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.</P>
|
|
<P>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).</P>
|
|
<P>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).</P>
|
|
<P>There was at least one early attempt to make Linux a truly PnP
|
|
operating system. See
|
|
<A HREF="http://www.astarte.free-online.co.uk">http://www.astarte.free-online.co.uk</A>. While developed around
|
|
1998 it never was put into the kernel (but probably should have been).</P>
|
|
|
|
<HR>
|
|
<A HREF="Plug-and-Play-HOWTO-3.html">Next</A>
|
|
<A HREF="Plug-and-Play-HOWTO-1.html">Previous</A>
|
|
<A HREF="Plug-and-Play-HOWTO.html#toc2">Contents</A>
|
|
</BODY>
|
|
</HTML>
|