diff options
author | dmick <none@none> | 2005-10-31 14:45:33 -0800 |
---|---|---|
committer | dmick <none@none> | 2005-10-31 14:45:33 -0800 |
commit | ebf3afa8e82eb30c81bf5c19510ef97a2c50a82f (patch) | |
tree | ca19a5a863ebbee5c06c3489a32c0a11fc8e6ab2 /usr/src | |
parent | 1cad4cbd461a7ad11aad36231778ebcd0d4f256a (diff) | |
download | illumos-joyent-ebf3afa8e82eb30c81bf5c19510ef97a2c50a82f.tar.gz |
6333242 pci I/O address allocation requires 1K alignment; fails
6325175 delay in adding "unconfigured" PCI nodes to tree breaks interrupt routing
6332693 display adapters' nodes should set the device_type=display property
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/i86pc/io/pci/pci_boot.c | 151 |
1 files changed, 23 insertions, 128 deletions
diff --git a/usr/src/uts/i86pc/io/pci/pci_boot.c b/usr/src/uts/i86pc/io/pci/pci_boot.c index 19ee4071e2..0d6d9797df 100644 --- a/usr/src/uts/i86pc/io/pci/pci_boot.c +++ b/usr/src/uts/i86pc/io/pci/pci_boot.c @@ -197,109 +197,6 @@ create_root_bus_dip(uchar_t bus) } /* - * returns: 0 = not configured, 1 = configured, -1 = error - */ -static int -func_configured(uchar_t bus, uchar_t dev, uchar_t func) -{ - uint16_t cmdreg; - uint32_t bar_low, bar_high, size_low; - uint8_t bar_base, bar_end; - int io_enabled, mem_enabled; - int configured; - - - /* - * Determine PCI config space type from header and - * adjust address and count of Base Address Registers - */ - switch (pci_getb(bus, dev, func, PCI_CONF_HEADER) & - PCI_HEADER_TYPE_M) { - case PCI_HEADER_ZERO: - bar_base = PCI_CONF_BASE0; - bar_end = bar_base + PCI_BASE_NUM * sizeof (uint32_t); - break; - case PCI_HEADER_PPB: - bar_base = PCI_CONF_BASE0; - bar_end = bar_base + PCI_BCNF_BASE_NUM * sizeof (uint32_t); - break; - case PCI_HEADER_CARDBUS: - bar_base = PCI_CBUS_SOCK_REG; - bar_end = bar_base + PCI_CBUS_BASE_NUM * sizeof (uint32_t); - break; - default: - /* invalid header value - return error */ - return (-1); - } - - cmdreg = pci_getw(bus, dev, func, PCI_CONF_COMM); - io_enabled = cmdreg & PCI_COMM_IO; - mem_enabled = cmdreg & PCI_COMM_MAE; - /* - * If neither I/O or memory-access are enabled, this - * device is not configured - */ - if (!io_enabled && !mem_enabled) - return (0); - - /* - * Start out believing the device is configured and scan - * the base address registers until we find a valid BAR - * that is unprogrammed. If all valid BARs are programmed, - * the device is assumed to be configured. - * - * Valid BARs have a non-zero size and are unprogrammed - * if they have a zero value. Note that the actual value - * of the BAR size doesn't matter and isn't calculated; - * if any bits in the probed size mask are non-zero, that - * indicates a non-zero size. - */ - configured = 1; - while (configured && bar_base < bar_end) { - /* disable device decoding while probing base register */ - pci_putw(bus, dev, func, PCI_CONF_COMM, - cmdreg & ~(PCI_COMM_IO | PCI_COMM_MAE)); - - bar_high = 0; /* default to 32-bit */ - /* probe the BAR for size */ - bar_low = pci_getl(bus, dev, func, bar_base); - pci_putl(bus, dev, func, bar_base, 0xffffffff); - size_low = pci_getl(bus, dev, func, bar_base); - pci_putl(bus, dev, func, bar_base, bar_low); - bar_base += sizeof (uint32_t); - - if (bar_low & PCI_BASE_SPACE_IO) { - bar_low &= PCI_BASE_IO_ADDR_M; - size_low &= PCI_BASE_IO_ADDR_M; - if (size_low != 0) - configured = io_enabled && (bar_low != 0); - } else { - if ((bar_low & PCI_BASE_TYPE_M) == PCI_BASE_TYPE_ALL) { - /* 64-bit case */ - bar_high = pci_getl(bus, dev, func, bar_base); - bar_base += sizeof (uint32_t); - } - bar_low &= PCI_BASE_M_ADDR_M; - size_low &= PCI_BASE_M_ADDR_M; - /* - * Omit test of upper 32-bits of size; some 64-bit - * devices may not properly implement the top 32-bits - * of the size; if a card appears that requests - * 4GB or more, this will need to be revisited. - */ - if (size_low != 0) - configured = mem_enabled && - ((bar_low != 0) || (bar_high != 0)); - } - /* restore the enable bits for this device */ - pci_putw(bus, dev, func, PCI_CONF_COMM, cmdreg); - } - - return (configured); -} - - -/* * For any fixed configuration (often compatability) pci devices * and those with their own expansion rom, create device nodes * to hold the already configured device details. @@ -326,7 +223,6 @@ enumerate_bus_devs(uchar_t bus, int config_op) for (dev = 0; dev < max_dev_pci; dev++) { nfunc = 1; for (func = 0; func < nfunc; func++) { - int configured; dcmn_err(CE_NOTE, "probing dev 0x%x, func 0x%x", dev, func); @@ -352,22 +248,16 @@ enumerate_bus_devs(uchar_t bus, int config_op) nfunc = 8; } - configured = func_configured(bus, dev, func); - - /* - * If the device is not configured and we're in the - * first pass (CONFIG_INFO), skip the device and - * it will be programmed/enumerated on the second pass - * (CONFIG_NEW). Likewise, if a device is configured, - * skip it on the second pass - */ - if ((configured < 0) || - (!configured && config_op != CONFIG_NEW) || - (configured && config_op != CONFIG_INFO)) - continue; - - dip = new_func_pci(bus, dev, func, header, venid, - config_op); + if (config_op == CONFIG_INFO) { + /* + * Create the node, unconditionally, on the + * first pass only. It may still need + * resource assignment, which will be + * done on the second, CONFIG_NEW, pass. + */ + dip = new_func_pci(bus, dev, func, header, + venid, config_op); + } /* * If dip isn't null, reprogram the device later. * This only happens for CONFIG_INFO case. @@ -575,6 +465,11 @@ new_func_pci(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header, (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "unit-address", unitaddr); + /* add device_type for display nodes */ + if (is_display(classcode)) { + (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, + "device_type", "display"); + } /* add special stuff for header type */ if ((header & PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) { uchar_t mingrant = pci_getb(bus, dev, func, PCI_CONF_MIN_G); @@ -814,7 +709,7 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, pci_regspec_t regs[16] = {{0}}; pci_regspec_t assigned[15] = {{0}}; - int nreg, nasgn, configured, enable = 0; + int nreg, nasgn, enable = 0; io_res = &pci_bus_res[bus].io_ports; mem_res = &pci_bus_res[bus].mem_space; @@ -834,10 +729,8 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, header = pci_getb(bus, dev, func, PCI_CONF_HEADER) & PCI_HEADER_TYPE_M; /* Fetch PCI command, disable I/O and memory */ cmd_reg = pci_getw(bus, dev, func, PCI_CONF_COMM); - configured = cmd_reg & (PCI_COMM_IO | PCI_COMM_MAE); pci_putw(bus, dev, func, PCI_CONF_COMM, cmd_reg & ~(PCI_COMM_IO | PCI_COMM_MAE)); - ASSERT(configured || config_op == CONFIG_NEW); switch (header) { case PCI_HEADER_ZERO: @@ -923,7 +816,7 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, reprogram = 1; } else if (*io_res && base == 0) { base = (uint_t)memlist_find(io_res, - (uint64_t)len, (uint64_t)0x400); + (uint64_t)len, (uint64_t)0x4); if (base != 0) { /* XXX need to worry about 64-bit? */ pci_putl(bus, dev, func, offset, @@ -933,8 +826,9 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, } if (base == 0) { cmn_err(CE_WARN, "failed to program" - " IO space 0x%x for [%d/%d/%d]", - len, bus, dev, func); + " IO space [%d/%d/%d] BAR@0x%x " + " length 0x%x\n", + bus, dev, func, offset, len); } else enable |= PCI_COMM_IO; } @@ -996,8 +890,9 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, if (base == 0) { cmn_err(CE_WARN, "failed to program " - "mem space 0x%x for [%d/%d/%d]", - len, bus, dev, func); + "mem space [%d/%d/%d] BAR@0x%x" + " length 0x%x\n", + bus, dev, func, offset, len); } else enable |= PCI_COMM_MAE; } |