]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - doc/html/ref/ecos-pci-library.html
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / doc / html / ref / ecos-pci-library.html
1 <!-- Copyright (C) 2003 Red Hat, Inc.                                -->
2 <!-- This material may be distributed only subject to the terms      -->
3 <!-- and conditions set forth in the Open Publication License, v1.0  -->
4 <!-- or later (the latest version is presently available at          -->
5 <!-- http://www.opencontent.org/openpub/).                           -->
6 <!-- Distribution of the work or derivative of the work in any       -->
7 <!-- standard (paper) book form is prohibited unless prior           -->
8 <!-- permission is obtained from the copyright holder.               -->
9 <HTML
10 ><HEAD
11 ><TITLE
12 >The eCos PCI Library</TITLE
13 ><meta name="MSSmartTagsPreventParsing" content="TRUE">
14 <META
15 NAME="GENERATOR"
16 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
17 "><LINK
18 REL="HOME"
19 TITLE="eCos Reference Manual"
20 HREF="ecos-ref.html"><LINK
21 REL="UP"
22 TITLE="PCI Library"
23 HREF="io-pci.html"><LINK
24 REL="PREVIOUS"
25 TITLE="PCI Library"
26 HREF="io-pci.html"><LINK
27 REL="NEXT"
28 TITLE="PCI Library reference"
29 HREF="pci-library-reference.html"></HEAD
30 ><BODY
31 CLASS="CHAPTER"
32 BGCOLOR="#FFFFFF"
33 TEXT="#000000"
34 LINK="#0000FF"
35 VLINK="#840084"
36 ALINK="#0000FF"
37 ><DIV
38 CLASS="NAVHEADER"
39 ><TABLE
40 SUMMARY="Header navigation table"
41 WIDTH="100%"
42 BORDER="0"
43 CELLPADDING="0"
44 CELLSPACING="0"
45 ><TR
46 ><TH
47 COLSPAN="3"
48 ALIGN="center"
49 >eCos Reference Manual</TH
50 ></TR
51 ><TR
52 ><TD
53 WIDTH="10%"
54 ALIGN="left"
55 VALIGN="bottom"
56 ><A
57 HREF="io-pci.html"
58 ACCESSKEY="P"
59 >Prev</A
60 ></TD
61 ><TD
62 WIDTH="80%"
63 ALIGN="center"
64 VALIGN="bottom"
65 ></TD
66 ><TD
67 WIDTH="10%"
68 ALIGN="right"
69 VALIGN="bottom"
70 ><A
71 HREF="pci-library-reference.html"
72 ACCESSKEY="N"
73 >Next</A
74 ></TD
75 ></TR
76 ></TABLE
77 ><HR
78 ALIGN="LEFT"
79 WIDTH="100%"></DIV
80 ><DIV
81 CLASS="CHAPTER"
82 ><H1
83 ><A
84 NAME="ECOS-PCI-LIBRARY">Chapter 30. The eCos PCI Library</H1
85 ><DIV
86 CLASS="TOC"
87 ><DL
88 ><DT
89 ><B
90 >Table of Contents</B
91 ></DT
92 ><DT
93 ><A
94 HREF="ecos-pci-library.html#PCI-LIBRARY"
95 >PCI Library</A
96 ></DT
97 ><DT
98 ><A
99 HREF="pci-library-reference.html"
100 >PCI Library reference</A
101 ></DT
102 ></DL
103 ></DIV
104 ><P
105 >The PCI library is an optional part of eCos, and is only
106         applicable to some platforms.</P
107 ><DIV
108 CLASS="SECT1"
109 ><H1
110 CLASS="SECT1"
111 ><A
112 NAME="PCI-LIBRARY">PCI Library</H1
113 ><P
114 >The eCos PCI library provides the following functionality:</P
115 ><P
116 ></P
117 ><OL
118 TYPE="1"
119 ><LI
120 ><P
121 >Scan the PCI bus for specific devices or devices of a certain
122 class.</P
123 ></LI
124 ><LI
125 ><P
126 >Read and change generic PCI information.</P
127 ></LI
128 ><LI
129 ><P
130 >Read and change device-specific PCI information.</P
131 ></LI
132 ><LI
133 ><P
134 >Allocate PCI memory and IO space to devices.</P
135 ></LI
136 ><LI
137 ><P
138 >Translate a device's PCI interrupts to equivalent HAL
139 vectors.</P
140 ></LI
141 ></OL
142 ><P
143 >Example code fragments are from the pci1 test (see <TT
144 CLASS="FILENAME"
145 >io/pci/&lt;release&gt;/tests/pci1.c</TT
146 >).</P
147 ><P
148 >All of the functions described below are declared in the header
149 file <TT
150 CLASS="FILENAME"
151 >&lt;cyg/io/pci.h&gt;</TT
152 > which all
153 clients of the PCI library should include.</P
154 ><DIV
155 CLASS="SECT2"
156 ><H2
157 CLASS="SECT2"
158 ><A
159 NAME="AEN12691">PCI Overview</H2
160 ><P
161 >The PCI bus supports several address spaces: memory, IO, and configuration. All PCI
162 devices must support mandatory configuration space registers. Some devices may also present
163 IO mapped and/or memory mapped resources. Before devices on the bus can be used, they must
164 be configured. Basically, configuration will assign PCI IO and/or memory address ranges to
165 each device and then enable that device. All PCI devices have a unique address in
166 configuration space. This address is comprised of a bus number, a device number, and a
167 function number. Special devices called bridges are used to connect two PCI busses together.
168 The PCI standard supports up to 255 busses with each bus having up to 32 devices and each
169 device having up to 8 functions.</P
170 ><P
171 >The environment in which a platform operates will dictate if and how eCos should
172 configure devices on the PCI bus. If the platform acts as a host on a single PCI bus,
173 then devices may be configured individually from the relevant device driver. If the
174 platform is not the primary host, such as a PCI card plugged into a PC, configuration
175 of PCI devices may be left to the PC BIOS. If PCI-PCI bridges are involved, configuration
176 of all devices is best done all at once early in the boot process. This is because all
177 devices on the secondary side of a bridge must be evaluated for their IO and memory space
178 requirements before the bridge can be configured.</P
179 ></DIV
180 ><DIV
181 CLASS="SECT2"
182 ><H2
183 CLASS="SECT2"
184 ><A
185 NAME="AEN12695">Initializing the bus</H2
186 ><P
187 >The PCI bus needs to be initialized before it can be used.
188 This only needs to be done once - some HALs may do it as part of
189 the platform initialization procedure, other HALs may leave it to
190 the application or device drivers to do it. The following function
191 will do the initialization only once, so it's safe to call from
192 multiple drivers:</P
193 ><TABLE
194 BORDER="5"
195 BGCOLOR="#E0E0F0"
196 WIDTH="70%"
197 ><TR
198 ><TD
199 ><PRE
200 CLASS="PROGRAMLISTING"
201 >void cyg_pci_init( void );</PRE
202 ></TD
203 ></TR
204 ></TABLE
205 ></DIV
206 ><DIV
207 CLASS="SECT2"
208 ><H2
209 CLASS="SECT2"
210 ><A
211 NAME="AEN12699">Scanning for devices</H2
212 ><P
213 >After the bus has been initialized, it is possible to scan
214 it for devices. This is done using the function:</P
215 ><TABLE
216 BORDER="5"
217 BGCOLOR="#E0E0F0"
218 WIDTH="70%"
219 ><TR
220 ><TD
221 ><PRE
222 CLASS="PROGRAMLISTING"
223 >cyg_bool cyg_pci_find_next(  cyg_pci_device_id cur_devid, 
224                              cyg_pci_device_id *next_devid );</PRE
225 ></TD
226 ></TR
227 ></TABLE
228 ><P
229 >It will scan the bus for devices starting at <TT
230 CLASS="PARAMETER"
231 ><I
232 >cur_devid</I
233 ></TT
234 >. If a device is found, its devid is stored in <TT
235 CLASS="PARAMETER"
236 ><I
237 >next_devid</I
238 ></TT
239 > and the function returns <TT
240 CLASS="CONSTANT"
241 >true</TT
242 >.</P
243 ><P
244 >The <TT
245 CLASS="FILENAME"
246 >pci1</TT
247 > test's outer loop looks like:</P
248 ><TABLE
249 BORDER="5"
250 BGCOLOR="#E0E0F0"
251 WIDTH="70%"
252 ><TR
253 ><TD
254 ><PRE
255 CLASS="PROGRAMLISTING"
256 >    cyg_pci_init();
257     if (cyg_pci_find_next(CYG_PCI_NULL_DEVID, &amp;devid)) {
258         do {
259              &lt;use devid&gt;
260         } while (cyg_pci_find_next(devid, &amp;devid));
261     }</PRE
262 ></TD
263 ></TR
264 ></TABLE
265 ><P
266 >What happens is that the bus gets initialized and a scan is
267 started. <TT
268 CLASS="LITERAL"
269 >CYG_PCI_NULL_DEVID</TT
270 > causes <TT
271 CLASS="FUNCTION"
272 >cyg_pci_find_next()</TT
273 > to restart its scan. If the bus does not
274 contain any devices, the first call to <TT
275 CLASS="FUNCTION"
276 >cyg_pci_find_next()</TT
277 >
278 will return <TT
279 CLASS="CONSTANT"
280 >false</TT
281 >.</P
282 ><P
283 >If the call returns <TT
284 CLASS="CONSTANT"
285 >true</TT
286 >, a loop is entered where
287 the found devid is used. After devid processing has completed, the next device
288 on the bus is searched for; <TT
289 CLASS="FUNCTION"
290 >cyg_pci_find_next()</TT
291 >
292 continues its scan from the current devid. The loop terminates when
293 no more devices are found on the bus.</P
294 ><P
295 >This is the generic way of scanning the bus, enumerating all
296 the devices on the bus. But if the application is looking for a
297 device of a given device class (e.g., a SCSI controller), or a specific
298 vendor device, these functions simplify the task a bit:</P
299 ><TABLE
300 BORDER="5"
301 BGCOLOR="#E0E0F0"
302 WIDTH="70%"
303 ><TR
304 ><TD
305 ><PRE
306 CLASS="PROGRAMLISTING"
307 >cyg_bool cyg_pci_find_class(  cyg_uint32 dev_class,
308                               cyg_pci_device_id *devid );
309 cyg_bool cyg_pci_find_device(  cyg_uint16 vendor, cyg_uint16 device,
310                                cyg_pci_device_id *devid );</PRE
311 ></TD
312 ></TR
313 ></TABLE
314 ><P
315 >They work just like <TT
316 CLASS="FUNCTION"
317 >cyg_pci_find_next()</TT
318 >,
319 but only return true when the dev_class or vendor/device
320 qualifiers match those of a device on the bus. The devid serves
321 as both an input and an output operand: the scan starts at the given
322 device, and if a device is found devid is updated with the value
323 for the found device.</P
324 ><P
325 >The <TT
326 CLASS="FILENAME"
327 >&lt;cyg/io/pci_cfg.h&gt;</TT
328 > header
329 file (included by <TT
330 CLASS="FILENAME"
331 >pci.h</TT
332 >) contains definitions for PCI 
333 class, vendor and device codes which can be used as arguments to the find
334 functions.
335 The list of vendor and device codes is not complete: add new codes
336 as necessary. If possible also register the codes at the PCI Code
337 List (<A
338 HREF="http://www.yourvote.com/pci"
339 TARGET="_top"
340 >http://www.yourvote.com/pci)</A
341 > which is where the eCos definitions are generated from.</P
342 ></DIV
343 ><DIV
344 CLASS="SECT2"
345 ><H2
346 CLASS="SECT2"
347 ><A
348 NAME="AEN12726">Generic config information</H2
349 ><P
350 >When a valid device ID (devid) is found using one of the above
351 functions, the associated device can be queried and controlled using
352 the functions:</P
353 ><TABLE
354 BORDER="5"
355 BGCOLOR="#E0E0F0"
356 WIDTH="70%"
357 ><TR
358 ><TD
359 ><PRE
360 CLASS="PROGRAMLISTING"
361 >void cyg_pci_get_device_info (  cyg_pci_device_id devid, 
362                                 cyg_pci_device *dev_info );
363 void cyg_pci_set_device_info (  cyg_pci_device_id devid, 
364                                 cyg_pci_device *dev_info );</PRE
365 ></TD
366 ></TR
367 ></TABLE
368 ><P
369 >The <SPAN
370 CLASS="STRUCTNAME"
371 >cyg_pci_device structure</SPAN
372 > (defined in
373 <TT
374 CLASS="FILENAME"
375 >pci.h</TT
376 >) primarily holds information as described by the PCI
377  specification <A
378 HREF="ecos-pci-library.html#PCI-SPEC"
379 >[1]</A
380 >.
381 The <TT
382 CLASS="FILENAME"
383 >pci1</TT
384 > test prints out some of this information:</P
385 ><TABLE
386 BORDER="5"
387 BGCOLOR="#E0E0F0"
388 WIDTH="70%"
389 ><TR
390 ><TD
391 ><PRE
392 CLASS="PROGRAMLISTING"
393 >            // Get device info
394             cyg_pci_get_device_info(devid, &amp;dev_info);
395             diag_printf("\n Command   0x%04x, Status 0x%04x\n",
396                         dev_info.command, dev_info.status);</PRE
397 ></TD
398 ></TR
399 ></TABLE
400 ><P
401 >The command register can also be written to, controlling (among
402 other things) whether the device responds to IO and memory access
403 from the bus. </P
404 ></DIV
405 ><DIV
406 CLASS="SECT2"
407 ><H2
408 CLASS="SECT2"
409 ><A
410 NAME="AEN12737">Specific config information</H2
411 ><P
412 >The above functions only allow access to generic PCI config
413 registers. A device can have extra config registers not specified
414 by the PCI specification. These can be accessed with these functions:</P
415 ><TABLE
416 BORDER="5"
417 BGCOLOR="#E0E0F0"
418 WIDTH="70%"
419 ><TR
420 ><TD
421 ><PRE
422 CLASS="PROGRAMLISTING"
423 >void cyg_pci_read_config_uint8(  cyg_pci_device_id devid,
424                                  cyg_uint8 offset, cyg_uint8 *val);
425 void cyg_pci_read_config_uint16(  cyg_pci_device_id devid,
426                                   cyg_uint8 offset, cyg_uint16 *val);
427 void cyg_pci_read_config_uint32(  cyg_pci_device_id devid,
428                                   cyg_uint8 offset, cyg_uint32 *val);
429 void cyg_pci_write_config_uint8(  cyg_pci_device_id devid,
430                                   cyg_uint8 offset, cyg_uint8 val);
431 void cyg_pci_write_config_uint16(  cyg_pci_device_id devid,
432                                    cyg_uint8 offset, cyg_uint16 val);
433 void cyg_pci_write_config_uint32(  cyg_pci_device_id devid,
434                                    cyg_uint8 offset, cyg_uint32 val);</PRE
435 ></TD
436 ></TR
437 ></TABLE
438 ><P
439 >The write functions should only be used for device-specific
440 config registers since using them on generic registers may invalidate
441 the contents of a previously fetched cyg_pci_device
442 structure.</P
443 ></DIV
444 ><DIV
445 CLASS="SECT2"
446 ><H2
447 CLASS="SECT2"
448 ><A
449 NAME="AEN12742">Allocating memory</H2
450 ><P
451 >A PCI device ignores all IO and memory access from the PCI
452 bus until it has been activated. Activation cannot happen until
453 after device configuration. Configuration means telling the device
454 where it should map its IO and memory resources. This is done with
455 one of the following functions::</P
456 ><TABLE
457 BORDER="5"
458 BGCOLOR="#E0E0F0"
459 WIDTH="70%"
460 ><TR
461 ><TD
462 ><PRE
463 CLASS="PROGRAMLISTING"
464 >cyg_bool cyg_pci_configure_device( cyg_pci_device *dev_info );
465 cyg_bool cyg_pci_configure_bus( cyg_uint8 bus, cyg_uint8 *next_bus );</PRE
466 ></TD
467 ></TR
468 ></TABLE
469 ><P
470 >The <TT
471 CLASS="FUNCTION"
472 >cyg_pci_configure_device</TT
473 > handles all IO
474 and memory regions that need configuration on non-bridge devices. On
475 platforms with multiple busses connected by bridges, the <TT
476 CLASS="FUNCTION"
477 >cyg_pci_configure_bus</TT
478 > function should be used. It will recursively
479 configure all devices on the given <TT
480 CLASS="PARAMETER"
481 ><I
482 >bus</I
483 ></TT
484 > and all
485 subordinate busses. <TT
486 CLASS="FUNCTION"
487 >cyg_pci_configure_bus</TT
488 > will
489 use <TT
490 CLASS="FUNCTION"
491 >cyg_pci_configure_device</TT
492 > to configure
493 individual non-bridge devices.</P
494 ><P
495 > Each region is represented in the PCI device's config space by BARs
496 (Base Address Registers) and is handled individually according to type
497 using these functions:</P
498 ><TABLE
499 BORDER="5"
500 BGCOLOR="#E0E0F0"
501 WIDTH="70%"
502 ><TR
503 ><TD
504 ><PRE
505 CLASS="PROGRAMLISTING"
506 >cyg_bool cyg_pci_allocate_memory(  cyg_pci_device *dev_info,
507                                    cyg_uint32 bar, 
508                                    CYG_PCI_ADDRESS64 *base );
509 cyg_bool cyg_pci_allocate_io(  cyg_pci_device *dev_info,
510                                cyg_uint32 bar, 
511                                CYG_PCI_ADDRESS32 *base );</PRE
512 ></TD
513 ></TR
514 ></TABLE
515 ><P
516 >The memory bases (in two distinct address spaces) are increased
517 as memory regions are allocated to devices. Allocation will fail
518 (the function returns false) if the base exceeds the limits of the
519 address space (IO is 1MB, memory is 2^32 or 2^64 bytes).</P
520 ><P
521 >These functions can also be called directly by the application/driver
522 if necessary, but this should not be necessary.</P
523 ><P
524 >The bases are initialized with default values provided by
525 the HAL. It is possible for an application to override these using
526 the following functions: </P
527 ><TABLE
528 BORDER="5"
529 BGCOLOR="#E0E0F0"
530 WIDTH="70%"
531 ><TR
532 ><TD
533 ><PRE
534 CLASS="PROGRAMLISTING"
535 >void cyg_pci_set_memory_base(  CYG_PCI_ADDRESS64 base );
536 void cyg_pci_set_io_base( CYG_PCI_ADDRESS32 base );</PRE
537 ></TD
538 ></TR
539 ></TABLE
540 ><P
541 >When a device has been configured, the cyg_pci_device
542 structure will contain the physical address in the CPU's
543 address space where the device's memory regions can be
544 accessed. </P
545 ><P
546 >This information is provided in <TT
547 CLASS="VARNAME"
548 >base_map[]</TT
549 > -
550 there is a 32 bit word for each of the device's BARs. For
551 32 bit PCI memory regions, each 32 bit word will be an actual pointer
552 that can be used immediately by the driver: the memory space will normally
553 be linearly addressable by the CPU.</P
554 ><P
555 >However, for 64 bit PCI memory regions, some (or all) of the
556 region may be outside of the CPUs address space. In this case the
557 driver will need to know how to access the region in segments. This
558 functionality may be adopted by the eCos HAL if deemed useful in
559 the future. The 2GB available on many systems should suffice though.</P
560 ></DIV
561 ><DIV
562 CLASS="SECT2"
563 ><H2
564 CLASS="SECT2"
565 ><A
566 NAME="PCI-INTERRUPTS">Interrupts</H2
567 ><P
568 >A device may generate interrupts. The HAL vector associated
569 with a given device on the bus is platform specific. This function
570 allows a driver to find the actual interrupt vector for a given
571 device:</P
572 ><TABLE
573 BORDER="5"
574 BGCOLOR="#E0E0F0"
575 WIDTH="70%"
576 ><TR
577 ><TD
578 ><PRE
579 CLASS="PROGRAMLISTING"
580 >cyg_bool cyg_pci_translate_interrupt(  cyg_pci_device *dev_info,
581                                        CYG_ADDRWORD *vec );</PRE
582 ></TD
583 ></TR
584 ></TABLE
585 ><P
586 >If the function returns false, no interrupts will be generated
587 by the device. If it returns true, the CYG_ADDRWORD pointed
588 to by vec is updated with the HAL interrupt vector the device will
589 be using. This is how the function is used in the <TT
590 CLASS="FILENAME"
591 >pci1</TT
592 >
593 test:</P
594 ><TABLE
595 BORDER="5"
596 BGCOLOR="#E0E0F0"
597 WIDTH="70%"
598 ><TR
599 ><TD
600 ><PRE
601 CLASS="PROGRAMLISTING"
602 >            if (cyg_pci_translate_interrupt(&amp;dev_info, &amp;irq))
603                 diag_printf(" Wired to HAL vector %d\n", irq);
604             else
605                 diag_printf(" Does not generate interrupts.\n");</PRE
606 ></TD
607 ></TR
608 ></TABLE
609 ><P
610 >The application/drive should attach an interrupt
611 handler to a device's interrupt before activating the device.</P
612 ></DIV
613 ><DIV
614 CLASS="SECT2"
615 ><H2
616 CLASS="SECT2"
617 ><A
618 NAME="AEN12770">Activating a device</H2
619 ><P
620 >When the device has been allocated memory space it can be
621 activated. This is not done by the library since a driver may have
622 to initialize more state on the device before it can be safely activated.</P
623 ><P
624 >Activating the device is done by enabling flags in its command
625 word. As an example, see the <TT
626 CLASS="FILENAME"
627 >pci1</TT
628 > test which can be
629 configured to enable the devices it finds. This allows these to be accessed from
630 GDB (if a breakpoint is set on <TT
631 CLASS="FUNCTION"
632 >cyg_test_exit</TT
633 >):</P
634 ><TABLE
635 BORDER="5"
636 BGCOLOR="#E0E0F0"
637 WIDTH="70%"
638 ><TR
639 ><TD
640 ><PRE
641 CLASS="PROGRAMLISTING"
642 >#ifdef ENABLE_PCI_DEVICES
643       {
644           cyg_uint16 cmd;
645
646           // Don't use cyg_pci_set_device_info since it clears
647           // some of the fields we want to print out below.
648           cyg_pci_read_config_uint16(dev_info.devid,
649                                      CYG_PCI_CFG_COMMAND, &amp;cmd);
650           cmd |= CYG_PCI_CFG_COMMAND_IO|CYG_PCI_CFG_COMMAND_MEMORY;
651           cyg_pci_write_config_uint16(dev_info.devid,
652                                       CYG_PCI_CFG_COMMAND, cmd);
653       }
654       diag_printf(" **** Device IO and MEM access enabled\n");
655 #endif</PRE
656 ></TD
657 ></TR
658 ></TABLE
659 ><DIV
660 CLASS="NOTE"
661 ><BLOCKQUOTE
662 CLASS="NOTE"
663 ><P
664 ><B
665 >Note: </B
666 >The best way to activate a device is actually
667 through <TT
668 CLASS="FUNCTION"
669 >cyg_pci_set_device_info()</TT
670 >,
671 but in this particular case the <SPAN
672 CLASS="STRUCTNAME"
673 >cyg_pci_device</SPAN
674 >
675 structure contents from before the activation is required for printout
676 further down in the code.</P
677 ></BLOCKQUOTE
678 ></DIV
679 ></DIV
680 ><DIV
681 CLASS="SECT2"
682 ><H2
683 CLASS="SECT2"
684 ><A
685 NAME="AEN12782">Links</H2
686 ><P
687 >See these links for more information about PCI:</P
688 ><P
689 ></P
690 ><OL
691 TYPE="1"
692 ><LI
693 ><P
694 ><A
695 NAME="PCI-SPEC"
696 ></A
697 ><A
698 HREF="http://www.pcisig.com/"
699 TARGET="_top"
700 >http://www.pcisig.com/</A
701 > - information on the PCI specifications</P
702 ></LI
703 ><LI
704 ><P
705 ><A
706 HREF="http://www.yourvote.com/pci/"
707 TARGET="_top"
708 >http://www.yourvote.com/pci/</A
709 > - list of vendor and device IDs</P
710 ></LI
711 ><LI
712 ><P
713 ><A
714 HREF="http://www.picmg.org/"
715 TARGET="_top"
716 >http://www.picmg.org/</A
717 > - PCI Industrial Computer Manufacturers Group</P
718 ></LI
719 ></OL
720 ></DIV
721 ></DIV
722 ></DIV
723 ><DIV
724 CLASS="NAVFOOTER"
725 ><HR
726 ALIGN="LEFT"
727 WIDTH="100%"><TABLE
728 SUMMARY="Footer navigation table"
729 WIDTH="100%"
730 BORDER="0"
731 CELLPADDING="0"
732 CELLSPACING="0"
733 ><TR
734 ><TD
735 WIDTH="33%"
736 ALIGN="left"
737 VALIGN="top"
738 ><A
739 HREF="io-pci.html"
740 ACCESSKEY="P"
741 >Prev</A
742 ></TD
743 ><TD
744 WIDTH="34%"
745 ALIGN="center"
746 VALIGN="top"
747 ><A
748 HREF="ecos-ref.html"
749 ACCESSKEY="H"
750 >Home</A
751 ></TD
752 ><TD
753 WIDTH="33%"
754 ALIGN="right"
755 VALIGN="top"
756 ><A
757 HREF="pci-library-reference.html"
758 ACCESSKEY="N"
759 >Next</A
760 ></TD
761 ></TR
762 ><TR
763 ><TD
764 WIDTH="33%"
765 ALIGN="left"
766 VALIGN="top"
767 >PCI Library</TD
768 ><TD
769 WIDTH="34%"
770 ALIGN="center"
771 VALIGN="top"
772 ><A
773 HREF="io-pci.html"
774 ACCESSKEY="U"
775 >Up</A
776 ></TD
777 ><TD
778 WIDTH="33%"
779 ALIGN="right"
780 VALIGN="top"
781 >PCI Library reference</TD
782 ></TR
783 ></TABLE
784 ></DIV
785 ></BODY
786 ></HTML
787 >