]> Zhao Yanbai Git Server - minix.git/commitdiff
PCI driver cleanup 68/2868/1
authorLionel Sambuc <lionel@minix3.org>
Tue, 14 Oct 2014 19:38:39 +0000 (21:38 +0200)
committerLionel Sambuc <lionel@minix3.org>
Fri, 7 Nov 2014 15:20:39 +0000 (16:20 +0100)
 - Moved to KNF
 - Whitespace cleanup
 - Removed useless static functions prototypes
 - Renamed some file private functions by prepending '__'
 - Renamed some server-specific function by prepending '_'
 - Fixed compilation warning for WARNS= 3

Change-Id: Ie44d35839177d5ee0630cdf576660c852452ab80

minix/drivers/bus/pci/Makefile
minix/drivers/bus/pci/main.c
minix/drivers/bus/pci/pci.c
minix/drivers/bus/pci/pci.h
minix/drivers/bus/pci/pci_table.c

index 50af8a580656e6fcce5f4125e859036d1382ebc7..d1e4cf882a3af10cd18d882d60763f8cc6e0ec67 100644 (file)
@@ -5,4 +5,6 @@ SRCS=   main.c pci.c pci_table.c
 DPADD+=        ${LIBSYS} ${LIBTIMERS}
 LDADD+=        -lsys -ltimers
 
+WARNS?=        3
+
 .include <minix.service.mk>
index 1e76f02ce731cc865f4bf37165757764fa8c7c75..7800290219c9713e9fda178ffa6c70b7e8c73675 100644 (file)
@@ -1,96 +1,13 @@
-/*
-main.c
-*/
+#include <minix/driver.h>
+#include <minix/rs.h>
 
 #include "pci.h"
 
+int debug = 0;
 struct pci_acl pci_acl[NR_DRIVERS];
 
-static void do_init(message *mp);
-static void do_first_dev(message *mp);
-static void do_next_dev(message *mp);
-static void do_find_dev(message *mp);
-static void do_ids(message *mp);
-static void do_dev_name_s(message *mp);
-static void do_slot_name_s(message *mp);
-static void do_set_acl(message *mp);
-static void do_del_acl(message *mp);
-static void do_reserve(message *mp);
-static void do_attr_r8(message *mp);
-static void do_attr_r16(message *mp);
-static void do_attr_r32(message *mp);
-static void do_attr_w8(message *mp);
-static void do_attr_w16(message *mp);
-static void do_attr_w32(message *mp);
-static void do_get_bar(message *mp);
-static void do_rescan_bus(message *mp);
-static void reply(message *mp, int result);
-static struct rs_pci *find_acl(int endpoint);
-
-extern int debug;
-
-/* SEF functions and variables. */
-static void sef_local_startup(void);
-
-int main(void)
-{
-       int r;
-       message m;
-       int ipc_status;
-
-       /* SEF local startup. */
-       sef_local_startup();
-
-       for(;;)
-       {
-               r= driver_receive(ANY, &m, &ipc_status);
-               if (r < 0)
-               {
-                       printf("PCI: driver_receive failed: %d\n", r);
-                       break;
-               }
-
-               if (is_ipc_notify(ipc_status)) {
-                       printf("PCI: got notify from %d\n", m.m_source);
-
-                       /* done, get a new message */
-                       continue;
-               }
-
-               switch(m.m_type)
-               {
-               case BUSC_PCI_INIT: do_init(&m); break;
-               case BUSC_PCI_FIRST_DEV: do_first_dev(&m); break;
-               case BUSC_PCI_NEXT_DEV: do_next_dev(&m); break;
-               case BUSC_PCI_FIND_DEV: do_find_dev(&m); break;
-               case BUSC_PCI_IDS: do_ids(&m); break;
-               case BUSC_PCI_RESERVE: do_reserve(&m); break;
-               case BUSC_PCI_ATTR_R8: do_attr_r8(&m); break;
-               case BUSC_PCI_ATTR_R16: do_attr_r16(&m); break;
-               case BUSC_PCI_ATTR_R32: do_attr_r32(&m); break;
-               case BUSC_PCI_ATTR_W8: do_attr_w8(&m); break;
-               case BUSC_PCI_ATTR_W16: do_attr_w16(&m); break;
-               case BUSC_PCI_ATTR_W32: do_attr_w32(&m); break;
-               case BUSC_PCI_RESCAN: do_rescan_bus(&m); break;
-               case BUSC_PCI_DEV_NAME_S: do_dev_name_s(&m); break;
-               case BUSC_PCI_SLOT_NAME_S: do_slot_name_s(&m); break;
-               case BUSC_PCI_SET_ACL: do_set_acl(&m); break;
-               case BUSC_PCI_DEL_ACL: do_del_acl(&m); break;
-               case BUSC_PCI_GET_BAR: do_get_bar(&m); break;
-               default:
-                       printf("PCI: got message from %d, type %d\n",
-                               m.m_source, m.m_type);
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-/*===========================================================================*
- *                            sef_local_startup                             *
- *===========================================================================*/
-static void sef_local_startup()
+static void
+sef_local_startup()
 {
   /* Register init callbacks. */
   sef_setcb_init_fresh(sef_cb_init_fresh);
@@ -105,8 +22,37 @@ static void sef_local_startup()
   sef_startup();
 }
 
-static void do_init(mp)
-message *mp;
+static struct rs_pci *
+find_acl(int endpoint)
+{
+       int i;
+
+       /* Find ACL entry for caller */
+       for (i= 0; i<NR_DRIVERS; i++)
+       {
+               if (!pci_acl[i].inuse)
+                       continue;
+               if (pci_acl[i].acl.rsp_endpoint == endpoint)
+                       return &pci_acl[i].acl;
+       }
+       return NULL;
+}
+
+static void
+reply(message *mp, int result)
+{
+       int r;
+       message m;
+
+       m.m_type= result;
+       r= ipc_send(mp->m_source, &m);
+       if (r != 0)
+               printf("reply: unable to send to %d: %d\n", mp->m_source, r);
+}
+
+
+static void
+do_init(message *mp)
 {
        int r;
 
@@ -121,7 +67,8 @@ message *mp;
                        mp->m_source, r);
 }
 
-static void do_first_dev(message *mp)
+static void
+do_first_dev(message *mp)
 {
        int r, devind;
        u16_t vid, did;
@@ -133,7 +80,7 @@ static void do_first_dev(message *mp)
                printf("PCI: do_first_dev: no acl for caller %d\n",
                        mp->m_source);
 
-       r= pci_first_dev_a(aclp, &devind, &vid, &did);
+       r= _pci_first_dev(aclp, &devind, &vid, &did);
        if (r == 1)
        {
                mp->m1_i1= devind;
@@ -149,7 +96,8 @@ static void do_first_dev(message *mp)
        }
 }
 
-static void do_next_dev(message *mp)
+static void
+do_next_dev(message *mp)
 {
        int r, devind;
        u16_t vid, did;
@@ -158,7 +106,7 @@ static void do_next_dev(message *mp)
        devind= mp->m1_i1;
        aclp= find_acl(mp->m_source);
 
-       r= pci_next_dev_a(aclp, &devind, &vid, &did);
+       r= _pci_next_dev(aclp, &devind, &vid, &did);
        if (r == 1)
        {
                mp->m1_i1= devind;
@@ -174,8 +122,8 @@ static void do_next_dev(message *mp)
        }
 }
 
-static void do_find_dev(mp)
-message *mp;
+static void
+do_find_dev(message *mp)
 {
        int r, devind;
        u8_t bus, dev, func;
@@ -184,7 +132,7 @@ message *mp;
        dev= mp->m1_i2;
        func= mp->m1_i3;
 
-       r= pci_find_dev(bus, dev, func, &devind);
+       r= _pci_find_dev(bus, dev, func, &devind);
        if (r == 1)
                mp->m1_i1= devind;
        mp->m_type= r;
@@ -196,15 +144,15 @@ message *mp;
        }
 }
 
-static void do_ids(mp)
-message *mp;
+static void
+do_ids(message *mp)
 {
        int r, devind;
        u16_t vid, did;
 
        devind= mp->m1_i1;
 
-       r= pci_ids_s(devind, &vid, &did);
+       r= _pci_ids(devind, &vid, &did);
        if (r != OK)
        {
                printf("pci:do_ids: failed for devind %d: %d\n",
@@ -222,20 +170,20 @@ message *mp;
        }
 }
 
-static void do_dev_name_s(mp)
-message *mp;
+static void
+do_dev_name(message *mp)
 {
        int r, name_len, len;
        u16_t vid, did;
        cp_grant_id_t name_gid;
-       char *name;
+       const char *name;
 
        vid= mp->m7_i1;
        did= mp->m7_i2;
        name_len= mp->m7_i3;
        name_gid= mp->m7_i4;
 
-       name= pci_dev_name(vid, did);
+       name= _pci_dev_name(vid, did);
        if (name == NULL)
        {
                /* No name */
@@ -259,8 +207,8 @@ message *mp;
        }
 }
 
-static void do_slot_name_s(mp)
-message *mp;
+static void
+do_slot_name(message *mp)
 {
        int r, devind, name_len, len;
        cp_grant_id_t gid;
@@ -270,7 +218,7 @@ message *mp;
        name_len= mp->m1_i2;
        gid= mp->m1_i3;
 
-       r= pci_slot_name_s(devind, &name);
+       r= _pci_slot_name(devind, &name);
        if (r != OK)
        {
                printf("pci:do_slot_name_s: failed for devind %d: %d\n",
@@ -295,8 +243,8 @@ message *mp;
        }
 }
 
-static void do_set_acl(mp)
-message *mp;
+static void
+do_set_acl(message *mp)
 {
        int i, r, gid;
 
@@ -338,7 +286,8 @@ message *mp;
        reply(mp, OK);
 }
 
-static void do_del_acl(message *mp)
+static void
+do_del_acl(message *mp)
 {
        int i, proc_nr;
 
@@ -373,12 +322,13 @@ static void do_del_acl(message *mp)
 #endif
 
        /* Also release all devices held by this process */
-       pci_release(proc_nr);
+       _pci_release(proc_nr);
 
        reply(mp, OK);
 }
 
-static void do_reserve(message *mp)
+static void
+do_reserve(message *mp)
 {
        struct rs_pci *aclp;
        int r, devind;
@@ -387,7 +337,7 @@ static void do_reserve(message *mp)
 
        aclp= find_acl(mp->m_source);
 
-       mp->m_type= pci_reserve_a(devind, mp->m_source, aclp);
+       mp->m_type= _pci_reserve(devind, mp->m_source, aclp);
        r= ipc_send(mp->m_source, mp);
        if (r != 0)
        {
@@ -396,8 +346,8 @@ static void do_reserve(message *mp)
        }
 }
 
-static void do_attr_r8(mp)
-message *mp;
+static void
+do_attr_r8(message *mp)
 {
        int r, devind, port;
        u8_t v;
@@ -405,11 +355,11 @@ message *mp;
        devind= mp->m2_i1;
        port= mp->m2_i2;
 
-       r= pci_attr_r8_s(devind, port, &v);
+       r= _pci_attr_r8(devind, port, &v);
        if (r != OK)
        {
                printf(
-               "pci:do_attr_r8: pci_attr_r8_s(%d, %d, ...) failed: %d\n",
+               "pci:do_attr_r8: pci_attr_r8(%d, %d, ...) failed: %d\n",
                        devind, port, r);
        }
        mp->m2_l1= v;
@@ -422,16 +372,22 @@ message *mp;
        }
 }
 
-static void do_attr_r16(mp)
-message *mp;
+static void
+do_attr_r16(message *mp)
 {
        int r, devind, port;
-       u32_t v;
+       u16_t v;
 
        devind= mp->m2_i1;
        port= mp->m2_i2;
 
-       v= pci_attr_r16(devind, port);
+       r= _pci_attr_r16(devind, port, &v);
+       if (r != OK)
+       {
+               printf(
+               "pci:do_attr_r16: pci_attr_r16(%d, %d, ...) failed: %d\n",
+                       devind, port, r);
+       }
        mp->m2_l1= v;
        mp->m_type= OK;
        r= ipc_send(mp->m_source, mp);
@@ -442,8 +398,8 @@ message *mp;
        }
 }
 
-static void do_attr_r32(mp)
-message *mp;
+static void
+do_attr_r32(message *mp)
 {
        int r, devind, port;
        u32_t v;
@@ -451,11 +407,11 @@ message *mp;
        devind= mp->m2_i1;
        port= mp->m2_i2;
 
-       r= pci_attr_r32_s(devind, port, &v);
+       r= _pci_attr_r32(devind, port, &v);
        if (r != OK)
        {
                printf(
-               "pci:do_attr_r32: pci_attr_r32_s(%d, %d, ...) failed: %d\n",
+               "pci:do_attr_r32: pci_attr_r32(%d, %d, ...) failed: %d\n",
                        devind, port, r);
        }
        mp->m2_l1= v;
@@ -468,8 +424,8 @@ message *mp;
        }
 }
 
-static void do_attr_w8(mp)
-message *mp;
+static void
+do_attr_w8(message *mp)
 {
        int r, devind, port;
        u8_t v;
@@ -478,7 +434,7 @@ message *mp;
        port= mp->m2_i2;
        v= mp->m2_l1;
 
-       pci_attr_w8(devind, port, v);
+       _pci_attr_w8(devind, port, v);
        mp->m_type= OK;
        r= ipc_send(mp->m_source, mp);
        if (r != 0)
@@ -488,8 +444,8 @@ message *mp;
        }
 }
 
-static void do_attr_w16(mp)
-message *mp;
+static void
+do_attr_w16(message *mp)
 {
        int r, devind, port;
        u16_t v;
@@ -498,7 +454,7 @@ message *mp;
        port= mp->m2_i2;
        v= mp->m2_l1;
 
-       pci_attr_w16(devind, port, v);
+       _pci_attr_w16(devind, port, v);
        mp->m_type= OK;
        r= ipc_send(mp->m_source, mp);
        if (r != 0)
@@ -508,8 +464,8 @@ message *mp;
        }
 }
 
-static void do_attr_w32(mp)
-message *mp;
+static void
+do_attr_w32(message *mp)
 {
        int r, devind, port;
        u32_t v;
@@ -518,7 +474,7 @@ message *mp;
        port= mp->m2_i2;
        v= mp->m2_l1;
 
-       pci_attr_w32(devind, port, v);
+       _pci_attr_w32(devind, port, v);
        mp->m_type= OK;
        r= ipc_send(mp->m_source, mp);
        if (r != 0)
@@ -528,8 +484,8 @@ message *mp;
        }
 }
 
-static void do_get_bar(mp)
-message *mp;
+static void
+do_get_bar(message *mp)
 {
        int r, devind, port, ioflag;
        u32_t base, size;
@@ -537,7 +493,7 @@ message *mp;
        devind= mp->m_lsys_pci_busc_get_bar.devind;
        port= mp->m_lsys_pci_busc_get_bar.port;
 
-       mp->m_type= pci_get_bar_s(devind, port, &base, &size, &ioflag);
+       mp->m_type= _pci_get_bar(devind, port, &base, &size, &ioflag);
 
        if (mp->m_type == OK)
        {
@@ -554,14 +510,14 @@ message *mp;
        }
 }
 
-static void do_rescan_bus(mp)
-message *mp;
+static void
+do_rescan_bus(message *mp)
 {
        int r, busnr;
 
        busnr= mp->m2_i1;
 
-       pci_rescan_bus(busnr);
+       _pci_rescan_bus(busnr);
        mp->m_type= OK;
        r= ipc_send(mp->m_source, mp);
        if (r != 0)
@@ -571,33 +527,58 @@ message *mp;
        }
 }
 
-
-static void reply(mp, result)
-message *mp;
-int result;
+int
+main(void)
 {
        int r;
        message m;
+       int ipc_status;
 
-       m.m_type= result;
-       r= ipc_send(mp->m_source, &m);
-       if (r != 0)
-               printf("reply: unable to send to %d: %d\n", mp->m_source, r);
-}
+       /* SEF local startup. */
+       sef_local_startup();
 
+       for(;;)
+       {
+               r= driver_receive(ANY, &m, &ipc_status);
+               if (r < 0)
+               {
+                       printf("PCI: driver_receive failed: %d\n", r);
+                       break;
+               }
 
-static struct rs_pci *find_acl(endpoint)
-int endpoint;
-{
-       int i;
+               if (is_ipc_notify(ipc_status)) {
+                       printf("PCI: got notify from %d\n", m.m_source);
 
-       /* Find ACL entry for caller */
-       for (i= 0; i<NR_DRIVERS; i++)
-       {
-               if (!pci_acl[i].inuse)
+                       /* done, get a new message */
                        continue;
-               if (pci_acl[i].acl.rsp_endpoint == endpoint)
-                       return &pci_acl[i].acl;
+               }
+
+               switch(m.m_type)
+               {
+               case BUSC_PCI_INIT: do_init(&m); break;
+               case BUSC_PCI_FIRST_DEV: do_first_dev(&m); break;
+               case BUSC_PCI_NEXT_DEV: do_next_dev(&m); break;
+               case BUSC_PCI_FIND_DEV: do_find_dev(&m); break;
+               case BUSC_PCI_IDS: do_ids(&m); break;
+               case BUSC_PCI_RESERVE: do_reserve(&m); break;
+               case BUSC_PCI_ATTR_R8: do_attr_r8(&m); break;
+               case BUSC_PCI_ATTR_R16: do_attr_r16(&m); break;
+               case BUSC_PCI_ATTR_R32: do_attr_r32(&m); break;
+               case BUSC_PCI_ATTR_W8: do_attr_w8(&m); break;
+               case BUSC_PCI_ATTR_W16: do_attr_w16(&m); break;
+               case BUSC_PCI_ATTR_W32: do_attr_w32(&m); break;
+               case BUSC_PCI_RESCAN: do_rescan_bus(&m); break;
+               case BUSC_PCI_DEV_NAME_S: do_dev_name(&m); break;
+               case BUSC_PCI_SLOT_NAME_S: do_slot_name(&m); break;
+               case BUSC_PCI_SET_ACL: do_set_acl(&m); break;
+               case BUSC_PCI_DEL_ACL: do_del_acl(&m); break;
+               case BUSC_PCI_GET_BAR: do_get_bar(&m); break;
+               default:
+                       printf("PCI: got message from %d, type %d\n",
+                               m.m_source, m.m_type);
+                       break;
+               }
        }
-       return NULL;
+
+       return 0;
 }
index 5a4baf7f3eee34a21fb77b1b9ee50cb4fa5201db..516cfce28ae9f615ecc71aa2be75c828239abf1f 100644 (file)
@@ -6,32 +6,26 @@ Configure devices on the PCI bus
 Created:       Jan 2000 by Philip Homburg <philip@cs.vu.nl>
 */
 
-#include <assert.h>
-#include <machine/pci.h>
-#include <machine/vm.h>
-#include <machine/vmparam.h>
-#include <minix/com.h>
-#include <minix/ds.h>
-#include <minix/syslib.h>
+#include <minix/driver.h>
+
+#include <minix/acpi.h>
 #include <minix/param.h>
+#include <minix/ds.h>
+#include <minix/rs.h>
 
-#include "pci.h"
+#include <machine/pci.h>
 #include <machine/pci_amd.h>
 #include <machine/pci_intel.h>
 #include <machine/pci_sis.h>
 #include <machine/pci_via.h>
-#if __minix_vmd
-#include "config.h"
-#endif
-
-#if !__minix_vmd
-#define irq_mode_pci(irq) ((void)0)
-#endif
+#include <machine/vmparam.h>
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <minix/sysutil.h>
-#include <minix/acpi.h>
+
+#include "pci.h"
+
+#define irq_mode_pci(irq) ((void)0)
 
 #define PBT_INTEL_HOST  1
 #define PBT_PCIBRIDGE   2
@@ -39,7 +33,7 @@ Created:      Jan 2000 by Philip Homburg <philip@cs.vu.nl>
 
 #define BAM_NR         6       /* Number of base-address registers */
 
-int debug= 0;
+struct pci_acl pci_acl[NR_DRIVERS];
 
 static struct pcibus
 {
@@ -88,1189 +82,986 @@ static struct pcidev
        int pd_bar_nr;
 } pcidev[NR_PCIDEV];
 
-EXTERN struct pci_acl pci_acl[NR_DRIVERS];
-
 /* pb_flags */
 #define PBF_IO         1       /* I/O else memory */
 #define PBF_INCOMPLETE 2       /* not allocated */
 
 static int nr_pcidev= 0;
 
-static void pci_intel_init(void);
-static void probe_bus(int busind);
-static int is_duplicate(u8_t busnr, u8_t dev, u8_t func);
-static void record_irq(int devind);
-static void record_bars_normal(int devind);
-static void record_bars_bridge(int devind);
-static void record_bars_cardbus(int devind);
-static void record_bars(int devind, int last_reg);
-static int record_bar(int devind, int bar_nr, int last);
-static void complete_bridges(void);
-static void complete_bars(void);
-static void update_bridge4dev_io(int devind, u32_t io_base, u32_t
-       io_size);
-static int get_freebus(void);
-static int do_isabridge(int busind);
-static void do_pcibridge(int busind);
-static int get_busind(int busnr);
-static int do_piix(int devind);
-static int do_amd_isabr(int devind);
-static int do_sis_isabr(int devind);
-static int do_via_isabr(int devind);
-#if 0
-static void report_vga(int devind);
-#endif
-static char *pci_vid_name(u16_t vid);
-static char *pci_baseclass_name(u8_t baseclass);
-static char *pci_subclass_name(u8_t baseclass, u8_t subclass, u8_t
-       infclass);
-static void ntostr(unsigned n, char **str, const char *end);
-
-static u8_t pci_attr_r8_u(int devind, int port);
-static u32_t pci_attr_r32_u(int devind, int port);
-
-static u16_t pci_attr_rsts(int devind);
-static void pci_attr_wsts(int devind, u16_t value);
-static u16_t pcibr_std_rsts(int busind);
-static void pcibr_std_wsts(int busind, u16_t value);
-static u16_t pcibr_cb_rsts(int busind);
-static void pcibr_cb_wsts(int busind, u16_t value);
-static u16_t pcibr_via_rsts(int busind);
-static void pcibr_via_wsts(int busind, u16_t value);
-static u8_t pcii_rreg8(int busind, int devind, int port);
-static u16_t pcii_rreg16(int busind, int devind, int port);
-static u32_t pcii_rreg32(int busind, int devind, int port);
-static void pcii_wreg8(int busind, int devind, int port, u8_t value);
-static void pcii_wreg16(int busind, int devind, int port, u16_t value);
-static void pcii_wreg32(int busind, int devind, int port, u32_t value);
-static u16_t pcii_rsts(int busind);
-static void pcii_wsts(int busind, u16_t value);
-static void print_capabilities(int devind);
-static int visible(struct rs_pci *aclp, int devind);
-static void print_hyper_cap(int devind, u8_t capptr);
-
 static struct machine machine;
 static endpoint_t acpi_ep;
 
-/*===========================================================================*
- *                             sef_cb_init_fresh                            *
- *===========================================================================*/
-int sef_cb_init_fresh(int type, sef_init_info_t *info)
-{
-/* Initialize the pci driver. */
-       long v;
-       int i, r;
-       struct rprocpub rprocpub[NR_BOOT_PROCS];
-
-       v= 0;
-       env_parse("pci_debug", "d", 0, &v, 0, 1);
-       debug= v;
-
-       if (sys_getmachine(&machine)) {
-               printf("PCI: no machine\n");
-               return ENODEV;
-       }
-       if (machine.apic_enabled &&
-                       ds_retrieve_label_endpt("acpi", &acpi_ep) != OK) {
-               panic("PCI: Cannot use APIC mode without ACPI!\n");
-       }
-
-       /* Only Intel (compatible) PCI controllers are supported at the
-        * moment.
-        */
-       pci_intel_init();
-
-       /* Map all the services in the boot image. */
-       if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
-               (vir_bytes) rprocpub, sizeof(rprocpub))) != OK) {
-               panic("sys_safecopyfrom failed: %d", r);
-       }
-       for(i=0;i < NR_BOOT_PROCS;i++) {
-               if(rprocpub[i].in_use) {
-                       if((r = map_service(&rprocpub[i])) != OK) {
-                               panic("unable to map service: %d", r);
-                       }
-               }
-       }
-
-       return(OK);
-}
-
-/*===========================================================================*
- *                            map_service                                   *
- *===========================================================================*/
-int map_service(rpub)
-struct rprocpub *rpub;
-{
-/* Map a new service by registering a new acl entry if required. */
-       int i;
-
-       /* Stop right now if no pci device or class is found. */
-       if(rpub->pci_acl.rsp_nr_device == 0
-               && rpub->pci_acl.rsp_nr_class == 0) {
-               return(OK);
-       }
-
-       /* Find a free acl slot. */
-       for (i= 0; i<NR_DRIVERS; i++)
-       {
-               if (!pci_acl[i].inuse)
-                       break;
-       }
-       if (i >= NR_DRIVERS)
-       {
-               printf("PCI: map_service: table is full\n");
-               return ENOMEM;
-       }
-
-       /* Initialize acl slot. */
-       pci_acl[i].inuse = 1;
-       pci_acl[i].acl = rpub->pci_acl;
-
-       return(OK);
-}
-
 /*===========================================================================*
  *                     helper functions for I/O                             *
  *===========================================================================*/
-unsigned pci_inb(u16_t port) {
+static unsigned
+pci_inb(u16_t port) {
        u32_t value;
        int s;
        if ((s=sys_inb(port, &value)) !=OK)
                printf("PCI: warning, sys_inb failed: %d\n", s);
        return value;
 }
-unsigned pci_inw(u16_t port) {
+
+static unsigned
+pci_inw(u16_t port) {
        u32_t value;
        int s;
        if ((s=sys_inw(port, &value)) !=OK)
                printf("PCI: warning, sys_inw failed: %d\n", s);
        return value;
 }
-unsigned pci_inl(u16_t port) {
+
+static unsigned
+pci_inl(u16_t port) {
        u32_t value;
        int s;
        if ((s=sys_inl(port, &value)) !=OK)
                printf("PCI: warning, sys_inl failed: %d\n", s);
        return value;
 }
-void pci_outb(u16_t port, u8_t value) {
+
+static void
+pci_outb(u16_t port, u8_t value) {
        int s;
        if ((s=sys_outb(port, value)) !=OK)
                printf("PCI: warning, sys_outb failed: %d\n", s);
 }
-void pci_outw(u16_t port, u16_t value) {
+
+static void
+pci_outw(u16_t port, u16_t value) {
        int s;
        if ((s=sys_outw(port, value)) !=OK)
                printf("PCI: warning, sys_outw failed: %d\n", s);
 }
-void pci_outl(u16_t port, u32_t value) {
+
+static void
+pci_outl(u16_t port, u32_t value) {
        int s;
        if ((s=sys_outl(port, value)) !=OK)
                printf("PCI: warning, sys_outl failed: %d\n", s);
 }
 
-/*===========================================================================*
- *                             pci_find_dev                                 *
- *===========================================================================*/
-int pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp)
+static u8_t
+pcii_rreg8(int busind, int devind, int port)
 {
-       int devind;
+       u8_t v;
+       int s;
 
-       for (devind= 0; devind < nr_pcidev; devind++)
-       {
-               if (pcidev[devind].pd_busnr == bus &&
-                       pcidev[devind].pd_dev == dev &&
-                       pcidev[devind].pd_func == func)
-               {
-                       break;
-               }
-       }
-       if (devind >= nr_pcidev)
-               return 0;
+       v= PCII_RREG8_(pcibus[busind].pb_busnr,
+               pcidev[devind].pd_dev, pcidev[devind].pd_func,
+               port);
+       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
+               printf("PCI: warning, sys_outl failed: %d\n", s);
 #if 0
-       if (pcidev[devind].pd_inuse)
-               return 0;
+       printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
+               busind, devind, port,
+               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
+               pcidev[devind].pd_func, v);
 #endif
-       *devindp= devind;
-       return 1;
+       return v;
 }
 
-/*===========================================================================*
- *                             pci_first_dev_a                              *
- *===========================================================================*/
-int pci_first_dev_a(
-  struct rs_pci *aclp,
-  int *devindp,
-  u16_t *vidp,
-  u16_t *didp
-)
+static u16_t
+pcii_rreg16(int busind, int devind, int port)
 {
-       int devind;
+       u16_t v;
+       int s;
 
-       for (devind= 0; devind < nr_pcidev; devind++)
-       {
+       v= PCII_RREG16_(pcibus[busind].pb_busnr,
+               pcidev[devind].pd_dev, pcidev[devind].pd_func,
+               port);
+       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
+               printf("PCI: warning, sys_outl failed: %d\n", s);
 #if 0
-               if (pcidev[devind].pd_inuse)
-                       continue;
+       printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
+               busind, devind, port,
+               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
+               pcidev[devind].pd_func, v);
 #endif
-               if (!visible(aclp, devind))
-                       continue;
-               break;
-       }
-       if (devind >= nr_pcidev)
-               return 0;
-       *devindp= devind;
-       *vidp= pcidev[devind].pd_vid;
-       *didp= pcidev[devind].pd_did;
-       return 1;
+       return v;
 }
 
-/*===========================================================================*
- *                             pci_next_dev                                 *
- *===========================================================================*/
-int pci_next_dev_a(
-  struct rs_pci *aclp,
-  int *devindp,
-  u16_t *vidp,
-  u16_t *didp
-)
+static u32_t
+pcii_rreg32(int busind, int devind, int port)
 {
-       int devind;
+       u32_t v;
+       int s;
 
-       for (devind= *devindp+1; devind < nr_pcidev; devind++)
-       {
+       v= PCII_RREG32_(pcibus[busind].pb_busnr,
+               pcidev[devind].pd_dev, pcidev[devind].pd_func,
+               port);
+       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
+               printf("PCI: warning, sys_outl failed: %d\n", s);
 #if 0
-               if (pcidev[devind].pd_inuse)
-                       continue;
+       printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
+               busind, devind, port,
+               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
+               pcidev[devind].pd_func, v);
 #endif
-               if (!visible(aclp, devind))
-                       continue;
-               break;
-       }
-       if (devind >= nr_pcidev)
-               return 0;
-       *devindp= devind;
-       *vidp= pcidev[devind].pd_vid;
-       *didp= pcidev[devind].pd_did;
-       return 1;
+       return v;
+}
+
+static void
+pcii_wreg8(int busind, int devind, int port, u8_t value)
+{
+       int s;
+#if 0
+       printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
+               busind, devind, port, value,
+               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
+               pcidev[devind].pd_func);
+#endif
+       PCII_WREG8_(pcibus[busind].pb_busnr,
+               pcidev[devind].pd_dev, pcidev[devind].pd_func,
+               port, value);
+       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
+               printf("PCI: warning, sys_outl failed: %d\n", s);
+}
+
+static void
+pcii_wreg16(int busind, int devind, int port, u16_t value)
+{
+       int s;
+#if 0
+       printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
+               busind, devind, port, value,
+               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
+               pcidev[devind].pd_func);
+#endif
+       PCII_WREG16_(pcibus[busind].pb_busnr,
+               pcidev[devind].pd_dev, pcidev[devind].pd_func,
+               port, value);
+       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
+               printf("PCI: warning, sys_outl failed: %d\n", s);
+}
+
+static void
+pcii_wreg32(int busind, int devind, int port, u32_t value)
+{
+       int s;
+#if 0
+       printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
+               busind, devind, port, value,
+               pcibus[busind].pb_busnr, pcidev[devind].pd_dev,
+               pcidev[devind].pd_func);
+#endif
+       PCII_WREG32_(pcibus[busind].pb_busnr,
+               pcidev[devind].pd_dev, pcidev[devind].pd_func,
+               port, value);
+       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
+               printf("PCI: warning, sys_outl failed: %d\n",s);
 }
 
 /*===========================================================================*
- *                             pci_reserve_a                                *
+ *                             ntostr                                       *
  *===========================================================================*/
-int pci_reserve_a(devind, proc, aclp)
-int devind;
-endpoint_t proc;
-struct rs_pci *aclp;
+static void
+ntostr(unsigned int n, char **str, const char *end)
 {
-       int i, r;
-       int ilr;
-       struct io_range ior;
-       struct minix_mem_range mr;
+       char tmpstr[20];
+       int i;
 
-       if (devind < 0 || devind >= nr_pcidev)
+       if (n == 0)
        {
-               printf("pci_reserve_a: bad devind: %d\n", devind);
-               return EINVAL;
+               tmpstr[0]= '0';
+               i= 1;
        }
-       if (!visible(aclp, devind))
+       else
        {
-               printf("pci_reserve_a: %u is not allowed to reserve %d\n",
-                       proc, devind);
-               return EPERM;
+               for (i= 0; n; i++)
+               {
+                       tmpstr[i]= '0' + (n%10);
+                       n /= 10;
+               }
        }
-
-       if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
-               return EBUSY;
-       pcidev[devind].pd_inuse= 1;
-       pcidev[devind].pd_proc= proc;
-
-       for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
-       {
-               if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
-               {
-                       printf("pci_reserve_a: BAR %d is incomplete\n", i);
-                       continue;
-               }
-               if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
-               {
-                       ior.ior_base= pcidev[devind].pd_bar[i].pb_base;
-                       ior.ior_limit= ior.ior_base +
-                               pcidev[devind].pd_bar[i].pb_size-1;
-
-                       if(debug) {
-                          printf(
-               "pci_reserve_a: for proc %d, adding I/O range [0x%x..0x%x]\n",
-                               proc, ior.ior_base, ior.ior_limit);
-                       }
-                       r= sys_privctl(proc, SYS_PRIV_ADD_IO, &ior);
-                       if (r != OK)
-                       {
-                               printf("sys_privctl failed for proc %d: %d\n",
-                                       proc, r);
-                       }
-               }
-               else
-               {
-                       mr.mr_base= pcidev[devind].pd_bar[i].pb_base;
-                       mr.mr_limit= mr.mr_base +
-                               pcidev[devind].pd_bar[i].pb_size-1;
-
-                       r= sys_privctl(proc, SYS_PRIV_ADD_MEM, &mr);
-                       if (r != OK)
-                       {
-                               printf("sys_privctl failed for proc %d: %d\n",
-                                       proc, r);
-                       }
-               }
-       }
-       ilr= pcidev[devind].pd_ilr;
-       if (ilr != PCI_ILR_UNKNOWN)
+       for (; i>0; i--)
        {
-               if(debug) printf("pci_reserve_a: adding IRQ %d\n", ilr);
-               r= sys_privctl(proc, SYS_PRIV_ADD_IRQ, &ilr);
-               if (r != OK)
+               if (*str == end)
                {
-                       printf("sys_privctl failed for proc %d: %d\n",
-                               proc, r);
+                       break;
                }
+               **str= tmpstr[i-1];
+               (*str)++;
        }
-
-       return OK;
+       if (*str == end)
+               (*str)[-1]= '\0';
+       else
+               **str= '\0';
 }
 
 /*===========================================================================*
- *                             pci_release                                  *
+ *                             get_busind                                           *
  *===========================================================================*/
-void pci_release(proc)
-endpoint_t proc;
+static int
+get_busind(int busnr)
 {
        int i;
 
-       for (i= 0; i<nr_pcidev; i++)
+       for (i= 0; i<nr_pcibus; i++)
        {
-               if (!pcidev[i].pd_inuse)
-                       continue;
-               if (pcidev[i].pd_proc != proc)
-                       continue;
-               pcidev[i].pd_inuse= 0;
+               if (pcibus[i].pb_busnr == busnr)
+                       return i;
        }
+       panic("get_busind: can't find bus: %d", busnr);
 }
 
 /*===========================================================================*
- *                             pci_ids_s                                    *
- *===========================================================================*/
-int pci_ids_s(int devind, u16_t *vidp, u16_t *didp)
-{
-       if (devind < 0 || devind >= nr_pcidev)
-               return EINVAL;
-
-       *vidp= pcidev[devind].pd_vid;
-       *didp= pcidev[devind].pd_did;
-       return OK;
-}
-
-/*===========================================================================*
- *                             pci_rescan_bus                               *
+ *                     Unprotected helper functions                         *
  *===========================================================================*/
-void pci_rescan_bus(u8_t busnr)
+static u8_t
+__pci_attr_r8(int devind, int port)
 {
-       int busind;
+       int busnr, busind;
 
+       busnr= pcidev[devind].pd_busnr;
        busind= get_busind(busnr);
-       probe_bus(busind);
-
-       /* Allocate bus numbers for uninitialized bridges */
-       complete_bridges();
-
-       /* Allocate I/O and memory resources for uninitialized devices */
-       complete_bars();
-}
-
-/*===========================================================================*
- *                             pci_slot_name_s                              *
- *===========================================================================*/
-int pci_slot_name_s(devind, cpp)
-int devind;
-char **cpp;
-{
-       static char label[]= "ddd.ddd.ddd";
-       char *end;
-       char *p;
-
-       if (devind < 0 || devind >= nr_pcidev)
-               return EINVAL;
-
-       p= label;
-       end= label+sizeof(label);
-
-       ntostr(pcidev[devind].pd_busnr, &p, end);
-       *p++= '.';
-
-       ntostr(pcidev[devind].pd_dev, &p, end);
-       *p++= '.';
-
-       ntostr(pcidev[devind].pd_func, &p, end);
-
-       *cpp= label;
-       return OK;
-}
-
-/*===========================================================================*
- *                             pci_dev_name                                 *
- *===========================================================================*/
-char *pci_dev_name(u16_t vid, u16_t did)
-{
-       int i;
-
-       for (i= 0; pci_device_table[i].name; i++)
-       {
-               if (pci_device_table[i].vid == vid &&
-                       pci_device_table[i].did == did)
-               {
-                       return pci_device_table[i].name;
-               }
-       }
-       return NULL;
-}
-
-/*===========================================================================*
- *                             pci_get_bar_s                                *
- *===========================================================================*/
-int pci_get_bar_s(int devind, int port, u32_t *base, u32_t *size,
-       int *ioflag)
-{
-       int i, reg;
-
-       if (devind < 0 || devind >= nr_pcidev)
-               return EINVAL;
-
-       for (i= 0; i < pcidev[devind].pd_bar_nr; i++)
-       {
-               reg= PCI_BAR+4*pcidev[devind].pd_bar[i].pb_nr;
-
-               if (reg == port)
-               {
-                       if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
-                               return EINVAL;
-
-                       *base= pcidev[devind].pd_bar[i].pb_base;
-                       *size= pcidev[devind].pd_bar[i].pb_size;
-                       *ioflag=
-                               !!(pcidev[devind].pd_bar[i].pb_flags & PBF_IO);
-                       return OK;
-               }
-       }
-       return EINVAL;
-}
-
-/*===========================================================================*
- *                             pci_attr_r8_s                                *
- *===========================================================================*/
-int pci_attr_r8_s(int devind, int port, u8_t *vp)
-{
-       if (devind < 0 || devind >= nr_pcidev)
-               return EINVAL;
-       if (port < 0 || port > 255)
-               return EINVAL;
-
-       *vp= pci_attr_r8_u(devind, port);
-       return OK;
+       return pcibus[busind].pb_rreg8(busind, devind, port);
 }
 
-/*===========================================================================*
- *                             pci_attr_r8_u                                *
- *===========================================================================*/
-static u8_t pci_attr_r8_u(devind, port)
-int devind;
-int port;
+static u16_t
+__pci_attr_r16(int devind, int port)
 {
        int busnr, busind;
 
        busnr= pcidev[devind].pd_busnr;
        busind= get_busind(busnr);
-       return pcibus[busind].pb_rreg8(busind, devind, port);
+       return pcibus[busind].pb_rreg16(busind, devind, port);
 }
 
-/*===========================================================================*
- *                             pci_attr_r16                                 *
- *===========================================================================*/
-u16_t pci_attr_r16(devind, port)
-int devind;
-int port;
+static u32_t
+__pci_attr_r32(int devind, int port)
 {
        int busnr, busind;
 
        busnr= pcidev[devind].pd_busnr;
        busind= get_busind(busnr);
-       return pcibus[busind].pb_rreg16(busind, devind, port);
+       return pcibus[busind].pb_rreg32(busind, devind, port);
 }
 
-/*===========================================================================*
- *                             pci_attr_r32_s                               *
- *===========================================================================*/
-int pci_attr_r32_s(int devind, int port, u32_t *vp)
+static void
+__pci_attr_w8(int devind, int port, u8_t value)
 {
-       if (devind < 0 || devind >= nr_pcidev)
-               return EINVAL;
-       if (port < 0 || port > 256-4)
-               return EINVAL;
+       int busnr, busind;
 
-       *vp= pci_attr_r32_u(devind, port);
-       return OK;
+       busnr= pcidev[devind].pd_busnr;
+       busind= get_busind(busnr);
+       pcibus[busind].pb_wreg8(busind, devind, port, value);
 }
 
-/*===========================================================================*
- *                             pci_attr_r32_u                               *
- *===========================================================================*/
-static u32_t pci_attr_r32_u(devind, port)
-int devind;
-int port;
+static void
+__pci_attr_w16(int devind, int port, u16_t value)
 {
        int busnr, busind;
 
        busnr= pcidev[devind].pd_busnr;
        busind= get_busind(busnr);
-       return pcibus[busind].pb_rreg32(busind, devind, port);
+       pcibus[busind].pb_wreg16(busind, devind, port, value);
 }
 
-/*===========================================================================*
- *                             pci_attr_w8                                  *
- *===========================================================================*/
-void pci_attr_w8(int devind, int port, u8_t value)
+static void
+__pci_attr_w32(int devind, int port, u32_t value)
 {
        int busnr, busind;
 
        busnr= pcidev[devind].pd_busnr;
        busind= get_busind(busnr);
-       pcibus[busind].pb_wreg8(busind, devind, port, value);
+       pcibus[busind].pb_wreg32(busind, devind, port, value);
 }
 
 /*===========================================================================*
- *                             pci_attr_w16                                 *
+ *                             helpers                                      *
  *===========================================================================*/
-void pci_attr_w16(int devind, int port, u16_t value)
+static u16_t
+pci_attr_rsts(int devind)
 {
        int busnr, busind;
 
        busnr= pcidev[devind].pd_busnr;
        busind= get_busind(busnr);
-       pcibus[busind].pb_wreg16(busind, devind, port, value);
+       return pcibus[busind].pb_rsts(busind);
 }
 
-/*===========================================================================*
- *                             pci_attr_w32                                 *
- *===========================================================================*/
-void pci_attr_w32(int devind, int port, u32_t value)
+static void
+pci_attr_wsts(int devind, u16_t value)
 {
        int busnr, busind;
 
        busnr= pcidev[devind].pd_busnr;
        busind= get_busind(busnr);
-       pcibus[busind].pb_wreg32(busind, devind, port, value);
+       pcibus[busind].pb_wsts(busind, value);
 }
 
-/*===========================================================================*
- *                             pci_intel_init                               *
- *===========================================================================*/
-static void pci_intel_init()
+static u16_t
+pcii_rsts(int busind)
 {
-       /* Try to detect a know PCI controller. Read the Vendor ID and
-        * the Device ID for function 0 of device 0.
-        * Two times the value 0xffff suggests a system without a (compatible)
-        * PCI controller. 
-        */
-       u32_t bus, dev, func;
-       u16_t vid, did;
-       int s, i, r, busind, busnr;
-       char *dstr;
+       u16_t v;
+       int s;
 
-       bus= 0;
-       dev= 0;
-       func= 0;
+       v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR);
+       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
+               printf("PCI: warning, sys_outl failed: %d\n", s);
+       return v;
+}
 
-       vid= PCII_RREG16_(bus, dev, func, PCI_VID);
-       did= PCII_RREG16_(bus, dev, func, PCI_DID);
+static void
+pcii_wsts(int busind, u16_t value)
+{
+       int s;
+       PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value);
        if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
                printf("PCI: warning, sys_outl failed: %d\n", s);
+}
 
-#if 0
-       if (vid == 0xffff && did == 0xffff)
-               return; /* Nothing here */
+static int
+is_duplicate(u8_t busnr, u8_t dev, u8_t func)
+{
+       int i;
 
-       for (i= 0; pci_intel_ctrl[i].vid; i++)
+       for (i= 0; i<nr_pcidev; i++)
        {
-               if (pci_intel_ctrl[i].vid == vid &&
-                       pci_intel_ctrl[i].did == did)
+               if (pcidev[i].pd_busnr == busnr &&
+                       pcidev[i].pd_dev == dev &&
+                       pcidev[i].pd_func == func)
                {
-                       break;
+                       return 1;
                }
        }
+       return 0;
+}
 
-       if (!pci_intel_ctrl[i].vid)
-       {
-               printf("pci_intel_init (warning): unknown PCI-controller:\n"
-                       "\tvendor %04X (%s), device %04X\n",
-                       vid, pci_vid_name(vid), did);
-       }
-#endif
+static int
+get_freebus(void)
+{
+       int i, freebus;
 
-       if (nr_pcibus >= NR_PCIBUS)
-               panic("too many PCI busses: %d", nr_pcibus);
-       busind= nr_pcibus;
-       nr_pcibus++;
-       pcibus[busind].pb_type= PBT_INTEL_HOST;
-       pcibus[busind].pb_needinit= 0;
-       pcibus[busind].pb_isabridge_dev= -1;
-       pcibus[busind].pb_isabridge_type= 0;
-       pcibus[busind].pb_devind= -1;
-       pcibus[busind].pb_busnr= 0;
-       pcibus[busind].pb_rreg8= pcii_rreg8;
-       pcibus[busind].pb_rreg16= pcii_rreg16;
-       pcibus[busind].pb_rreg32= pcii_rreg32;
-       pcibus[busind].pb_wreg8= pcii_wreg8;
-       pcibus[busind].pb_wreg16= pcii_wreg16;
-       pcibus[busind].pb_wreg32= pcii_wreg32;
-       pcibus[busind].pb_rsts= pcii_rsts;
-       pcibus[busind].pb_wsts= pcii_wsts;
-
-       dstr= pci_dev_name(vid, did);
-       if (!dstr)
-               dstr= "unknown device";
-       if (debug)
+       freebus= 1;
+       for (i= 0; i<nr_pcibus; i++)
        {
-               printf("pci_intel_init: %s (%04X:%04X)\n",
-                       dstr, vid, did);
+               if (pcibus[i].pb_needinit)
+                       continue;
+               if (pcibus[i].pb_type == PBT_INTEL_HOST)
+                       continue;
+               if (pcibus[i].pb_busnr <= freebus)
+                       freebus= pcibus[i].pb_busnr+1;
+               printf("get_freebus: should check suboridinate bus number\n");
        }
+       return freebus;
+}
 
-       probe_bus(busind);
+static const char *
+pci_vid_name(u16_t vid)
+{
+       int i;
 
-       r= do_isabridge(busind);
-       if (r != OK)
+       for (i= 0; pci_vendor_table[i].name; i++)
        {
-               busnr= pcibus[busind].pb_busnr;
-
-               /* Disable all devices for this bus */
-               for (i= 0; i<nr_pcidev; i++)
-               {
-                       if (pcidev[i].pd_busnr != busnr)
-                               continue;
-                       pcidev[i].pd_inuse= 1;
-               }
-               return;
+               if (pci_vendor_table[i].vid == vid)
+                       return pci_vendor_table[i].name;
        }
+       return "unknown";
+}
 
-       /* Look for PCI bridges */
-       do_pcibridge(busind);
 
-       /* Allocate bus numbers for uninitialized bridges */
-       complete_bridges();
+static const char *
+pci_baseclass_name(u8_t baseclass)
+{
+       int i;
 
-       /* Allocate I/O and memory resources for uninitialized devices */
-       complete_bars();
+       for (i= 0; pci_baseclass_table[i].name; i++)
+       {
+               if (pci_baseclass_table[i].baseclass == baseclass)
+                       return pci_baseclass_table[i].name;
+       }
+       return NULL;
 }
 
-/*===========================================================================*
- *                             probe_bus                                    *
- *===========================================================================*/
-static void probe_bus(int busind)
+static const char *
+pci_subclass_name(u8_t baseclass, u8_t subclass, u8_t infclass)
 {
-       u32_t dev, func, t3;
-       u16_t vid, did, sts, sub_vid, sub_did;
-       u8_t headt;
-       u8_t baseclass, subclass, infclass;
-       int devind, busnr;
-       char *s, *dstr;
-
-       if (debug)
-               printf("probe_bus(%d)\n", busind);
-       if (nr_pcidev >= NR_PCIDEV)
-               panic("too many PCI devices: %d", nr_pcidev);
-       devind= nr_pcidev;
+       int i;
 
-       busnr= pcibus[busind].pb_busnr;
-       for (dev= 0; dev<32; dev++)
+       for (i= 0; pci_subclass_table[i].name; i++)
        {
-
-               for (func= 0; func < 8; func++)
+               if (pci_subclass_table[i].baseclass != baseclass)
+                       continue;
+               if (pci_subclass_table[i].subclass != subclass)
+                       continue;
+               if (pci_subclass_table[i].infclass != infclass &&
+                       pci_subclass_table[i].infclass != (u16_t)-1)
                {
-                       pcidev[devind].pd_busnr= busnr;
-                       pcidev[devind].pd_dev= dev;
-                       pcidev[devind].pd_func= func;
+                       continue;
+               }
+               return pci_subclass_table[i].name;
+       }
+       return NULL;
+}
 
-                       pci_attr_wsts(devind, 
-                               PSR_SSE|PSR_RMAS|PSR_RTAS);
-                       vid= pci_attr_r16(devind, PCI_VID);
-                       did= pci_attr_r16(devind, PCI_DID);
-                       headt= pci_attr_r8_u(devind, PCI_HEADT);
-                       sts= pci_attr_rsts(devind);
+static void
+print_hyper_cap(int devind, u8_t capptr)
+{
+       u32_t v;
+       u16_t cmd;
+       int type0, type1;
 
+       printf("\n");
+       v= __pci_attr_r32(devind, capptr);
+       printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr);
+       cmd= (v >> 16) & 0xffff;
 #if 0
-                       printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
-                               vid, did, headt, sts);
+       if (v & 0x10000)
+       {
+               printf(" WarmReset");
+               v &= ~0x10000;
+       }
+       if (v & 0x20000)
+       {
+               printf(" DblEnded");
+               v &= ~0x20000;
+       }
+       printf(" DevNum %d", (v & 0x7C0000) >> 18);
+       v &= ~0x7C0000;
 #endif
+       type0= (cmd & 0xE000) >> 13;
+       type1= (cmd & 0xF800) >> 11;
+       if (type0 == 0 || type0 == 1)
+       {
+               printf("Capability Type: %s\n",
+                       type0 == 0 ? "Slave or Primary Interface" :
+                       "Host or Secondary Interface");
+               cmd &= ~0xE000;
+       }
+       else
+       {
+               printf(" Capability Type 0x%x", type1);
+               cmd &= ~0xF800;
+       }
+       if (cmd)
+               printf(" undecoded 0x%x\n", cmd);
 
-                       if (vid == NO_VID && did == NO_VID)
-                       {
-                               if (func == 0)
-                                       break;  /* Nothing here */
-
-                               /* Scan all functions of a multifunction
-                                * device.
-                                */
-                               continue;
-                       }
-
-                       if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
-                       {
-                           static int warned = 0;
-
-                           if(!warned) {
-                               printf(
-                                       "PCI: ignoring bad value 0x%x in sts for QEMU\n",
-                                       sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
-                               warned = 1;
-                           }
-                       }
-
-                       sub_vid= pci_attr_r16(devind, PCI_SUBVID);
-                       sub_did= pci_attr_r16(devind, PCI_SUBDID);
+#if 0
+       printf("print_hyper_cap: off 4 (ctl): 0x%x\n",
+               __pci_attr_r32(devind, capptr+4));
+       printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n",
+               __pci_attr_r32(devind, capptr+8));
+       printf("print_hyper_cap: off 12 (cap): 0x%x\n",
+               __pci_attr_r32(devind, capptr+12));
+       printf("print_hyper_cap: off 16 (buf count): 0x%x\n",
+               __pci_attr_r32(devind, capptr+16));
+       v= __pci_attr_r32(devind, capptr+20);
+       printf("print_hyper_cap: @0x%x, off 20 (bus nr): ",
+               capptr+20);
+       printf("prim %d", v & 0xff);
+       printf(", sec %d", (v >> 8) & 0xff);
+       printf(", sub %d", (v >> 16) & 0xff);
+       if (v >> 24)
+               printf(", reserved %d", (v >> 24) & 0xff);
+       printf("\n");
+       printf("print_hyper_cap: off 24 (type): 0x%x\n",
+               __pci_attr_r32(devind, capptr+24));
+#endif
+}
 
-                       dstr= pci_dev_name(vid, did);
-                       if (debug)
-                       {
-                               if (dstr)
-                               {
-                                       printf("%d.%lu.%lu: %s (%04X:%04X)\n",
-                                               busnr, (unsigned long)dev,
-                                               (unsigned long)func, dstr,
-                                               vid, did);
-                               }
-                               else
-                               {
-                                       printf(
-               "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
-                                               busnr, (unsigned long)dev,
-                                               (unsigned long)func, vid,
-                                               pci_vid_name(vid), did);
-                               }
-                               printf("Device index: %d\n", devind);
-                               printf("Subsystem: Vid 0x%x, did 0x%x\n",
-                                       sub_vid, sub_did);
-                       }
+static void
+print_capabilities(int devind)
+{
+       u8_t status, capptr, type, next, subtype;
+       const char *str;
 
-                       baseclass= pci_attr_r8_u(devind, PCI_BCR);
-                       subclass= pci_attr_r8_u(devind, PCI_SCR);
-                       infclass= pci_attr_r8_u(devind, PCI_PIFR);
-                       s= pci_subclass_name(baseclass, subclass, infclass);
-                       if (!s)
-                               s= pci_baseclass_name(baseclass);
-                       {
-                               if (!s)
-                                       s= "(unknown class)";
-                       }
-                       if (debug)
-                       {
-                               printf("\tclass %s (%X/%X/%X)\n", s,
-                                       baseclass, subclass, infclass);
-                       }
+       /* Check capabilities bit in the device status register */
+       status= __pci_attr_r16(devind, PCI_SR);
+       if (!(status & PSR_CAPPTR))
+               return;
 
-                       if (is_duplicate(busnr, dev, func))
-                       {
-                               printf("\tduplicate!\n");
-                               if (func == 0 && !(headt & PHT_MULTIFUNC))
-                                       break;
-                               continue;
-                       }
+       capptr= (__pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK);
+       while (capptr != 0)
+       {
+               type = __pci_attr_r8(devind, capptr+CAP_TYPE);
+               next= (__pci_attr_r8(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
+               switch(type)
+               {
+               case 1: str= "PCI Power Management"; break;
+               case 2: str= "AGP"; break;
+               case 3: str= "Vital Product Data"; break;
+               case 4: str= "Slot Identification"; break;
+               case 5: str= "Message Signaled Interrupts"; break;
+               case 6: str= "CompactPCI Hot Swap"; break;
+               case 8: str= "AMD HyperTransport"; break;
+               case 0xf: str= "Secure Device"; break;
+               default: str= "(unknown type)"; break;
+               }
 
-                       devind= nr_pcidev;
-                       nr_pcidev++;
-                       pcidev[devind].pd_baseclass= baseclass;
-                       pcidev[devind].pd_subclass= subclass;
-                       pcidev[devind].pd_infclass= infclass;
-                       pcidev[devind].pd_vid= vid;
-                       pcidev[devind].pd_did= did;
-                       pcidev[devind].pd_sub_vid= sub_vid;
-                       pcidev[devind].pd_sub_did= sub_did;
-                       pcidev[devind].pd_inuse= 0;
-                       pcidev[devind].pd_bar_nr= 0;
-                       record_irq(devind);
-                       switch(headt & PHT_MASK)
+               printf(" @0x%x (0x%08x): capability type 0x%x: %s",
+                       capptr, __pci_attr_r32(devind, capptr), type, str);
+               if (type == 0x08)
+                       print_hyper_cap(devind, capptr);
+               else if (type == 0x0f)
+               {
+                       subtype= (__pci_attr_r8(devind, capptr+2) & 0x07);
+                       switch(subtype)
                        {
-                       case PHT_NORMAL:
-                               record_bars_normal(devind);
-                               break;
-                       case PHT_BRIDGE:
-                               record_bars_bridge(devind);
-                               break;
-                       case PHT_CARDBUS:
-                               record_bars_cardbus(devind);
-                               break;
-                       default:
-                               printf("\t%d.%d.%d: unknown header type %d\n",
-                                       busind, dev, func,
-                                       headt & PHT_MASK);
-                               break;
+                       case 0: str= "Device Exclusion Vector"; break;
+                       case 3: str= "IOMMU"; break;
+                       default: str= "(unknown type)"; break;
                        }
-                       if (debug)
-                               print_capabilities(devind);
-
-                       t3= ((baseclass << 16) | (subclass << 8) | infclass);
-#if 0
-                       if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD)
-                               report_vga(devind);
-#endif
-
-                       if (nr_pcidev >= NR_PCIDEV)
-                         panic("too many PCI devices: %d", nr_pcidev);
-                       devind= nr_pcidev;
-
-                       if (func == 0 && !(headt & PHT_MULTIFUNC))
-                               break;
+                       printf(", sub type 0%o: %s", subtype, str);
                }
+               printf("\n");
+               capptr= next;
        }
 }
 
 /*===========================================================================*
- *                             is_duplicate                                 *
+ *                             ISA Bridge Helpers                           *
  *===========================================================================*/
-static int is_duplicate(u8_t busnr, u8_t dev, u8_t func)
+static void
+update_bridge4dev_io(int devind, u32_t io_base, u32_t io_size)
 {
-       int i;
+       int busnr, busind, type, br_devind;
+       u16_t v16;
 
-       for (i= 0; i<nr_pcidev; i++)
+       busnr= pcidev[devind].pd_busnr;
+       busind= get_busind(busnr);
+       type= pcibus[busind].pb_type;
+       if (type == PBT_INTEL_HOST)
+               return; /* Nothing to do for host controller */
+       if (type == PBT_PCIBRIDGE)
        {
-               if (pcidev[i].pd_busnr == busnr &&
-                       pcidev[i].pd_dev == dev &&
-                       pcidev[i].pd_func == func)
-               {
-                       return 1;
-               }
+               printf(
+               "update_bridge4dev_io: not implemented for PCI bridges\n");
+               return;
        }
-       return 0;
-}
-
-static int acpi_get_irq(unsigned bus, unsigned dev, unsigned pin)
-{
-       int err;
-       message m;
-
-       ((struct acpi_get_irq_req *)&m)->hdr.request = ACPI_REQ_GET_IRQ;
-       ((struct acpi_get_irq_req *)&m)->bus = bus;
-       ((struct acpi_get_irq_req *)&m)->dev = dev;
-       ((struct acpi_get_irq_req *)&m)->pin = pin;
-
-       if ((err = ipc_sendrec(acpi_ep, &m)) != OK)
-               panic("PCI: error %d while receiveing from ACPI\n", err);
-
-       return ((struct acpi_get_irq_resp *)&m)->irq;
-}
-
-static int derive_irq(struct pcidev * dev, int pin)
-{
-       struct pcidev * parent_bridge;
-       int slot;
-       
-       parent_bridge = &pcidev[pcibus[get_busind(dev->pd_busnr)].pb_devind];
+       if (type != PBT_CARDBUS)
+               panic("update_bridge4dev_io: strange bus type: %d", type);
 
-       /*
-        * We don't support PCI-Express, no ARI, decode the slot of the device
-        * and mangle the pin as the device is behind a bridge
-        */
-       slot = ((dev->pd_func) >> 3) & 0x1f;
+       if (debug)
+       {
+               printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
+                       io_size, io_base);
+       }
+       br_devind= pcibus[busind].pb_devind;
+       __pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1);
+       __pci_attr_w32(br_devind, CBB_IOBASE_0, io_base);
 
-       return acpi_get_irq(parent_bridge->pd_busnr,
-                       parent_bridge->pd_dev, (pin + slot) % 4);
+       /* Enable I/O access. Enable busmaster access as well. */
+       v16= __pci_attr_r16(devind, PCI_CR);
+       __pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN);
 }
 
-/*===========================================================================*
- *                             record_irq                                   *
- *===========================================================================*/
-static void record_irq(devind)
-int devind;
+static int
+do_piix(int devind)
 {
-       int ilr, ipr, busnr, busind, cb_devind;
-
-       ilr= pci_attr_r8_u(devind, PCI_ILR);
-       ipr= pci_attr_r8_u(devind, PCI_IPR);
-
-       if (ipr && machine.apic_enabled) {
-               int irq;
-
-               irq = acpi_get_irq(pcidev[devind].pd_busnr,
-                               pcidev[devind].pd_dev, ipr - 1);
-
-               if (irq < 0)
-                       irq = derive_irq(&pcidev[devind], ipr - 1);
-
-               if (irq >= 0) {
-                       ilr = irq;
-                       pci_attr_w8(devind, PCI_ILR, ilr);
-                       if (debug)
-                               printf("PCI: ACPI IRQ %d for "
-                                               "device %d.%d.%d INT%c\n",
-                                               irq,
-                                               pcidev[devind].pd_busnr,
-                                               pcidev[devind].pd_dev,
-                                               pcidev[devind].pd_func,
-                                               'A' + ipr-1);
-               }
-               else if (debug) {
-                       printf("PCI: no ACPI IRQ routing for "
-                                       "device %d.%d.%d INT%c\n",
-                                       pcidev[devind].pd_busnr,
-                                       pcidev[devind].pd_dev,
-                                       pcidev[devind].pd_func,
-                                       'A' + ipr-1);
-               }
-       }
+       int i, s, irqrc, irq;
+       u32_t elcr1, elcr2, elcr;
 
-       if (ilr == 0)
+#if DEBUG
+       printf("in piix\n");
+#endif
+       if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
+               printf("Warning, sys_inb failed: %d\n", s);
+       if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
+               printf("Warning, sys_inb failed: %d\n", s);
+       elcr= elcr1 | (elcr2 << 8);
+       for (i= 0; i<4; i++)
        {
-               static int first= 1;
-               if (ipr && first && debug)
+               irqrc= __pci_attr_r8(devind, PIIX_PIRQRCA+i);
+               if (irqrc & PIIX_IRQ_DI)
                {
-                       first= 0;
-                       printf("PCI: strange, BIOS assigned IRQ0\n");
+                       if (debug)
+                               printf("INT%c: disabled\n", 'A'+i);
                }
-               ilr= PCI_ILR_UNKNOWN;
-       }
-       pcidev[devind].pd_ilr= ilr;
-       if (ilr == PCI_ILR_UNKNOWN && !ipr)
-       {
-       }
-       else if (ilr != PCI_ILR_UNKNOWN && ipr)
-       {
-               if (debug)
-                       printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
-       }
-       else if (ilr != PCI_ILR_UNKNOWN)
-       {
-               printf(
-       "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
-                       ilr, pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
-                       pcidev[devind].pd_func);
-       }
-       else
-       {
-               /* Check for cardbus devices */
-               busnr= pcidev[devind].pd_busnr;
-               busind= get_busind(busnr);
-               if (pcibus[busind].pb_type == PBT_CARDBUS)
+               else
                {
-                       cb_devind= pcibus[busind].pb_devind;
-                       ilr= pcidev[cb_devind].pd_ilr;
-                       if (ilr != PCI_ILR_UNKNOWN)
+                       irq= irqrc & PIIX_IRQ_MASK;
+                       if (debug)
+                               printf("INT%c: %d\n", 'A'+i, irq);
+                       if (!(elcr & (1 << irq)))
                        {
                                if (debug)
                                {
                                        printf(
-                                       "assigning IRQ %d to Cardbus device\n",
-                                               ilr);
+                               "(warning) IRQ %d is not level triggered\n",
+                                               irq);
                                }
-                               pci_attr_w8(devind, PCI_ILR, ilr);
-                               pcidev[devind].pd_ilr= ilr;
-                               return;
                        }
-               }
-               if(debug) {
-                       printf(
-               "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
-                       pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
-                       pcidev[devind].pd_func, 'A' + ipr-1);
+                       irq_mode_pci(irq);
                }
        }
+       return 0;
 }
 
-/*===========================================================================*
- *                             record_bars_normal                           *
- *===========================================================================*/
-static void record_bars_normal(devind)
-int devind;
+static int
+do_amd_isabr(int devind)
 {
-       int i, j, clear_01, clear_23, pb_nr;
+       int i, busnr, dev, func, xdevind, irq, edge;
+       u8_t levmask;
+       u16_t pciirq;
 
-       /* The BAR area of normal devices is six DWORDs in size. */
-       record_bars(devind, PCI_BAR_6);
+       /* Find required function */
+       func= AMD_ISABR_FUNC;
+       busnr= pcidev[devind].pd_busnr;
+       dev= pcidev[devind].pd_dev;
 
-       /* Special case code for IDE controllers in compatibility mode */
-       if (pcidev[devind].pd_baseclass == PCI_BCR_MASS_STORAGE &&
-               pcidev[devind].pd_subclass == PCI_MS_IDE)
+       /* Fake a device with the required function */
+       if (nr_pcidev >= NR_PCIDEV)
+               panic("too many PCI devices: %d", nr_pcidev);
+       xdevind= nr_pcidev;
+       pcidev[xdevind].pd_busnr= busnr;
+       pcidev[xdevind].pd_dev= dev;
+       pcidev[xdevind].pd_func= func;
+       pcidev[xdevind].pd_inuse= 1;
+       nr_pcidev++;
+
+       levmask= __pci_attr_r8(xdevind, AMD_ISABR_PCIIRQ_LEV);
+       pciirq= __pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
+       for (i= 0; i<4; i++)
        {
-               /* IDE device */
-               clear_01= 0;
-               clear_23= 0;
-               if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
+               edge= (levmask >> i) & 1;
+               irq= (pciirq >> (4*i)) & 0xf;
+               if (!irq)
                {
                        if (debug)
-                       {
-                               printf(
-       "primary channel is not in native mode, clearing BARs 0 and 1\n");
-                       }
-                       clear_01= 1;
+                               printf("INT%c: disabled\n", 'A'+i);
                }
-               if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
+               else
                {
                        if (debug)
+                               printf("INT%c: %d\n", 'A'+i, irq);
+                       if (edge && debug)
                        {
                                printf(
-       "secondary channel is not in native mode, clearing BARs 2 and 3\n");
+                               "(warning) IRQ %d is not level triggered\n",
+                                       irq);
                        }
-                       clear_23= 1;
+                       irq_mode_pci(irq);
                }
+       }
+       nr_pcidev--;
+       return 0;
+}
 
-               j= 0;
-               for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
+static int
+do_sis_isabr(int devind)
+{
+       int i, irq;
+
+       irq= 0; /* lint */
+       for (i= 0; i<4; i++)
+       {
+               irq= __pci_attr_r8(devind, SIS_ISABR_IRQ_A+i);
+               if (irq & SIS_IRQ_DISABLED)
                {
-                       pb_nr= pcidev[devind].pd_bar[i].pb_nr;
-                       if ((pb_nr == 0 || pb_nr == 1) && clear_01)
-                       {
-                               if (debug) printf("skipping bar %d\n", pb_nr);
-                               continue;       /* Skip */
-                       }
-                       if ((pb_nr == 2 || pb_nr == 3) && clear_23)
-                       {
-                               if (debug) printf("skipping bar %d\n", pb_nr);
-                               continue;       /* Skip */
-                       }
-                       if (i == j)
+                       if (debug)
+                               printf("INT%c: disabled\n", 'A'+i);
+               }
+               else
+               {
+                       irq &= SIS_IRQ_MASK;
+                       if (debug)
+                               printf("INT%c: %d\n", 'A'+i, irq);
+                       irq_mode_pci(irq);
+               }
+       }
+       return 0;
+}
+
+static int
+do_via_isabr(int devind)
+{
+       int i, irq, edge;
+       u8_t levmask;
+
+       levmask= __pci_attr_r8(devind, VIA_ISABR_EL);
+       irq= 0; /* lint */
+       edge= 0; /* lint */
+       for (i= 0; i<4; i++)
+       {
+               switch(i)
+               {
+               case 0:
+                       edge= (levmask & VIA_ISABR_EL_INTA);
+                       irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R2) >> 4;
+                       break;
+               case 1:
+                       edge= (levmask & VIA_ISABR_EL_INTB);
+                       irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R2);
+                       break;
+               case 2:
+                       edge= (levmask & VIA_ISABR_EL_INTC);
+                       irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R3) >> 4;
+                       break;
+               case 3:
+                       edge= (levmask & VIA_ISABR_EL_INTD);
+                       irq= __pci_attr_r8(devind, VIA_ISABR_IRQ_R1) >> 4;
+                       break;
+               default:
+                       panic("PCI: VIA ISA Bridge IRQ Detection Failed");
+               }
+               irq &= 0xf;
+               if (!irq)
+               {
+                       if (debug)
+                               printf("INT%c: disabled\n", 'A'+i);
+               }
+               else
+               {
+                       if (debug)
+                               printf("INT%c: %d\n", 'A'+i, irq);
+                       if (edge && debug)
                        {
-                               j++;
-                               continue;       /* No need to copy */
+                               printf(
+                               "(warning) IRQ %d is not level triggered\n",
+                                       irq);
                        }
-                       pcidev[devind].pd_bar[j]=
-                               pcidev[devind].pd_bar[i];
-                       j++;
+                       irq_mode_pci(irq);
                }
-               pcidev[devind].pd_bar_nr= j;
        }
+       return 0;
 }
 
-/*===========================================================================*
- *                             record_bars_bridge                           *
- *===========================================================================*/
-static void record_bars_bridge(devind)
-int devind;
+static int
+do_isabridge(int busind)
 {
-       u32_t base, limit, size;
-
-       /* The generic BAR area of PCI-to-PCI bridges is two DWORDs in size.
-        * It may contain up to two 32-bit BARs, or one 64-bit BAR.
-        */
-       record_bars(devind, PCI_BAR_2);
+       int i, j, r, type, busnr, unknown_bridge, bridge_dev;
+       u16_t vid, did;
+       u32_t t3;
+       const char *dstr;
 
-       base= ((pci_attr_r8_u(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) |
-               (pci_attr_r16(devind, PPB_IOBASEU16) << 16);
-       limit= 0xff |
-               ((pci_attr_r8_u(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) |
-               ((~PPB_IOL_MASK & 0xff) << 8) |
-               (pci_attr_r16(devind, PPB_IOLIMITU16) << 16);
-       size= limit-base + 1;
-       if (debug)
+       unknown_bridge= -1;
+       bridge_dev= -1;
+       j= 0;   /* lint */
+       vid= did= 0;    /* lint */
+       busnr= pcibus[busind].pb_busnr;
+       for (i= 0; i< nr_pcidev; i++)
        {
-               printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
-                       base, limit, size);
+               if (pcidev[i].pd_busnr != busnr)
+                       continue;
+               t3= ((pcidev[i].pd_baseclass << 16) |
+                       (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass);
+               if (t3 == PCI_T3_ISA)
+               {
+                       /* ISA bridge. Report if no supported bridge is
+                        * found.
+                        */
+                       unknown_bridge= i;
+               }
+
+               vid= pcidev[i].pd_vid;
+               did= pcidev[i].pd_did;
+               for (j= 0; pci_isabridge[j].vid != 0; j++)
+               {
+                       if (pci_isabridge[j].vid != vid)
+                               continue;
+                       if (pci_isabridge[j].did != did)
+                               continue;
+                       if (pci_isabridge[j].checkclass &&
+                               unknown_bridge != i)
+                       {
+                               /* This part of multifunction device is
+                                * not the bridge.
+                                */
+                               continue;
+                       }
+                       break;
+               }
+               if (pci_isabridge[j].vid)
+               {
+                       bridge_dev= i;
+                       break;
+               }
        }
 
-       base= ((pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16);
-       limit= 0xffff |
-               ((pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) |
-               ((~PPB_MEML_MASK & 0xffff) << 16);
-       size= limit-base + 1;
-       if (debug)
+       if (bridge_dev != -1)
        {
-               printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
-                       base, limit, size);
+               dstr= _pci_dev_name(vid, did);
+               if (!dstr)
+                       dstr= "unknown device";
+               if (debug)
+               {
+                       printf("found ISA bridge (%04X:%04X) %s\n",
+                               vid, did, dstr);
+               }
+               pcibus[busind].pb_isabridge_dev= bridge_dev;
+               type= pci_isabridge[j].type;
+               pcibus[busind].pb_isabridge_type= type;
+               switch(type)
+               {
+               case PCI_IB_PIIX:
+                       r= do_piix(bridge_dev);
+                       break;
+               case PCI_IB_VIA:
+                       r= do_via_isabr(bridge_dev);
+                       break;
+               case PCI_IB_AMD:
+                       r= do_amd_isabr(bridge_dev);
+                       break;
+               case PCI_IB_SIS:
+                       r= do_sis_isabr(bridge_dev);
+                       break;
+               default:
+                       panic("unknown ISA bridge type: %d", type);
+               }
+               return r;
        }
 
-       /* Ignore the upper 32 bits */
-       base= ((pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16);
-       limit= 0xffff |
-               ((pci_attr_r16(devind, PPB_PFMEMLIMIT) &
-                       PPB_PFMEML_MASK) << 16) |
-               ((~PPB_PFMEML_MASK & 0xffff) << 16);
-       size= limit-base + 1;
+       if (unknown_bridge == -1)
+       {
+               if (debug)
+               {
+                       printf("(warning) no ISA bridge found on bus %d\n",
+                               busind);
+               }
+               return 0;
+       }
        if (debug)
        {
                printf(
-       "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
-                       base, limit, size);
+               "(warning) unsupported ISA bridge %04X:%04X for bus %d\n",
+                       pcidev[unknown_bridge].pd_vid,
+                       pcidev[unknown_bridge].pd_did, busind);
        }
+       return 0;
 }
 
 /*===========================================================================*
- *                             record_bars_cardbus                          *
+ *                             IRQ handling                                 *
  *===========================================================================*/
-static void record_bars_cardbus(devind)
-int devind;
+static int
+acpi_get_irq(unsigned bus, unsigned dev, unsigned pin)
 {
-       u32_t base, limit, size;
+       int err;
+       message m;
 
-       /* The generic BAR area of CardBus devices is one DWORD in size. */
-       record_bars(devind, PCI_BAR);
+       ((struct acpi_get_irq_req *)&m)->hdr.request = ACPI_REQ_GET_IRQ;
+       ((struct acpi_get_irq_req *)&m)->bus = bus;
+       ((struct acpi_get_irq_req *)&m)->dev = dev;
+       ((struct acpi_get_irq_req *)&m)->pin = pin;
 
-       base= pci_attr_r32_u(devind, CBB_MEMBASE_0);
-       limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_0) |
-               (~CBB_MEML_MASK & 0xffffffff);
-       size= limit-base + 1;
-       if (debug)
-       {
-               printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
-                       base, limit, size);
+       if ((err = ipc_sendrec(acpi_ep, &m)) != OK)
+               panic("PCI: error %d while receiveing from ACPI\n", err);
+
+       return ((struct acpi_get_irq_resp *)&m)->irq;
+}
+
+static int
+derive_irq(struct pcidev * dev, int pin)
+{
+       struct pcidev * parent_bridge;
+       int slot;
+
+       parent_bridge = &pcidev[pcibus[get_busind(dev->pd_busnr)].pb_devind];
+
+       /*
+        * We don't support PCI-Express, no ARI, decode the slot of the device
+        * and mangle the pin as the device is behind a bridge
+        */
+       slot = ((dev->pd_func) >> 3) & 0x1f;
+
+       return acpi_get_irq(parent_bridge->pd_busnr,
+                       parent_bridge->pd_dev, (pin + slot) % 4);
+}
+
+static void
+record_irq(int devind)
+{
+       int ilr, ipr, busnr, busind, cb_devind;
+
+       ilr= __pci_attr_r8(devind, PCI_ILR);
+       ipr= __pci_attr_r8(devind, PCI_IPR);
+
+       if (ipr && machine.apic_enabled) {
+               int irq;
+
+               irq = acpi_get_irq(pcidev[devind].pd_busnr,
+                               pcidev[devind].pd_dev, ipr - 1);
+
+               if (irq < 0)
+                       irq = derive_irq(&pcidev[devind], ipr - 1);
+
+               if (irq >= 0) {
+                       ilr = irq;
+                       __pci_attr_w8(devind, PCI_ILR, ilr);
+                       if (debug)
+                               printf("PCI: ACPI IRQ %d for "
+                                               "device %d.%d.%d INT%c\n",
+                                               irq,
+                                               pcidev[devind].pd_busnr,
+                                               pcidev[devind].pd_dev,
+                                               pcidev[devind].pd_func,
+                                               'A' + ipr-1);
+               }
+               else if (debug) {
+                       printf("PCI: no ACPI IRQ routing for "
+                                       "device %d.%d.%d INT%c\n",
+                                       pcidev[devind].pd_busnr,
+                                       pcidev[devind].pd_dev,
+                                       pcidev[devind].pd_func,
+                                       'A' + ipr-1);
+               }
        }
 
-       base= pci_attr_r32_u(devind, CBB_MEMBASE_1);
-       limit= pci_attr_r32_u(devind, CBB_MEMLIMIT_1) |
-               (~CBB_MEML_MASK & 0xffffffff);
-       size= limit-base + 1;
-       if (debug)
+       if (ilr == 0)
        {
-               printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
-                       base, limit, size);
+               static int first= 1;
+               if (ipr && first && debug)
+               {
+                       first= 0;
+                       printf("PCI: strange, BIOS assigned IRQ0\n");
+               }
+               ilr= PCI_ILR_UNKNOWN;
        }
-
-       base= pci_attr_r32_u(devind, CBB_IOBASE_0);
-       limit= pci_attr_r32_u(devind, CBB_IOLIMIT_0) |
-               (~CBB_IOL_MASK & 0xffffffff);
-       size= limit-base + 1;
-       if (debug)
+       pcidev[devind].pd_ilr= ilr;
+       if (ilr == PCI_ILR_UNKNOWN && !ipr)
        {
-               printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
-                       base, limit, size);
        }
-
-       base= pci_attr_r32_u(devind, CBB_IOBASE_1);
-       limit= pci_attr_r32_u(devind, CBB_IOLIMIT_1) |
-               (~CBB_IOL_MASK & 0xffffffff);
-       size= limit-base + 1;
-       if (debug)
+       else if (ilr != PCI_ILR_UNKNOWN && ipr)
        {
-               printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
-                       base, limit, size);
+               if (debug)
+                       printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
        }
-}
-
-/*===========================================================================*
- *                             record_bars                                  *
- *===========================================================================*/
-static void record_bars(int devind, int last_reg)
-{
-       int i, reg, width;
-
-       for (i= 0, reg= PCI_BAR; reg <= last_reg; i += width, reg += 4 * width)
+       else if (ilr != PCI_ILR_UNKNOWN)
        {
-               width = record_bar(devind, i, reg == last_reg);
+               printf(
+       "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
+                       ilr, pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
+                       pcidev[devind].pd_func);
+       }
+       else
+       {
+               /* Check for cardbus devices */
+               busnr= pcidev[devind].pd_busnr;
+               busind= get_busind(busnr);
+               if (pcibus[busind].pb_type == PBT_CARDBUS)
+               {
+                       cb_devind= pcibus[busind].pb_devind;
+                       ilr= pcidev[cb_devind].pd_ilr;
+                       if (ilr != PCI_ILR_UNKNOWN)
+                       {
+                               if (debug)
+                               {
+                                       printf(
+                                       "assigning IRQ %d to Cardbus device\n",
+                                               ilr);
+                               }
+                               __pci_attr_w8(devind, PCI_ILR, ilr);
+                               pcidev[devind].pd_ilr= ilr;
+                               return;
+                       }
+               }
+               if(debug) {
+                       printf(
+               "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
+                       pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
+                       pcidev[devind].pd_func, 'A' + ipr-1);
+               }
        }
 }
 
 /*===========================================================================*
- *                             record_bar                                   *
+ *                             BAR helpers                                  *
  *===========================================================================*/
-static int record_bar(devind, bar_nr, last)
-int devind;
-int bar_nr;
-int last;
+static int
+record_bar(int devind, int bar_nr, int last)
 {
        int reg, prefetch, type, dev_bar_nr, width;
        u32_t bar, bar2;
@@ -1281,20 +1072,20 @@ int last;
 
        reg= PCI_BAR+4*bar_nr;
 
-       bar= pci_attr_r32_u(devind, reg);
+       bar= __pci_attr_r32(devind, reg);
        if (bar & PCI_BAR_IO)
        {
                /* Disable I/O access before probing for BAR's size */
-               cmd = pci_attr_r16(devind, PCI_CR);
-               pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_IO_EN);
+               cmd = __pci_attr_r16(devind, PCI_CR);
+               __pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_IO_EN);
 
                /* Probe BAR's size */
-               pci_attr_w32(devind, reg, 0xffffffff);
-               bar2= pci_attr_r32_u(devind, reg);
+               __pci_attr_w32(devind, reg, 0xffffffff);
+               bar2= __pci_attr_r32(devind, reg);
 
                /* Restore original state */
-               pci_attr_w32(devind, reg, bar);
-               pci_attr_w16(devind, PCI_CR, cmd);
+               __pci_attr_w32(devind, reg, bar);
+               __pci_attr_w16(devind, PCI_CR, cmd);
 
                bar &= PCI_BAR_IO_MASK;         /* Clear non-address bits */
                bar2 &= PCI_BAR_IO_MASK;
@@ -1312,7 +1103,7 @@ int last;
                pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
                if (bar == 0)
                {
-                       pcidev[devind].pd_bar[dev_bar_nr].pb_flags |= 
+                       pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
                                PBF_INCOMPLETE;
                }
        }
@@ -1339,7 +1130,7 @@ int last;
                        }
                        width++;
 
-                       bar2= pci_attr_r32_u(devind, reg+4);
+                       bar2= __pci_attr_r32(devind, reg+4);
 
                        /* If the upper 32 bits of the BAR are not zero, the
                         * memory is inaccessible to us; ignore the BAR.
@@ -1369,16 +1160,16 @@ int last;
                }
 
                /* Disable mem access before probing for BAR's size */
-               cmd = pci_attr_r16(devind, PCI_CR);
-               pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_MEM_EN);
+               cmd = __pci_attr_r16(devind, PCI_CR);
+               __pci_attr_w16(devind, PCI_CR, cmd & ~PCI_CR_MEM_EN);
 
                /* Probe BAR's size */
-               pci_attr_w32(devind, reg, 0xffffffff);
-               bar2= pci_attr_r32_u(devind, reg);
+               __pci_attr_w32(devind, reg, 0xffffffff);
+               bar2= __pci_attr_r32(devind, reg);
 
                /* Restore original values */
-               pci_attr_w32(devind, reg, bar);
-               pci_attr_w16(devind, PCI_CR, cmd);
+               __pci_attr_w32(devind, reg, bar);
+               __pci_attr_w16(devind, PCI_CR, cmd);
 
                if (bar2 == 0)
                        return width;   /* Reg. is not implemented */
@@ -1402,59 +1193,186 @@ int last;
                pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
                if (bar == 0)
                {
-                       pcidev[devind].pd_bar[dev_bar_nr].pb_flags |= 
+                       pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
                                PBF_INCOMPLETE;
                }
        }
-
-       return width;
+
+       return width;
+}
+
+static void
+record_bars(int devind, int last_reg)
+{
+       int i, reg, width;
+
+       for (i= 0, reg= PCI_BAR; reg <= last_reg; i += width, reg += 4 * width)
+       {
+               width = record_bar(devind, i, reg == last_reg);
+       }
+}
+
+static void
+record_bars_normal(int devind)
+{
+       int i, j, clear_01, clear_23, pb_nr;
+
+       /* The BAR area of normal devices is six DWORDs in size. */
+       record_bars(devind, PCI_BAR_6);
+
+       /* Special case code for IDE controllers in compatibility mode */
+       if (pcidev[devind].pd_baseclass == PCI_BCR_MASS_STORAGE &&
+               pcidev[devind].pd_subclass == PCI_MS_IDE)
+       {
+               /* IDE device */
+               clear_01= 0;
+               clear_23= 0;
+               if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
+               {
+                       if (debug)
+                       {
+                               printf(
+       "primary channel is not in native mode, clearing BARs 0 and 1\n");
+                       }
+                       clear_01= 1;
+               }
+               if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
+               {
+                       if (debug)
+                       {
+                               printf(
+       "secondary channel is not in native mode, clearing BARs 2 and 3\n");
+                       }
+                       clear_23= 1;
+               }
+
+               j= 0;
+               for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
+               {
+                       pb_nr= pcidev[devind].pd_bar[i].pb_nr;
+                       if ((pb_nr == 0 || pb_nr == 1) && clear_01)
+                       {
+                               if (debug) printf("skipping bar %d\n", pb_nr);
+                               continue;       /* Skip */
+                       }
+                       if ((pb_nr == 2 || pb_nr == 3) && clear_23)
+                       {
+                               if (debug) printf("skipping bar %d\n", pb_nr);
+                               continue;       /* Skip */
+                       }
+                       if (i == j)
+                       {
+                               j++;
+                               continue;       /* No need to copy */
+                       }
+                       pcidev[devind].pd_bar[j]=
+                               pcidev[devind].pd_bar[i];
+                       j++;
+               }
+               pcidev[devind].pd_bar_nr= j;
+       }
+}
+
+static void
+record_bars_bridge(int devind)
+{
+       u32_t base, limit, size;
+
+       /* The generic BAR area of PCI-to-PCI bridges is two DWORDs in size.
+        * It may contain up to two 32-bit BARs, or one 64-bit BAR.
+        */
+       record_bars(devind, PCI_BAR_2);
+
+       base= ((__pci_attr_r8(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) |
+               (__pci_attr_r16(devind, PPB_IOBASEU16) << 16);
+       limit= 0xff |
+               ((__pci_attr_r8(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) |
+               ((~PPB_IOL_MASK & 0xff) << 8) |
+               (__pci_attr_r16(devind, PPB_IOLIMITU16) << 16);
+       size= limit-base + 1;
+       if (debug)
+       {
+               printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
+                       base, limit, size);
+       }
+
+       base= ((__pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16);
+       limit= 0xffff |
+               ((__pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) |
+               ((~PPB_MEML_MASK & 0xffff) << 16);
+       size= limit-base + 1;
+       if (debug)
+       {
+               printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
+                       base, limit, size);
+       }
+
+       /* Ignore the upper 32 bits */
+       base= ((__pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16);
+       limit= 0xffff |
+               ((__pci_attr_r16(devind, PPB_PFMEMLIMIT) &
+                       PPB_PFMEML_MASK) << 16) |
+               ((~PPB_PFMEML_MASK & 0xffff) << 16);
+       size= limit-base + 1;
+       if (debug)
+       {
+               printf(
+       "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
+                       base, limit, size);
+       }
 }
 
-/*===========================================================================*
- *                             complete_bridges                             *
- *===========================================================================*/
-static void complete_bridges()
+static void
+record_bars_cardbus(int devind)
 {
-       int i, freebus, devind, prim_busnr;
-
-       for (i= 0; i<nr_pcibus; i++)
-       {
-               if (!pcibus[i].pb_needinit)
-                       continue;
-               printf("should allocate bus number for bus %d\n", i);
-               freebus= get_freebus();
-               printf("got bus number %d\n", freebus);
-
-               devind= pcibus[i].pb_devind;
+       u32_t base, limit, size;
 
-               prim_busnr= pcidev[devind].pd_busnr;
-               if (prim_busnr != 0)
-               {
-                       printf(
-       "complete_bridge: updating subordinate bus number not implemented\n");
-               }
+       /* The generic BAR area of CardBus devices is one DWORD in size. */
+       record_bars(devind, PCI_BAR);
 
-               pcibus[i].pb_needinit= 0;
-               pcibus[i].pb_busnr= freebus;
+       base= __pci_attr_r32(devind, CBB_MEMBASE_0);
+       limit= __pci_attr_r32(devind, CBB_MEMLIMIT_0) |
+               (~CBB_MEML_MASK & 0xffffffff);
+       size= limit-base + 1;
+       if (debug)
+       {
+               printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
+                       base, limit, size);
+       }
 
-               printf("devind = %d\n", devind);
-               printf("prim_busnr= %d\n", prim_busnr);
+       base= __pci_attr_r32(devind, CBB_MEMBASE_1);
+       limit= __pci_attr_r32(devind, CBB_MEMLIMIT_1) |
+               (~CBB_MEML_MASK & 0xffffffff);
+       size= limit-base + 1;
+       if (debug)
+       {
+               printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
+                       base, limit, size);
+       }
 
-               pci_attr_w8(devind, PPB_PRIMBN, prim_busnr);
-               pci_attr_w8(devind, PPB_SECBN, freebus);
-               pci_attr_w8(devind, PPB_SUBORDBN, freebus);
+       base= __pci_attr_r32(devind, CBB_IOBASE_0);
+       limit= __pci_attr_r32(devind, CBB_IOLIMIT_0) |
+               (~CBB_IOL_MASK & 0xffffffff);
+       size= limit-base + 1;
+       if (debug)
+       {
+               printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
+                       base, limit, size);
+       }
 
-               printf("CR = 0x%x\n", pci_attr_r16(devind, PCI_CR));
-               printf("SECBLT = 0x%x\n", pci_attr_r8_u(devind, PPB_SECBLT));
-               printf("BRIDGECTRL = 0x%x\n",
-                       pci_attr_r16(devind, PPB_BRIDGECTRL));
+       base= __pci_attr_r32(devind, CBB_IOBASE_1);
+       limit= __pci_attr_r32(devind, CBB_IOLIMIT_1) |
+               (~CBB_IOL_MASK & 0xffffffff);
+       size= limit-base + 1;
+       if (debug)
+       {
+               printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
+                       base, limit, size);
        }
 }
 
-/*===========================================================================*
- *                             complete_bars                                *
- *===========================================================================*/
-static void complete_bars(void)
+static void
+complete_bars(void)
 {
        int i, j, bar_nr, reg;
        u32_t memgap_low, memgap_high, iogap_low, iogap_high, io_high,
@@ -1580,8 +1498,8 @@ static void complete_bars(void)
                        memgap_high= base;
                        bar_nr= pcidev[i].pd_bar[j].pb_nr;
                        reg= PCI_BAR + 4*bar_nr;
-                       v32= pci_attr_r32_u(i, reg);
-                       pci_attr_w32(i, reg, v32 | base);
+                       v32= __pci_attr_r32(i, reg);
+                       __pci_attr_w32(i, reg, v32 | base);
                        if (debug)
                        {
                                printf(
@@ -1616,8 +1534,8 @@ static void complete_bars(void)
                        iogap_high= base;
                        bar_nr= pcidev[i].pd_bar[j].pb_nr;
                        reg= PCI_BAR + 4*bar_nr;
-                       v32= pci_attr_r32_u(i, reg);
-                       pci_attr_w32(i, reg, v32 | base);
+                       v32= __pci_attr_r32(i, reg);
+                       __pci_attr_w32(i, reg, v32 | base);
                        if (debug)
                        {
                                printf(
@@ -1650,171 +1568,267 @@ static void complete_bars(void)
 }
 
 /*===========================================================================*
- *                             update_bridge4dev_io                         *
+ *                             PCI Bridge Helpers                           *
  *===========================================================================*/
-static void update_bridge4dev_io(
-  int devind,
-  u32_t io_base,
-  u32_t io_size
-)
+static void
+probe_bus(int busind)
 {
-       int busnr, busind, type, br_devind;
-       u16_t v16;
-
-       busnr= pcidev[devind].pd_busnr;
-       busind= get_busind(busnr);
-       type= pcibus[busind].pb_type;
-       if (type == PBT_INTEL_HOST)
-               return; /* Nothing to do for host controller */
-       if (type == PBT_PCIBRIDGE)
-       {
-               printf(
-               "update_bridge4dev_io: not implemented for PCI bridges\n");
-               return; 
-       }
-       if (type != PBT_CARDBUS)
-               panic("update_bridge4dev_io: strange bus type: %d", type);
+       u32_t dev, func, t3;
+       u16_t vid, did, sts, sub_vid, sub_did;
+       u8_t headt;
+       u8_t baseclass, subclass, infclass;
+       int devind, busnr;
+       const char *s, *dstr;
 
        if (debug)
+               printf("probe_bus(%d)\n", busind);
+       if (nr_pcidev >= NR_PCIDEV)
+               panic("too many PCI devices: %d", nr_pcidev);
+       devind= nr_pcidev;
+
+       busnr= pcibus[busind].pb_busnr;
+       for (dev= 0; dev<32; dev++)
        {
-               printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
-                       io_size, io_base);
+
+               for (func= 0; func < 8; func++)
+               {
+                       pcidev[devind].pd_busnr= busnr;
+                       pcidev[devind].pd_dev= dev;
+                       pcidev[devind].pd_func= func;
+
+                       pci_attr_wsts(devind,
+                               PSR_SSE|PSR_RMAS|PSR_RTAS);
+                       vid= __pci_attr_r16(devind, PCI_VID);
+                       did= __pci_attr_r16(devind, PCI_DID);
+                       headt= __pci_attr_r8(devind, PCI_HEADT);
+                       sts= pci_attr_rsts(devind);
+
+#if 0
+                       printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
+                               vid, did, headt, sts);
+#endif
+
+                       if (vid == NO_VID && did == NO_VID)
+                       {
+                               if (func == 0)
+                                       break;  /* Nothing here */
+
+                               /* Scan all functions of a multifunction
+                                * device.
+                                */
+                               continue;
+                       }
+
+                       if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
+                       {
+                               static int warned = 0;
+
+                               if(!warned) {
+                                       printf(
+       "PCI: ignoring bad value 0x%x in sts for QEMU\n",
+       sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
+                                       warned = 1;
+                               }
+                       }
+
+                       sub_vid= __pci_attr_r16(devind, PCI_SUBVID);
+                       sub_did= __pci_attr_r16(devind, PCI_SUBDID);
+
+                       dstr= _pci_dev_name(vid, did);
+                       if (debug)
+                       {
+                               if (dstr)
+                               {
+                                       printf("%d.%lu.%lu: %s (%04X:%04X)\n",
+                                               busnr, (unsigned long)dev,
+                                               (unsigned long)func, dstr,
+                                               vid, did);
+                               }
+                               else
+                               {
+                                       printf(
+               "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
+                                               busnr, (unsigned long)dev,
+                                               (unsigned long)func, vid,
+                                               pci_vid_name(vid), did);
+                               }
+                               printf("Device index: %d\n", devind);
+                               printf("Subsystem: Vid 0x%x, did 0x%x\n",
+                                       sub_vid, sub_did);
+                       }
+
+                       baseclass= __pci_attr_r8(devind, PCI_BCR);
+                       subclass= __pci_attr_r8(devind, PCI_SCR);
+                       infclass= __pci_attr_r8(devind, PCI_PIFR);
+                       s= pci_subclass_name(baseclass, subclass, infclass);
+                       if (!s)
+                               s= pci_baseclass_name(baseclass);
+                       {
+                               if (!s)
+                                       s= "(unknown class)";
+                       }
+                       if (debug)
+                       {
+                               printf("\tclass %s (%X/%X/%X)\n", s,
+                                       baseclass, subclass, infclass);
+                       }
+
+                       if (is_duplicate(busnr, dev, func))
+                       {
+                               printf("\tduplicate!\n");
+                               if (func == 0 && !(headt & PHT_MULTIFUNC))
+                                       break;
+                               continue;
+                       }
+
+                       devind= nr_pcidev;
+                       nr_pcidev++;
+                       pcidev[devind].pd_baseclass= baseclass;
+                       pcidev[devind].pd_subclass= subclass;
+                       pcidev[devind].pd_infclass= infclass;
+                       pcidev[devind].pd_vid= vid;
+                       pcidev[devind].pd_did= did;
+                       pcidev[devind].pd_sub_vid= sub_vid;
+                       pcidev[devind].pd_sub_did= sub_did;
+                       pcidev[devind].pd_inuse= 0;
+                       pcidev[devind].pd_bar_nr= 0;
+                       record_irq(devind);
+                       switch(headt & PHT_MASK)
+                       {
+                       case PHT_NORMAL:
+                               record_bars_normal(devind);
+                               break;
+                       case PHT_BRIDGE:
+                               record_bars_bridge(devind);
+                               break;
+                       case PHT_CARDBUS:
+                               record_bars_cardbus(devind);
+                               break;
+                       default:
+                               printf("\t%d.%d.%d: unknown header type %d\n",
+                                       busind, dev, func,
+                                       headt & PHT_MASK);
+                               break;
+                       }
+                       if (debug)
+                               print_capabilities(devind);
+
+                       t3= ((baseclass << 16) | (subclass << 8) | infclass);
+#if 0
+                       if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD)
+                               report_vga(devind);
+#endif
+
+                       if (nr_pcidev >= NR_PCIDEV)
+                               panic("too many PCI devices: %d", nr_pcidev);
+                       devind= nr_pcidev;
+
+                       if (func == 0 && !(headt & PHT_MULTIFUNC))
+                               break;
+               }
        }
-       br_devind= pcibus[busind].pb_devind;
-       pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1);
-       pci_attr_w32(br_devind, CBB_IOBASE_0, io_base);
+}
 
-       /* Enable I/O access. Enable busmaster access as well. */
-       v16= pci_attr_r16(devind, PCI_CR);
-       pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN);
+
+static u16_t
+pcibr_std_rsts(int busind)
+{
+       int devind;
+
+       devind= pcibus[busind].pb_devind;
+       return __pci_attr_r16(devind, PPB_SSTS);
 }
 
-/*===========================================================================*
- *                             get_freebus                                  *
- *===========================================================================*/
-static int get_freebus()
+static void
+pcibr_std_wsts(int busind, u16_t value)
 {
-       int i, freebus;
+       int devind;
+       devind= pcibus[busind].pb_devind;
 
-       freebus= 1;
-       for (i= 0; i<nr_pcibus; i++)
-       {
-               if (pcibus[i].pb_needinit)
-                       continue;
-               if (pcibus[i].pb_type == PBT_INTEL_HOST)
-                       continue;
-               if (pcibus[i].pb_busnr <= freebus)
-                       freebus= pcibus[i].pb_busnr+1;
-               printf("get_freebus: should check suboridinate bus number\n");
-       }
-       return freebus;
+#if 0
+       printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
+               busind, value, devind);
+#endif
+       __pci_attr_w16(devind, PPB_SSTS, value);
+}
+
+static u16_t
+pcibr_cb_rsts(int busind)
+{
+       int devind;
+       devind= pcibus[busind].pb_devind;
+
+       return __pci_attr_r16(devind, CBB_SSTS);
+}
+
+static void
+pcibr_cb_wsts(int busind, u16_t value)
+{
+       int devind;
+       devind= pcibus[busind].pb_devind;
+
+#if 0
+       printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
+               busind, value, devind);
+#endif
+       __pci_attr_w16(devind, CBB_SSTS, value);
+}
+
+static u16_t
+pcibr_via_rsts(int busind)
+{
+       return 0;
 }
 
-/*===========================================================================*
- *                             do_isabridge                                 *
- *===========================================================================*/
-static int do_isabridge(busind)
-int busind;
+static void
+pcibr_via_wsts(int busind, u16_t value)
 {
-       int i, j, r, type, busnr, unknown_bridge, bridge_dev;
-       u16_t vid, did;
-       u32_t t3;
-       char *dstr;
+       int devind;
+       devind= pcibus[busind].pb_devind;
 
-       unknown_bridge= -1;
-       bridge_dev= -1;
-       j= 0;   /* lint */
-       vid= did= 0;    /* lint */
-       busnr= pcibus[busind].pb_busnr;
-       for (i= 0; i< nr_pcidev; i++)
+#if 0
+       printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
+               busind, value, devind);
+#endif
+}
+
+static void
+complete_bridges(void)
+{
+       int i, freebus, devind, prim_busnr;
+
+       for (i= 0; i<nr_pcibus; i++)
        {
-               if (pcidev[i].pd_busnr != busnr)
+               if (!pcibus[i].pb_needinit)
                        continue;
-               t3= ((pcidev[i].pd_baseclass << 16) |
-                       (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass);
-               if (t3 == PCI_T3_ISA)
-               {
-                       /* ISA bridge. Report if no supported bridge is
-                        * found.
-                        */
-                       unknown_bridge= i;
-               }
+               printf("should allocate bus number for bus %d\n", i);
+               freebus= get_freebus();
+               printf("got bus number %d\n", freebus);
 
-               vid= pcidev[i].pd_vid;
-               did= pcidev[i].pd_did;
-               for (j= 0; pci_isabridge[j].vid != 0; j++)
-               {
-                       if (pci_isabridge[j].vid != vid)
-                               continue;
-                       if (pci_isabridge[j].did != did)
-                               continue;
-                       if (pci_isabridge[j].checkclass &&
-                               unknown_bridge != i)
-                       {
-                               /* This part of multifunction device is
-                                * not the bridge.
-                                */
-                               continue;
-                       }
-                       break;
-               }
-               if (pci_isabridge[j].vid)
-               {
-                       bridge_dev= i;
-                       break;
-               }
-       }
+               devind= pcibus[i].pb_devind;
 
-       if (bridge_dev != -1)
-       {
-               dstr= pci_dev_name(vid, did);
-               if (!dstr)
-                       dstr= "unknown device";
-               if (debug)
-               {
-                       printf("found ISA bridge (%04X:%04X) %s\n",
-                               vid, did, dstr);
-               }
-               pcibus[busind].pb_isabridge_dev= bridge_dev;
-               type= pci_isabridge[j].type;
-               pcibus[busind].pb_isabridge_type= type;
-               switch(type)
+               prim_busnr= pcidev[devind].pd_busnr;
+               if (prim_busnr != 0)
                {
-               case PCI_IB_PIIX:
-                       r= do_piix(bridge_dev);
-                       break;
-               case PCI_IB_VIA:
-                       r= do_via_isabr(bridge_dev);
-                       break;
-               case PCI_IB_AMD:
-                       r= do_amd_isabr(bridge_dev);
-                       break;
-               case PCI_IB_SIS:
-                       r= do_sis_isabr(bridge_dev);
-                       break;
-               default:
-                       panic("unknown ISA bridge type: %d", type);
+                       printf(
+       "complete_bridge: updating subordinate bus number not implemented\n");
                }
-               return r;
-       }
 
-       if (unknown_bridge == -1)
-       {
-               if (debug)
-               {
-                       printf("(warning) no ISA bridge found on bus %d\n",
-                               busind);
-               }
-               return 0;
-       }
-       if (debug)
-       {
-               printf(
-               "(warning) unsupported ISA bridge %04X:%04X for bus %d\n",
-                       pcidev[unknown_bridge].pd_vid,
-                       pcidev[unknown_bridge].pd_did, busind);
+               pcibus[i].pb_needinit= 0;
+               pcibus[i].pb_busnr= freebus;
+
+               printf("devind = %d\n", devind);
+               printf("prim_busnr= %d\n", prim_busnr);
+
+               __pci_attr_w8(devind, PPB_PRIMBN, prim_busnr);
+               __pci_attr_w8(devind, PPB_SECBN, freebus);
+               __pci_attr_w8(devind, PPB_SUBORDBN, freebus);
+
+               printf("CR = 0x%x\n", __pci_attr_r16(devind, PCI_CR));
+               printf("SECBLT = 0x%x\n", __pci_attr_r8(devind, PPB_SECBLT));
+               printf("BRIDGECTRL = 0x%x\n",
+                       __pci_attr_r16(devind, PPB_BRIDGECTRL));
        }
-       return 0;
 }
 
 /*
@@ -1822,7 +1836,8 @@ int busind;
  * (pbnr) must be already known to acpi and it must map dev as the connection to
  * the secondary (sbnr) bus
  */
-static void acpi_map_bridge(unsigned pbnr, unsigned dev, unsigned sbnr)
+static void
+acpi_map_bridge(unsigned int pbnr, unsigned int dev, unsigned int sbnr)
 {
        int err;
        message m;
@@ -1840,11 +1855,8 @@ static void acpi_map_bridge(unsigned pbnr, unsigned dev, unsigned sbnr)
                                                                pbnr, sbnr);
 }
 
-/*===========================================================================*
- *                             do_pcibridge                                 *
- *===========================================================================*/
-static void do_pcibridge(busind)
-int busind;
+static void
+do_pcibridge(int busind)
 {
        int i, devind, busnr;
        int ind, type;
@@ -1858,7 +1870,7 @@ int busind;
        {
 #if 0
                printf("do_pcibridge: trying %u.%u.%u\n",
-                       pcidev[devind].pd_busnr, pcidev[devind].pd_dev, 
+                       pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
                        pcidev[devind].pd_func);
 #endif
 
@@ -1883,7 +1895,7 @@ int busind;
                type= pci_pcibridge[i].type;
                if (pci_pcibridge[i].vid == 0)
                {
-                       headt= pci_attr_r8_u(devind, PCI_HEADT);
+                       headt= __pci_attr_r8(devind, PCI_HEADT);
                        type= 0;
                        if ((headt & PHT_MASK) == PHT_BRIDGE)
                                type= PCI_PPB_STD;
@@ -1897,9 +1909,9 @@ int busind;
                                continue;       /* Not a bridge */
                        }
 
-                       baseclass= pci_attr_r8_u(devind, PCI_BCR);
-                       subclass= pci_attr_r8_u(devind, PCI_SCR);
-                       infclass= pci_attr_r8_u(devind, PCI_PIFR);
+                       baseclass= __pci_attr_r8(devind, PCI_BCR);
+                       subclass= __pci_attr_r8(devind, PCI_SCR);
+                       infclass= __pci_attr_r8(devind, PCI_PIFR);
                        t3= ((baseclass << 16) | (subclass << 8) | infclass);
                        if (type == PCI_PPB_STD &&
                                t3 != PCI_T3_PCI2PCI &&
@@ -1910,7 +1922,7 @@ int busind;
                                        baseclass, subclass, infclass,
                                        vid, did);
                                continue;
-                        }
+                       }
                        if (type == PCI_PPB_CB &&
                                t3 != PCI_T3_CARDBUS)
                        {
@@ -1919,21 +1931,21 @@ int busind;
                                        baseclass, subclass, infclass,
                                        vid, did);
                                continue;
-                        }
+                       }
                }
 
                if (debug)
                {
                        printf("%u.%u.%u: PCI-to-PCI bridge: %04X:%04X\n",
                                pcidev[devind].pd_busnr,
-                               pcidev[devind].pd_dev, 
+                               pcidev[devind].pd_dev,
                                pcidev[devind].pd_func, vid, did);
                }
 
                /* Assume that the BIOS initialized the secondary bus
                 * number.
                 */
-               sbusn= pci_attr_r8_u(devind, PPB_SECBN);
+               sbusn= __pci_attr_r8(devind, PPB_SECBN);
 
                if (nr_pcibus >= NR_PCIBUS)
                        panic("too many PCI busses: %d", nr_pcibus);
@@ -1967,235 +1979,140 @@ int busind;
                        pcibus[ind].pb_wsts= pcibr_via_wsts;
                        break;
                default:
-                   panic("unknown PCI-PCI bridge type: %d", type);
+                       panic("unknown PCI-PCI bridge type: %d", type);
                }
 
                if (machine.apic_enabled)
-                       acpi_map_bridge(pcidev[devind].pd_busnr,
-                                       pcidev[devind].pd_dev, sbusn);
-
-               if (debug)
-               {
-                       printf(
-                       "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
-                               ind, sbusn, pci_attr_r8_u(devind, PPB_SUBORDBN));
-               }
-               if (sbusn == 0)
-               {
-                       printf("Secondary bus number not initialized\n");
-                       continue;
-               }
-               pcibus[ind].pb_needinit= 0;
-
-               probe_bus(ind);
-
-               /* Look for PCI bridges */
-               do_pcibridge(ind);
-       }
-}
-
-/*===========================================================================*
- *                             get_busind                                           *
- *===========================================================================*/
-static int get_busind(busnr)
-int busnr;
-{
-       int i;
-
-       for (i= 0; i<nr_pcibus; i++)
-       {
-               if (pcibus[i].pb_busnr == busnr)
-                       return i;
-       }
-       panic("get_busind: can't find bus: %d", busnr);
-}
-
-/*===========================================================================*
- *                             do_piix                                      *
- *===========================================================================*/
-static int do_piix(int devind)
-{
-       int i, s, irqrc, irq;
-       u32_t elcr1, elcr2, elcr;
-
-#if DEBUG
-       printf("in piix\n");
-#endif
-       if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
-               printf("Warning, sys_inb failed: %d\n", s);
-       if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
-               printf("Warning, sys_inb failed: %d\n", s);
-       elcr= elcr1 | (elcr2 << 8);
-       for (i= 0; i<4; i++)
-       {
-               irqrc= pci_attr_r8_u(devind, PIIX_PIRQRCA+i);
-               if (irqrc & PIIX_IRQ_DI)
-               {
-                       if (debug)
-                               printf("INT%c: disabled\n", 'A'+i);
-               }
-               else
-               {
-                       irq= irqrc & PIIX_IRQ_MASK;
-                       if (debug)
-                               printf("INT%c: %d\n", 'A'+i, irq);
-                       if (!(elcr & (1 << irq)))
-                       {
-                               if (debug)
-                               {
-                                       printf(
-                               "(warning) IRQ %d is not level triggered\n", 
-                                               irq);
-                               }
-                       }
-                       irq_mode_pci(irq);
-               }
-       }
-       return 0;
-}
-
-/*===========================================================================*
- *                             do_amd_isabr                                 *
- *===========================================================================*/
-static int do_amd_isabr(int devind)
-{
-       int i, busnr, dev, func, xdevind, irq, edge;
-       u8_t levmask;
-       u16_t pciirq;
-
-       /* Find required function */
-       func= AMD_ISABR_FUNC;
-       busnr= pcidev[devind].pd_busnr;
-       dev= pcidev[devind].pd_dev;
-
-       /* Fake a device with the required function */
-       if (nr_pcidev >= NR_PCIDEV)
-               panic("too many PCI devices: %d", nr_pcidev);
-       xdevind= nr_pcidev;
-       pcidev[xdevind].pd_busnr= busnr;
-       pcidev[xdevind].pd_dev= dev;
-       pcidev[xdevind].pd_func= func;
-       pcidev[xdevind].pd_inuse= 1;
-       nr_pcidev++;
-
-       levmask= pci_attr_r8_u(xdevind, AMD_ISABR_PCIIRQ_LEV);
-       pciirq= pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
-       for (i= 0; i<4; i++)
-       {
-               edge= (levmask >> i) & 1;
-               irq= (pciirq >> (4*i)) & 0xf;
-               if (!irq)
-               {
-                       if (debug)
-                               printf("INT%c: disabled\n", 'A'+i);
-               }
-               else
-               {
-                       if (debug)
-                               printf("INT%c: %d\n", 'A'+i, irq);
-                       if (edge && debug)
-                       {
-                               printf(
-                               "(warning) IRQ %d is not level triggered\n",
-                                       irq);
-                       }
-                       irq_mode_pci(irq);
-               }
-       }
-       nr_pcidev--;
-       return 0;
-}
-
-/*===========================================================================*
- *                             do_sis_isabr                                 *
- *===========================================================================*/
-static int do_sis_isabr(int devind)
-{
-       int i, irq;
-
-       irq= 0; /* lint */
-       for (i= 0; i<4; i++)
-       {
-               irq= pci_attr_r8_u(devind, SIS_ISABR_IRQ_A+i);
-               if (irq & SIS_IRQ_DISABLED)
+                       acpi_map_bridge(pcidev[devind].pd_busnr,
+                                       pcidev[devind].pd_dev, sbusn);
+
+               if (debug)
                {
-                       if (debug)
-                               printf("INT%c: disabled\n", 'A'+i);
+                       printf(
+                       "bus(table) = %d, bus(sec) = %d, bus(subord) = %d\n",
+                               ind, sbusn, __pci_attr_r8(devind, PPB_SUBORDBN));
                }
-               else
+               if (sbusn == 0)
                {
-                       irq &= SIS_IRQ_MASK;
-                       if (debug)
-                               printf("INT%c: %d\n", 'A'+i, irq);
-                       irq_mode_pci(irq);
+                       printf("Secondary bus number not initialized\n");
+                       continue;
                }
+               pcibus[ind].pb_needinit= 0;
+
+               probe_bus(ind);
+
+               /* Look for PCI bridges */
+               do_pcibridge(ind);
        }
-       return 0;
 }
 
 /*===========================================================================*
- *                             do_via_isabr                                 *
+ *                             pci_intel_init                               *
  *===========================================================================*/
-static int do_via_isabr(int devind)
+static void
+pci_intel_init()
 {
-       int i, irq, edge;
-       u8_t levmask;
+       /* Try to detect a know PCI controller. Read the Vendor ID and
+        * the Device ID for function 0 of device 0.
+        * Two times the value 0xffff suggests a system without a (compatible)
+        * PCI controller.
+        */
+       u32_t bus, dev, func;
+       u16_t vid, did;
+       int s, i, r, busind, busnr;
+       const char *dstr;
 
-       levmask= pci_attr_r8_u(devind, VIA_ISABR_EL);
-       irq= 0; /* lint */
-       edge= 0; /* lint */
-       for (i= 0; i<4; i++)
+       bus= 0;
+       dev= 0;
+       func= 0;
+
+       vid= PCII_RREG16_(bus, dev, func, PCI_VID);
+       did= PCII_RREG16_(bus, dev, func, PCI_DID);
+       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
+               printf("PCI: warning, sys_outl failed: %d\n", s);
+
+#if 0
+       if (vid == 0xffff && did == 0xffff)
+               return; /* Nothing here */
+
+       for (i= 0; pci_intel_ctrl[i].vid; i++)
        {
-               switch(i)
+               if (pci_intel_ctrl[i].vid == vid &&
+                       pci_intel_ctrl[i].did == did)
                {
-               case 0:
-                       edge= (levmask & VIA_ISABR_EL_INTA);
-                       irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R2) >> 4;
-                       break;
-               case 1:
-                       edge= (levmask & VIA_ISABR_EL_INTB);
-                       irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R2);
-                       break;
-               case 2:
-                       edge= (levmask & VIA_ISABR_EL_INTC);
-                       irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R3) >> 4;
-                       break;
-               case 3:
-                       edge= (levmask & VIA_ISABR_EL_INTD);
-                       irq= pci_attr_r8_u(devind, VIA_ISABR_IRQ_R1) >> 4;
                        break;
-               default:
-                       assert(0);
-               }
-               irq &= 0xf;
-               if (!irq)
-               {
-                       if (debug)
-                               printf("INT%c: disabled\n", 'A'+i);
                }
-               else
+       }
+
+       if (!pci_intel_ctrl[i].vid)
+       {
+               printf("pci_intel_init (warning): unknown PCI-controller:\n"
+                       "\tvendor %04X (%s), device %04X\n",
+                       vid, pci_vid_name(vid), did);
+       }
+#endif
+
+       if (nr_pcibus >= NR_PCIBUS)
+               panic("too many PCI busses: %d", nr_pcibus);
+       busind= nr_pcibus;
+       nr_pcibus++;
+       pcibus[busind].pb_type= PBT_INTEL_HOST;
+       pcibus[busind].pb_needinit= 0;
+       pcibus[busind].pb_isabridge_dev= -1;
+       pcibus[busind].pb_isabridge_type= 0;
+       pcibus[busind].pb_devind= -1;
+       pcibus[busind].pb_busnr= 0;
+       pcibus[busind].pb_rreg8= pcii_rreg8;
+       pcibus[busind].pb_rreg16= pcii_rreg16;
+       pcibus[busind].pb_rreg32= pcii_rreg32;
+       pcibus[busind].pb_wreg8= pcii_wreg8;
+       pcibus[busind].pb_wreg16= pcii_wreg16;
+       pcibus[busind].pb_wreg32= pcii_wreg32;
+       pcibus[busind].pb_rsts= pcii_rsts;
+       pcibus[busind].pb_wsts= pcii_wsts;
+
+       dstr= _pci_dev_name(vid, did);
+       if (!dstr)
+               dstr= "unknown device";
+       if (debug)
+       {
+               printf("pci_intel_init: %s (%04X:%04X)\n",
+                       dstr, vid, did);
+       }
+
+       probe_bus(busind);
+
+       r= do_isabridge(busind);
+       if (r != OK)
+       {
+               busnr= pcibus[busind].pb_busnr;
+
+               /* Disable all devices for this bus */
+               for (i= 0; i<nr_pcidev; i++)
                {
-                       if (debug)
-                               printf("INT%c: %d\n", 'A'+i, irq);
-                       if (edge && debug)
-                       {
-                               printf(
-                               "(warning) IRQ %d is not level triggered\n",
-                                       irq);
-                       }
-                       irq_mode_pci(irq);
+                       if (pcidev[i].pd_busnr != busnr)
+                               continue;
+                       pcidev[i].pd_inuse= 1;
                }
+               return;
        }
-       return 0;
-}
 
+       /* Look for PCI bridges */
+       do_pcibridge(busind);
+
+       /* Allocate bus numbers for uninitialized bridges */
+       complete_bridges();
+
+       /* Allocate I/O and memory resources for uninitialized devices */
+       complete_bars();
+}
 
 #if 0
 /*===========================================================================*
  *                             report_vga                                   *
  *===========================================================================*/
-static void report_vga(devind)
-int devind;
+static void
+report_vga(int devind)
 {
        /* Report the amount of video memory. This is needed by the X11R6
         * postinstall script to chmem the X server. Hopefully this can be
@@ -2227,535 +2144,513 @@ int devind;
 
 
 /*===========================================================================*
- *                             pci_vid_name                                 *
- *===========================================================================*/
-static char *pci_vid_name(u16_t vid)
-{
-       int i;
-
-       for (i= 0; pci_vendor_table[i].name; i++)
-       {
-               if (pci_vendor_table[i].vid == vid)
-                       return pci_vendor_table[i].name;
-       }
-       return "unknown";
-}
-
-/*===========================================================================*
- *                             pci_baseclass_name                           *
+ *                             visible                                      *
  *===========================================================================*/
-static char *pci_baseclass_name(u8_t baseclass)
+static int
+visible(struct rs_pci *aclp, int devind)
 {
+       u16_t acl_sub_vid, acl_sub_did;
        int i;
+       u32_t class_id;
 
-       for (i= 0; pci_baseclass_table[i].name; i++)
+       if (!aclp)
+               return TRUE;    /* Should be changed when ACLs become
+                                * mandatory. Do note that procfs relies
+                                * on being able to see all devices.
+                                */
+       /* Check whether the caller is allowed to get this device. */
+       for (i= 0; i<aclp->rsp_nr_device; i++)
        {
-               if (pci_baseclass_table[i].baseclass == baseclass)
-                       return pci_baseclass_table[i].name;
+               acl_sub_vid = aclp->rsp_device[i].sub_vid;
+               acl_sub_did = aclp->rsp_device[i].sub_did;
+               if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid &&
+                       aclp->rsp_device[i].did == pcidev[devind].pd_did &&
+                       (acl_sub_vid == NO_SUB_VID ||
+                       acl_sub_vid == pcidev[devind].pd_sub_vid) &&
+                       (acl_sub_did == NO_SUB_DID ||
+                       acl_sub_did == pcidev[devind].pd_sub_did))
+               {
+                       return TRUE;
+               }
        }
-       return NULL;
-}
-
-/*===========================================================================*
- *                             pci_subclass_name                            *
- *===========================================================================*/
-static char *pci_subclass_name(u8_t baseclass, u8_t subclass, u8_t infclass)
-{
-       int i;
+       if (!aclp->rsp_nr_class)
+               return FALSE;
 
-       for (i= 0; pci_subclass_table[i].name; i++)
+       class_id= (pcidev[devind].pd_baseclass << 16) |
+               (pcidev[devind].pd_subclass << 8) |
+               pcidev[devind].pd_infclass;
+       for (i= 0; i<aclp->rsp_nr_class; i++)
        {
-               if (pci_subclass_table[i].baseclass != baseclass)
-                       continue;
-               if (pci_subclass_table[i].subclass != subclass)
-                       continue;
-               if (pci_subclass_table[i].infclass != infclass &&
-                       pci_subclass_table[i].infclass != (u16_t)-1)
+               if (aclp->rsp_class[i].pciclass ==
+                       (class_id & aclp->rsp_class[i].mask))
                {
-                       continue;
+                       return TRUE;
                }
-               return pci_subclass_table[i].name;
        }
-       return NULL;
+
+       return FALSE;
 }
 
 /*===========================================================================*
- *                             ntostr                                       *
+ *                             sef_cb_init_fresh                            *
  *===========================================================================*/
-static void ntostr(n, str, end)
-unsigned n;
-char **str;
-const char *end;
+int
+sef_cb_init_fresh(int type, sef_init_info_t *info)
 {
-       char tmpstr[20];
-       int i;
+/* Initialize the pci driver. */
+       long v;
+       int i, r;
+       struct rprocpub rprocpub[NR_BOOT_PROCS];
 
-       if (n == 0)
-       {
-               tmpstr[0]= '0';
-               i= 1;
+       v= 0;
+       env_parse("pci_debug", "d", 0, &v, 0, 1);
+       debug= v;
+
+       if (sys_getmachine(&machine)) {
+               printf("PCI: no machine\n");
+               return ENODEV;
        }
-       else
-       {
-               for (i= 0; n; i++)
-               {
-                       tmpstr[i]= '0' + (n%10);
-                       n /= 10;
-               }
+       if (machine.apic_enabled &&
+                       ds_retrieve_label_endpt("acpi", &acpi_ep) != OK) {
+               panic("PCI: Cannot use APIC mode without ACPI!\n");
        }
-       for (; i>0; i--)
-       {
-               if (*str == end)
-               {
-                       break;
+
+       /* Only Intel (compatible) PCI controllers are supported at the
+        * moment.
+        */
+       pci_intel_init();
+
+       /* Map all the services in the boot image. */
+       if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
+               (vir_bytes) rprocpub, sizeof(rprocpub))) != OK) {
+               panic("sys_safecopyfrom failed: %d", r);
+       }
+       for(i=0;i < NR_BOOT_PROCS;i++) {
+               if(rprocpub[i].in_use) {
+                       if((r = map_service(&rprocpub[i])) != OK) {
+                               panic("unable to map service: %d", r);
+                       }
                }
-               **str= tmpstr[i-1];
-               (*str)++;
        }
-       if (*str == end)        
-               (*str)[-1]= '\0';
-       else
-               **str= '\0';
+
+       return(OK);
 }
 
 /*===========================================================================*
- *                             pci_attr_rsts                                *
+ *                            map_service                                   *
  *===========================================================================*/
-static u16_t pci_attr_rsts(devind)
-int devind;
+int
+map_service(struct rprocpub *rpub)
 {
-       int busnr, busind;
+/* Map a new service by registering a new acl entry if required. */
+       int i;
 
-       busnr= pcidev[devind].pd_busnr;
-       busind= get_busind(busnr);
-       return pcibus[busind].pb_rsts(busind);
-}
-                               
+       /* Stop right now if no pci device or class is found. */
+       if(rpub->pci_acl.rsp_nr_device == 0
+               && rpub->pci_acl.rsp_nr_class == 0) {
+               return(OK);
+       }
 
-/*===========================================================================*
- *                             pcibr_std_rsts                               *
- *===========================================================================*/
-static u16_t pcibr_std_rsts(busind)
-int busind;
-{
-       int devind;
+       /* Find a free acl slot. */
+       for (i= 0; i<NR_DRIVERS; i++)
+       {
+               if (!pci_acl[i].inuse)
+                       break;
+       }
+       if (i >= NR_DRIVERS)
+       {
+               printf("PCI: map_service: table is full\n");
+               return ENOMEM;
+       }
 
-       devind= pcibus[busind].pb_devind;
-       return pci_attr_r16(devind, PPB_SSTS);
+       /* Initialize acl slot. */
+       pci_acl[i].inuse = 1;
+       pci_acl[i].acl = rpub->pci_acl;
+
+       return(OK);
 }
 
 /*===========================================================================*
- *                             pcibr_std_wsts                               *
+ *                             _pci_find_dev                                *
  *===========================================================================*/
-static void pcibr_std_wsts(int busind, u16_t value)
+int
+_pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp)
 {
        int devind;
-       devind= pcibus[busind].pb_devind;
 
+       for (devind= 0; devind < nr_pcidev; devind++)
+       {
+               if (pcidev[devind].pd_busnr == bus &&
+                       pcidev[devind].pd_dev == dev &&
+                       pcidev[devind].pd_func == func)
+               {
+                       break;
+               }
+       }
+       if (devind >= nr_pcidev)
+               return 0;
 #if 0
-       printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n", 
-               busind, value, devind);
+       if (pcidev[devind].pd_inuse)
+               return 0;
 #endif
-       pci_attr_w16(devind, PPB_SSTS, value);
-}
-
-/*===========================================================================*
- *                             pcibr_cb_rsts                                *
- *===========================================================================*/
-static u16_t pcibr_cb_rsts(busind)
-int busind;
-{
-       int devind;
-       devind= pcibus[busind].pb_devind;
-
-       return pci_attr_r16(devind, CBB_SSTS);
+       *devindp= devind;
+       return 1;
 }
 
 /*===========================================================================*
- *                             pcibr_cb_wsts                                *
+ *                             _pci_first_dev                               *
  *===========================================================================*/
-static void pcibr_cb_wsts(int busind, u16_t value)
+int
+_pci_first_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp,
+       u16_t *didp)
 {
        int devind;
-       devind= pcibus[busind].pb_devind;
 
+       for (devind= 0; devind < nr_pcidev; devind++)
+       {
 #if 0
-       printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n", 
-               busind, value, devind);
+               if (pcidev[devind].pd_inuse)
+                       continue;
 #endif
-       pci_attr_w16(devind, CBB_SSTS, value);
-}
-
-/*===========================================================================*
- *                             pcibr_via_rsts                               *
- *===========================================================================*/
-static u16_t pcibr_via_rsts(int busind)
-{
-       return 0;
+               if (!visible(aclp, devind))
+                       continue;
+               break;
+       }
+       if (devind >= nr_pcidev)
+               return 0;
+       *devindp= devind;
+       *vidp= pcidev[devind].pd_vid;
+       *didp= pcidev[devind].pd_did;
+       return 1;
 }
 
 /*===========================================================================*
- *                             pcibr_via_wsts                               *
+ *                             _pci_next_dev                                *
  *===========================================================================*/
-static void pcibr_via_wsts(int busind, u16_t value)
+int
+_pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t *didp)
 {
        int devind;
-       devind= pcibus[busind].pb_devind;
 
+       for (devind= *devindp+1; devind < nr_pcidev; devind++)
+       {
 #if 0
-       printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n", 
-               busind, value, devind);
+               if (pcidev[devind].pd_inuse)
+                       continue;
 #endif
+               if (!visible(aclp, devind))
+                       continue;
+               break;
+       }
+       if (devind >= nr_pcidev)
+               return 0;
+       *devindp= devind;
+       *vidp= pcidev[devind].pd_vid;
+       *didp= pcidev[devind].pd_did;
+       return 1;
 }
 
 /*===========================================================================*
- *                             pci_attr_wsts                                *
+ *                             _pci_reserve                                 *
  *===========================================================================*/
-static void pci_attr_wsts(int devind, u16_t value)
+int
+_pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp)
 {
-       int busnr, busind;
-
-       busnr= pcidev[devind].pd_busnr;
-       busind= get_busind(busnr);
-       pcibus[busind].pb_wsts(busind, value);
-}
-                               
+       int i, r;
+       int ilr;
+       struct io_range ior;
+       struct minix_mem_range mr;
 
-/*===========================================================================*
- *                             pcii_rreg8                                   *
- *===========================================================================*/
-static u8_t pcii_rreg8(busind, devind, port)
-int busind;
-int devind;
-int port;
-{
-       u8_t v;
-       int s;
+       if (devind < 0 || devind >= nr_pcidev)
+       {
+               printf("pci_reserve_a: bad devind: %d\n", devind);
+               return EINVAL;
+       }
+       if (!visible(aclp, devind))
+       {
+               printf("pci_reserve_a: %u is not allowed to reserve %d\n",
+                       proc, devind);
+               return EPERM;
+       }
 
-       v= PCII_RREG8_(pcibus[busind].pb_busnr, 
-               pcidev[devind].pd_dev, pcidev[devind].pd_func,
-               port);
-       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
-               printf("PCI: warning, sys_outl failed: %d\n", s);
-#if 0
-       printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
-               busind, devind, port,
-               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
-               pcidev[devind].pd_func, v);
-#endif
-       return v;
-}
+       if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
+               return EBUSY;
+       pcidev[devind].pd_inuse= 1;
+       pcidev[devind].pd_proc= proc;
 
-/*===========================================================================*
- *                             pcii_rreg16                                  *
- *===========================================================================*/
-static u16_t pcii_rreg16(int busind, int devind, int port)
-{
-       u16_t v;
-       int s;
+       for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
+       {
+               if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
+               {
+                       printf("pci_reserve_a: BAR %d is incomplete\n", i);
+                       continue;
+               }
+               if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
+               {
+                       ior.ior_base= pcidev[devind].pd_bar[i].pb_base;
+                       ior.ior_limit= ior.ior_base +
+                               pcidev[devind].pd_bar[i].pb_size-1;
 
-       v= PCII_RREG16_(pcibus[busind].pb_busnr, 
-               pcidev[devind].pd_dev, pcidev[devind].pd_func,
-               port);
-       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
-               printf("PCI: warning, sys_outl failed: %d\n", s);
-#if 0
-       printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
-               busind, devind, port,
-               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
-               pcidev[devind].pd_func, v);
-#endif
-       return v;
-}
+                       if(debug) {
+                               printf(
+               "pci_reserve_a: for proc %d, adding I/O range [0x%x..0x%x]\n",
+               proc, ior.ior_base, ior.ior_limit);
+                       }
+                       r= sys_privctl(proc, SYS_PRIV_ADD_IO, &ior);
+                       if (r != OK)
+                       {
+                               printf("sys_privctl failed for proc %d: %d\n",
+                                       proc, r);
+                       }
+               }
+               else
+               {
+                       mr.mr_base= pcidev[devind].pd_bar[i].pb_base;
+                       mr.mr_limit= mr.mr_base +
+                               pcidev[devind].pd_bar[i].pb_size-1;
 
-/*===========================================================================*
- *                             pcii_rreg32                                  *
- *===========================================================================*/
-static u32_t pcii_rreg32(int busind, int devind, int port)
-{
-       u32_t v;
-       int s;
+                       r= sys_privctl(proc, SYS_PRIV_ADD_MEM, &mr);
+                       if (r != OK)
+                       {
+                               printf("sys_privctl failed for proc %d: %d\n",
+                                       proc, r);
+                       }
+               }
+       }
+       ilr= pcidev[devind].pd_ilr;
+       if (ilr != PCI_ILR_UNKNOWN)
+       {
+               if(debug) printf("pci_reserve_a: adding IRQ %d\n", ilr);
+               r= sys_privctl(proc, SYS_PRIV_ADD_IRQ, &ilr);
+               if (r != OK)
+               {
+                       printf("sys_privctl failed for proc %d: %d\n",
+                               proc, r);
+               }
+       }
 
-       v= PCII_RREG32_(pcibus[busind].pb_busnr, 
-               pcidev[devind].pd_dev, pcidev[devind].pd_func,
-               port);
-       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
-               printf("PCI: warning, sys_outl failed: %d\n", s);
-#if 0
-       printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
-               busind, devind, port,
-               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
-               pcidev[devind].pd_func, v);
-#endif
-       return v;
+       return OK;
 }
 
 /*===========================================================================*
- *                             pcii_wreg8                                   *
+ *                             _pci_release                                 *
  *===========================================================================*/
-static void pcii_wreg8(
-  int busind,
-  int devind,
-  int port,
-  u8_t value
-)
+void
+_pci_release(endpoint_t proc)
 {
-       int s;
-#if 0
-       printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
-               busind, devind, port, value,
-               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
-               pcidev[devind].pd_func);
-#endif
-       PCII_WREG8_(pcibus[busind].pb_busnr, 
-               pcidev[devind].pd_dev, pcidev[devind].pd_func,
-               port, value);
-       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
-               printf("PCI: warning, sys_outl failed: %d\n", s);
-}
+       int i;
 
-/*===========================================================================*
- *                             pcii_wreg16                                  *
- *===========================================================================*/
-static void pcii_wreg16(
-  int busind,
-  int devind,
-  int port,
-  u16_t value
-)
-{
-       int s;
-#if 0
-       printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
-               busind, devind, port, value,
-               pcibus[busind].pb_bus, pcidev[devind].pd_dev,
-               pcidev[devind].pd_func);
-#endif
-       PCII_WREG16_(pcibus[busind].pb_busnr, 
-               pcidev[devind].pd_dev, pcidev[devind].pd_func,
-               port, value);
-       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
-               printf("PCI: warning, sys_outl failed: %d\n", s);
+       for (i= 0; i<nr_pcidev; i++)
+       {
+               if (!pcidev[i].pd_inuse)
+                       continue;
+               if (pcidev[i].pd_proc != proc)
+                       continue;
+               pcidev[i].pd_inuse= 0;
+       }
 }
 
 /*===========================================================================*
- *                             pcii_wreg32                                  *
+ *                             _pci_ids                                     *
  *===========================================================================*/
-static void pcii_wreg32(
-  int busind,
-  int devind,
-  int port,
-  u32_t value
-)
+int
+_pci_ids(int devind, u16_t *vidp, u16_t *didp)
 {
-       int s;
-#if 0
-       printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
-               busind, devind, port, value,
-               pcibus[busind].pb_busnr, pcidev[devind].pd_dev,
-               pcidev[devind].pd_func);
-#endif
-       PCII_WREG32_(pcibus[busind].pb_busnr, 
-               pcidev[devind].pd_dev, pcidev[devind].pd_func,
-               port, value);
-       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
-               printf("PCI: warning, sys_outl failed: %d\n",s);
+       if (devind < 0 || devind >= nr_pcidev)
+               return EINVAL;
+
+       *vidp= pcidev[devind].pd_vid;
+       *didp= pcidev[devind].pd_did;
+       return OK;
 }
 
 /*===========================================================================*
- *                             pcii_rsts                                    *
+ *                             _pci_rescan_bus                              *
  *===========================================================================*/
-static u16_t pcii_rsts(int busind)
+void
+_pci_rescan_bus(u8_t busnr)
 {
-       u16_t v;
-       int s;
+       int busind;
 
-       v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR);
-       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
-               printf("PCI: warning, sys_outl failed: %d\n", s);
-       return v;
+       busind= get_busind(busnr);
+       probe_bus(busind);
+
+       /* Allocate bus numbers for uninitialized bridges */
+       complete_bridges();
+
+       /* Allocate I/O and memory resources for uninitialized devices */
+       complete_bars();
 }
 
 /*===========================================================================*
- *                             pcii_wsts                                    *
+ *                             _pci_slot_name                               *
  *===========================================================================*/
-static void pcii_wsts(int busind, u16_t value)
+int
+_pci_slot_name(int devind, char **cpp)
 {
-       int s;
-       PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value);
-       if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
-               printf("PCI: warning, sys_outl failed: %d\n", s);
-}
+       static char label[]= "ddd.ddd.ddd.ddd";
+       char *end;
+       char *p;
 
+       if (devind < 0 || devind >= nr_pcidev)
+               return EINVAL;
 
-/*===========================================================================*
- *                             print_capabilities                           *
- *===========================================================================*/
-static void print_capabilities(int devind)
-{
-       u8_t status, capptr, type, next, subtype;
-       char *str;
+       p= label;
+       end= label+sizeof(label);
 
-       /* Check capabilities bit in the device status register */
-       status= pci_attr_r16(devind, PCI_SR);
-       if (!(status & PSR_CAPPTR))
-               return;
+       /* FIXME: domain nb is always 0 on 32bit system, but we should
+        *        retrieve it properly, somehow. */
+       ntostr(0, &p, end);
+       *p++= '.';
 
-       capptr= (pci_attr_r8_u(devind, PCI_CAPPTR) & PCI_CP_MASK);
-       while (capptr != 0)
-       {
-               type = pci_attr_r8_u(devind, capptr+CAP_TYPE);
-               next= (pci_attr_r8_u(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
-               switch(type)
-               {
-               case 1: str= "PCI Power Management"; break;
-               case 2: str= "AGP"; break;
-               case 3: str= "Vital Product Data"; break;
-               case 4: str= "Slot Identification"; break;
-               case 5: str= "Message Signaled Interrupts"; break;
-               case 6: str= "CompactPCI Hot Swap"; break;
-               case 8: str= "AMD HyperTransport"; break;
-               case 0xf: str= "Secure Device"; break;
-               default: str= "(unknown type)"; break;
-               }
+       ntostr(pcidev[devind].pd_busnr, &p, end);
+       *p++= '.';
 
-               printf(" @0x%x (0x%08x): capability type 0x%x: %s",
-                       capptr, pci_attr_r32_u(devind, capptr), type, str);
-               if (type == 0x08)
-                       print_hyper_cap(devind, capptr);
-               else if (type == 0x0f)
-               {
-                       subtype= (pci_attr_r8_u(devind, capptr+2) & 0x07);
-                       switch(subtype)
-                       {
-                       case 0: str= "Device Exclusion Vector"; break;
-                       case 3: str= "IOMMU"; break;
-                       default: str= "(unknown type)"; break;
-                       }
-                       printf(", sub type 0%o: %s", subtype, str);
-               }
-               printf("\n");
-               capptr= next;
-       }
-}
+       ntostr(pcidev[devind].pd_dev, &p, end);
+       *p++= '.';
+
+       ntostr(pcidev[devind].pd_func, &p, end);
 
+       *cpp= label;
+       return OK;
+}
 
 /*===========================================================================*
- *                             visible                                      *
+ *                             _pci_dev_name                                *
  *===========================================================================*/
-static int visible(aclp, devind)
-struct rs_pci *aclp;
-int devind;
+const char *
+_pci_dev_name(u16_t vid, u16_t did)
 {
-       u16_t acl_sub_vid, acl_sub_did;
        int i;
-       u32_t class_id;
 
-       if (!aclp)
-               return TRUE;    /* Should be changed when ACLs become
-                                * mandatory. Do note that procfs relies
-                                * on being able to see all devices.
-                                */
-       /* Check whether the caller is allowed to get this device. */
-       for (i= 0; i<aclp->rsp_nr_device; i++)
+       for (i= 0; pci_device_table[i].name; i++)
        {
-               acl_sub_vid = aclp->rsp_device[i].sub_vid;
-               acl_sub_did = aclp->rsp_device[i].sub_did;
-               if (aclp->rsp_device[i].vid == pcidev[devind].pd_vid &&
-                       aclp->rsp_device[i].did == pcidev[devind].pd_did &&
-                       (acl_sub_vid == NO_SUB_VID ||
-                       acl_sub_vid == pcidev[devind].pd_sub_vid) &&
-                       (acl_sub_did == NO_SUB_DID ||
-                       acl_sub_did == pcidev[devind].pd_sub_did))
+               if (pci_device_table[i].vid == vid &&
+                       pci_device_table[i].did == did)
                {
-                       return TRUE;
+                       return pci_device_table[i].name;
                }
        }
-       if (!aclp->rsp_nr_class)
-               return FALSE;
+       return NULL;
+}
 
-       class_id= (pcidev[devind].pd_baseclass << 16) |
-               (pcidev[devind].pd_subclass << 8) |
-               pcidev[devind].pd_infclass;
-       for (i= 0; i<aclp->rsp_nr_class; i++)
+/*===========================================================================*
+ *                             _pci_get_bar                                 *
+ *===========================================================================*/
+int
+_pci_get_bar(int devind, int port, u32_t *base, u32_t *size,
+       int *ioflag)
+{
+       int i, reg;
+
+       if (devind < 0 || devind >= nr_pcidev)
+               return EINVAL;
+
+       for (i= 0; i < pcidev[devind].pd_bar_nr; i++)
        {
-               if (aclp->rsp_class[i].pciclass ==
-                       (class_id & aclp->rsp_class[i].mask))
+               reg= PCI_BAR+4*pcidev[devind].pd_bar[i].pb_nr;
+
+               if (reg == port)
                {
-                       return TRUE;
+                       if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
+                               return EINVAL;
+
+                       *base= pcidev[devind].pd_bar[i].pb_base;
+                       *size= pcidev[devind].pd_bar[i].pb_size;
+                       *ioflag=
+                               !!(pcidev[devind].pd_bar[i].pb_flags & PBF_IO);
+                       return OK;
                }
        }
+       return EINVAL;
+}
 
-       return FALSE;
+/*===========================================================================*
+ *                             _pci_attr_r8                                 *
+ *===========================================================================*/
+int
+_pci_attr_r8(int devind, int port, u8_t *vp)
+{
+       if (devind < 0 || devind >= nr_pcidev)
+               return EINVAL;
+       if (port < 0 || port > 256-1)
+               return EINVAL;
+
+       *vp= __pci_attr_r8(devind, port);
+       return OK;
 }
 
 /*===========================================================================*
- *                             print_hyper_cap                              *
+ *                             _pci_attr_r16                                *
  *===========================================================================*/
-static void print_hyper_cap(int devind, u8_t capptr)
-{ 
-       u32_t v;
-       u16_t cmd;
-       int type0, type1;
+int
+_pci_attr_r16(int devind, int port, u16_t *vp)
+{
+       if (devind < 0 || devind >= nr_pcidev)
+               return EINVAL;
+       if (port < 0 || port > 256-2)
+               return EINVAL;
 
-       printf("\n");
-       v= pci_attr_r32_u(devind, capptr);
-       printf("print_hyper_cap: @0x%x, off 0 (cap):", capptr);
-       cmd= (v >> 16) & 0xffff;
-#if 0
-       if (v & 0x10000)
-       {
-               printf(" WarmReset");
-               v &= ~0x10000;
-       }
-       if (v & 0x20000)
-       {
-               printf(" DblEnded");
-               v &= ~0x20000;
-       }
-       printf(" DevNum %d", (v & 0x7C0000) >> 18);
-       v &= ~0x7C0000;
-#endif
-       type0= (cmd & 0xE000) >> 13;
-       type1= (cmd & 0xF800) >> 11;
-       if (type0 == 0 || type0 == 1)
-       {
-               printf("Capability Type: %s\n",
-                       type0 == 0 ? "Slave or Primary Interface" :
-                       "Host or Secondary Interface");
-               cmd &= ~0xE000;
-       }
-       else
-       {
-               printf(" Capability Type 0x%x", type1);
-               cmd &= ~0xF800;
-       }
-       if (cmd)
-               printf(" undecoded 0x%x\n", cmd);
+       *vp= __pci_attr_r16(devind, port);
+       return OK;
+}
 
-#if 0
-       printf("print_hyper_cap: off 4 (ctl): 0x%x\n", 
-               pci_attr_r32_u(devind, capptr+4));
-       printf("print_hyper_cap: off 8 (freq/rev): 0x%x\n", 
-               pci_attr_r32_u(devind, capptr+8));
-       printf("print_hyper_cap: off 12 (cap): 0x%x\n", 
-               pci_attr_r32_u(devind, capptr+12));
-       printf("print_hyper_cap: off 16 (buf count): 0x%x\n", 
-               pci_attr_r32_u(devind, capptr+16));
-       v= pci_attr_r32_u(devind, capptr+20);
-       printf("print_hyper_cap: @0x%x, off 20 (bus nr): ", 
-               capptr+20);
-       printf("prim %d", v & 0xff);
-       printf(", sec %d", (v >> 8) & 0xff);
-       printf(", sub %d", (v >> 16) & 0xff);
-       if (v >> 24)
-               printf(", reserved %d", (v >> 24) & 0xff);
-       printf("\n");
-       printf("print_hyper_cap: off 24 (type): 0x%x\n", 
-               pci_attr_r32_u(devind, capptr+24));
-#endif
+/*===========================================================================*
+ *                             _pci_attr_r32                                *
+ *===========================================================================*/
+int
+_pci_attr_r32(int devind, int port, u32_t *vp)
+{
+       if (devind < 0 || devind >= nr_pcidev)
+               return EINVAL;
+       if (port < 0 || port > 256-4)
+               return EINVAL;
+
+       *vp= __pci_attr_r32(devind, port);
+       return OK;
 }
 
-/*
- * $PchId: pci.c,v 1.7 2003/08/07 09:06:51 philip Exp $
- */
+/*===========================================================================*
+ *                             _pci_attr_w8                                 *
+ *===========================================================================*/
+int
+_pci_attr_w8(int devind, int port, u8_t value)
+{
+       if (devind < 0 || devind >= nr_pcidev)
+               return EINVAL;
+       if (port < 0 || port > 256-1)
+               return EINVAL;
+
+       __pci_attr_w8(devind, port, value);
+       return OK;
+}
+
+/*===========================================================================*
+ *                             _pci_attr_w16                                *
+ *===========================================================================*/
+int
+_pci_attr_w16(int devind, int port, u16_t value)
+{
+       if (devind < 0 || devind >= nr_pcidev)
+               return EINVAL;
+       if (port < 0 || port > 256-2)
+               return EINVAL;
+
+       __pci_attr_w16(devind, port, value);
+       return OK;
+}
+
+/*===========================================================================*
+ *                             _pci_attr_w32                                *
+ *===========================================================================*/
+int
+_pci_attr_w32(int devind, int port, u32_t value)
+{
+       if (devind < 0 || devind >= nr_pcidev)
+               return EINVAL;
+       if (port < 0 || port > 256-4)
+               return EINVAL;
+
+       __pci_attr_w32(devind, port, value);
+       return OK;
+}
index 1aac8d373cc5083a52dfaf8985930d916351d123..e3c6fd383b96743e2828108ef0171fcdf2e1cb32 100644 (file)
@@ -4,36 +4,23 @@ pci.h
 Created:       Jan 2000 by Philip Homburg <philip@cs.vu.nl>
 */
 
-#include <minix/drivers.h>
-#include <minix/driver.h>
-#include <minix/rs.h>
-
-/* tempory functions: to be replaced later (see pci_intel.h) */
-unsigned pci_inb(u16_t port);
-unsigned pci_inw(u16_t port);
-unsigned pci_inl(u16_t port);
-
-void pci_outb(u16_t port, u8_t value);
-void pci_outw(u16_t port, u16_t value);
-void pci_outl(u16_t port, u32_t value);
-
 struct pci_vendor
 {
        u16_t vid;
-       char *name;
+       const char *name;
 };
 
 struct pci_device
 {
        u16_t vid;
        u16_t did;
-       char *name;
+       const char *name;
 };
 
 struct pci_baseclass
 {
        u8_t baseclass;
-       char *name;
+       const char *name;
 };
 
 struct pci_subclass
@@ -41,7 +28,7 @@ struct pci_subclass
        u8_t baseclass;
        u8_t subclass;
        u16_t infclass;
-       char *name;
+       const char *name;
 };
 
 struct pci_intel_ctrl
@@ -83,6 +70,8 @@ struct pci_acl
 /* Still needed? */
 #define PCI_AGPB_VIA   3       /* VIA compatible AGP bridge */
 
+extern int debug;
+
 extern struct pci_vendor pci_vendor_table[];
 extern struct pci_device pci_device_table[];
 extern struct pci_baseclass pci_baseclass_table[];
@@ -92,24 +81,36 @@ extern struct pci_intel_ctrl pci_intel_ctrl[];
 #endif
 extern struct pci_isabridge pci_isabridge[];
 extern struct pci_pcibridge pci_pcibridge[];
+extern struct pci_acl pci_acl[NR_DRIVERS];
 
 /* Function prototypes. */
 int sef_cb_init_fresh(int type, sef_init_info_t *info);
 int map_service(struct rprocpub *rpub);
-int pci_reserve_a(int devind, endpoint_t proc, struct rs_pci *aclp);
-void pci_release(endpoint_t proc);
-int pci_first_dev_a(struct rs_pci *aclp, int *devindp, u16_t *vidp,
+
+int _pci_reserve(int devind, endpoint_t proc, struct rs_pci *aclp);
+void _pci_release(endpoint_t proc);
+
+int _pci_first_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp,
        u16_t *didp);
-int pci_next_dev_a(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t
+int _pci_next_dev(struct rs_pci *aclp, int *devindp, u16_t *vidp, u16_t
        *didp);
+int _pci_find_dev(u8_t bus, u8_t dev, u8_t func, int *devindp);
 
-int pci_attr_r8_s(int devind, int port, u8_t *vp);
-int pci_attr_r32_s(int devind, int port, u32_t *vp);
-int pci_get_bar_s(int devind, int port, u32_t *base, u32_t *size, int
-       *ioflag);
-int pci_slot_name_s(int devind, char **cpp);
-int pci_ids_s(int devind, u16_t *vidp, u16_t *didp);
+void _pci_rescan_bus(u8_t busnr);
+const char *_pci_dev_name(u16_t vid, u16_t did);
 
-/*
- * $PchId: pci.h,v 1.4 2001/12/06 20:21:22 philip Exp $
- */
+
+int _pci_get_bar(int devind, int port, u32_t *base, u32_t *size, int
+       *ioflag);
+int _pci_slot_name(int devind, char **cpp);
+int _pci_ids(int devind, u16_t *vidp, u16_t *didp);
+
+/* PCI Config Read functions */
+int _pci_attr_r8(int devind, int port, u8_t *vp);
+int _pci_attr_r16(int devind, int port, u16_t *vp);
+int _pci_attr_r32(int devind, int port, u32_t *vp);
+
+/* PCI Config Write functions */
+int _pci_attr_w8(int devind, int port, u8_t value);
+int _pci_attr_w16(int devind, int port, u16_t value);
+int _pci_attr_w32(int devind, int port, u32_t value);
index e468f2948c4619d2e0af87307e3862c157aae10e..3182282ee82de68c5cafc389ed2b70f7b2487ac0 100644 (file)
@@ -14,10 +14,9 @@ See the Linux PCI ID Repository <http://pciids.sourceforge.net/>.
  */
 
 #include <minix/drivers.h>
+#include <minix/rs.h>
+
 #include "pci.h"
-#if __minix_vmd
-#include "config.h"
-#endif
 
 struct pci_vendor pci_vendor_table[]=
 {