summaryrefslogtreecommitdiffstats
path: root/sys/dev/pccbb
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2004-04-23 05:25:13 +0000
committerimp <imp@FreeBSD.org>2004-04-23 05:25:13 +0000
commit800bba64fe69c02c7b292d0d136953ef3749cdc8 (patch)
treef5b1357f133ca320a4d82af82e8e7bdeb87c1813 /sys/dev/pccbb
parentc8457a17a5edc36efcd781535b1388be1a70b0a2 (diff)
downloadFreeBSD-src-800bba64fe69c02c7b292d0d136953ef3749cdc8.zip
FreeBSD-src-800bba64fe69c02c7b292d0d136953ef3749cdc8.tar.gz
Start programming the bus numbers for the pci<->cardbus. When the
secondary bus is 0, we program the primary bus, the secondary bus and the suborindate bus. This isn't ideal, since we start at parent_bus + 1 and store this in a static. Ideally, we'd walk the tree and assign bus numbers. However, that's harder to accomplish without some help from the bus layer which we're not planning on doing that until 6. This fixes my CardBus problems on my Sony PCG-Z1WA, and might fix the Dells that have had problems.
Diffstat (limited to 'sys/dev/pccbb')
-rw-r--r--sys/dev/pccbb/pccbb.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c
index 9d690bb..527cef9 100644
--- a/sys/dev/pccbb/pccbb.c
+++ b/sys/dev/pccbb/pccbb.c
@@ -683,9 +683,12 @@ cbb_print_config(device_t dev)
static int
cbb_attach(device_t brdev)
{
+ static int curr_bus_number = 1; /* XXX EVILE BAD (see below) */
struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(brdev);
- int rid;
+ int rid, bus, pribus;
+ device_t parent;
+ parent = device_get_parent(brdev);
mtx_init(&sc->mtx, device_get_nameunit(brdev), "cbb", MTX_DEF);
cv_init(&sc->cv, "cbb cv");
sc->chipset = cbb_chipset(pci_get_devid(brdev), NULL);
@@ -759,6 +762,32 @@ cbb_attach(device_t brdev)
sc->exca.chipset = EXCA_CARDBUS;
cbb_chipinit(sc);
+ /*
+ * This is a gross hack. We should be scanning the entire pci
+ * tree, assigning bus numbers in a way such that we (1) can
+ * reserve 1 extra bus just in case and (2) all sub busses
+ * are in an appropriate range.
+ */
+ bus = pci_read_config(brdev, PCIR_SECBUS_2, 1);
+ pribus = pcib_get_bus(parent);
+ DEVPRINTF((brdev, "Secondary bus is %d\n", bus));
+ if (bus == 0) {
+ if (curr_bus_number < pribus)
+ curr_bus_number = pribus + 1;
+ if (pci_read_config(brdev, PCIR_PRIBUS_2, 1) != pribus) {
+ DEVPRINTF((brdev, "Setting primary bus to %d\n", pribus));
+ pci_write_config(brdev, PCIR_PRIBUS_2, pribus, 1);
+ }
+ bus = curr_bus_number;
+ DEVPRINTF((brdev, "Secondary bus set to %d subbus %d\n", bus,
+ bus + 1));
+ sc->secbus = bus;
+ sc->subbus = bus + 1;
+ pci_write_config(brdev, PCIR_SECBUS_2, bus, 1);
+ pci_write_config(brdev, PCIR_SUBBUS_2, bus + 1, 1);
+ curr_bus_number += 2;
+ }
+
/* attach children */
sc->cbdev = device_add_child(brdev, "cardbus", -1);
if (sc->cbdev == NULL)
OpenPOWER on IntegriCloud