Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Number PCI busses using a simple pre-order numbe...



details:   https://anonhg.NetBSD.org/src/rev/82a3597eb246
branches:  trunk
changeset: 534603:82a3597eb246
user:      augustss <augustss%NetBSD.org@localhost>
date:      Tue Jul 30 15:00:03 2002 +0000

description:
Number PCI busses using a simple pre-order numbering instead of
some strange binary split numbering that doesn't work with multiple
bridges on the same bus, nor with deeply nested bridges.

diffstat:

 sys/dev/pci/pciconf.c |  48 ++++++++++++++++++++++++++----------------------
 1 files changed, 26 insertions(+), 22 deletions(-)

diffs (118 lines):

diff -r dd8fdfa5c16b -r 82a3597eb246 sys/dev/pci/pciconf.c
--- a/sys/dev/pci/pciconf.c     Tue Jul 30 14:57:31 2002 +0000
+++ b/sys/dev/pci/pciconf.c     Tue Jul 30 15:00:03 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pciconf.c,v 1.16 2002/06/27 00:59:21 briggs Exp $      */
+/*     $NetBSD: pciconf.c,v 1.17 2002/07/30 15:00:03 augustss Exp $    */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pciconf.c,v 1.16 2002/06/27 00:59:21 briggs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pciconf.c,v 1.17 2002/07/30 15:00:03 augustss Exp $");
 
 #include "opt_pci.h"
 
@@ -91,8 +91,6 @@
 #define MAX_CONF_MEM   (3 * MAX_CONF_DEV)      /* Avg. 3 per device -- Arb. */
 #define MAX_CONF_IO    (3 * MAX_CONF_DEV)      /* Avg. 1 per device -- Arb. */
 
-#define PCI_BUSNO_SPACING      (1 << 5)
-
 struct _s_pciconf_bus_t;                       /* Forward declaration */
 
 typedef struct _s_pciconf_dev_t {
@@ -119,7 +117,6 @@
        int             busno;
        int             next_busno;
        int             last_busno;
-       int             busno_spacing;
        int             max_mingnt;
        int             min_maxlat;
        int             cacheline_size;
@@ -296,21 +293,25 @@
 alloc_busno(pciconf_bus_t *parent, pciconf_bus_t *pb)
 {
        pb->busno = parent->next_busno;
-       if (parent->next_busno + parent->busno_spacing > parent->last_busno)
-               panic("Too many PCI busses on bus %d", parent->busno);
-       parent->next_busno = parent->next_busno + parent->busno_spacing;
-       pb->next_busno = pb->busno+1;
-       pb->busno_spacing = parent->busno_spacing >> 1;
-       if (!pb->busno_spacing)
-               panic("PCI busses nested too deep.");
-       pb->last_busno = parent->next_busno - 1;
+       pb->next_busno = pb->busno + 1;
+}
+
+static void
+set_busreg(pci_chipset_tag_t pc, pcitag_t tag, int prim, int sec, int sub)
+{
+       pcireg_t        busreg;
+
+       busreg  =  prim << PCI_BRIDGE_BUS_PRIMARY_SHIFT;
+       busreg |=   sec << PCI_BRIDGE_BUS_SECONDARY_SHIFT;
+       busreg |=   sub << PCI_BRIDGE_BUS_SUBORDINATE_SHIFT;
+       pci_conf_write(pc, tag, PCI_BRIDGE_BUS_REG, busreg);
 }
 
 static pciconf_bus_t *
 query_bus(pciconf_bus_t *parent, pciconf_dev_t *pd, int dev)
 {
        pciconf_bus_t   *pb;
-       pcireg_t        busreg, io, pmem;
+       pcireg_t        io, pmem;
        pciconf_win_t   *pi, *pm;
 
        pb = malloc (sizeof (pciconf_bus_t), M_DEVBUF, M_NOWAIT);
@@ -320,14 +321,8 @@
        pb->cacheline_size = parent->cacheline_size;
        pb->parent_bus = parent;
        alloc_busno(parent, pb);
-       if (pci_conf_debug)
-               printf("PCI bus bridge covers busses %d-%d\n",
-                       pb->busno, pb->last_busno);
 
-       busreg  =  parent->busno << PCI_BRIDGE_BUS_PRIMARY_SHIFT;
-       busreg |=      pb->busno << PCI_BRIDGE_BUS_SECONDARY_SHIFT;
-       busreg |= pb->last_busno << PCI_BRIDGE_BUS_SUBORDINATE_SHIFT;
-       pci_conf_write(parent->pc, pd->tag, PCI_BRIDGE_BUS_REG, busreg);
+       set_busreg(parent->pc, pd->tag, parent->busno, pb->busno, 0xff);
 
        pb->swiz = parent->swiz + dev;
 
@@ -359,6 +354,15 @@
                goto err;
        }
 
+       /* We have found all subordinate busses now, reprogram busreg. */
+       pb->last_busno = pb->next_busno-1;
+       parent->next_busno = pb->next_busno;
+       set_busreg(parent->pc, pd->tag, parent->busno, pb->busno,
+                  pb->last_busno);
+       if (pci_conf_debug)
+               printf("PCI bus bridge (parent %d) covers busses %d-%d\n",
+                       parent->busno, pb->busno, pb->last_busno);
+
        if (pb->io_total > 0) {
                if (parent->niowin >= MAX_CONF_IO) {
                        printf("pciconf: too many I/O windows\n");
@@ -1046,7 +1050,6 @@
 
        pb = malloc (sizeof (pciconf_bus_t), M_DEVBUF, M_NOWAIT);
        pb->busno = firstbus;
-       pb->busno_spacing = PCI_BUSNO_SPACING;
        pb->next_busno = pb->busno + 1;
        pb->last_busno = 255;
        pb->cacheline_size = cacheline_size;
@@ -1065,6 +1068,7 @@
        pb->io_total = pb->mem_total = pb->pmem_total = 0;
 
        rv = probe_bus(pb);
+       pb->last_busno = pb->next_busno-1;
        if (rv == 0) {
                rv = configure_bus(pb);
        }



Home | Main Index | Thread Index | Old Index