summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authordmick <none@none>2005-10-31 14:45:33 -0800
committerdmick <none@none>2005-10-31 14:45:33 -0800
commitebf3afa8e82eb30c81bf5c19510ef97a2c50a82f (patch)
treeca19a5a863ebbee5c06c3489a32c0a11fc8e6ab2 /usr/src
parent1cad4cbd461a7ad11aad36231778ebcd0d4f256a (diff)
downloadillumos-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.c151
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;
}