svn commit: r233210 - stable/9/sys/dev/pci
Jung-uk Kim
jkim at FreeBSD.org
Mon Mar 19 22:08:14 UTC 2012
Author: jkim
Date: Mon Mar 19 22:08:13 2012
New Revision: 233210
URL: http://svn.freebsd.org/changeset/base/233210
Log:
MFC: r232991
Add a PCI quirk to ignore PCI map registers from configuration space.
This works around a resource conflict, e. g., MSI K9AGM2 motherboard.
Modified:
stable/9/sys/dev/pci/pci.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/dev/pci/pci.c
==============================================================================
--- stable/9/sys/dev/pci/pci.c Mon Mar 19 21:57:31 2012 (r233209)
+++ stable/9/sys/dev/pci/pci.c Mon Mar 19 22:08:13 2012 (r233210)
@@ -188,6 +188,7 @@ struct pci_quirk {
#define PCI_QUIRK_MAP_REG 1 /* PCI map register in weird place */
#define PCI_QUIRK_DISABLE_MSI 2 /* MSI/MSI-X doesn't work */
#define PCI_QUIRK_ENABLE_MSI_VM 3 /* Older chipset in VM where MSI works */
+#define PCI_QUIRK_UNMAP_REG 4 /* Ignore PCI map register */
int arg1;
int arg2;
};
@@ -236,6 +237,16 @@ static const struct pci_quirk const pci_
*/
{ 0x12378086, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 },
+ /*
+ * HPET MMIO base address may appear in Bar1 for AMD SB600 SMBus
+ * controller depending on SoftPciRst register (PM_IO 0x55 [7]).
+ * It prevents us from attaching hpet(4) when the bit is unset.
+ * Note this quirk only affects SB600 revision A13 and earlier.
+ * For SB600 A21 and later, firmware must set the bit to hide it.
+ * For SB700 and later, it is unused and hardcoded to zero.
+ */
+ { 0x43851002, PCI_QUIRK_UNMAP_REG, 0x14, 0 },
+
{ 0 }
};
@@ -3023,12 +3034,18 @@ xhci_early_takeover(device_t self)
void
pci_add_resources(device_t bus, device_t dev, int force, uint32_t prefetchmask)
{
- struct pci_devinfo *dinfo = device_get_ivars(dev);
- pcicfgregs *cfg = &dinfo->cfg;
- struct resource_list *rl = &dinfo->resources;
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+ struct resource_list *rl;
const struct pci_quirk *q;
+ uint32_t devid;
int i;
+ dinfo = device_get_ivars(dev);
+ cfg = &dinfo->cfg;
+ rl = &dinfo->resources;
+ devid = (cfg->device << 16) | cfg->vendor;
+
/* ATA devices needs special map treatment */
if ((pci_get_class(dev) == PCIC_STORAGE) &&
(pci_get_subclass(dev) == PCIS_STORAGE_IDE) &&
@@ -3037,18 +3054,29 @@ pci_add_resources(device_t bus, device_t
!pci_read_config(dev, PCIR_BAR(2), 4))) )
pci_ata_maps(bus, dev, rl, force, prefetchmask);
else
- for (i = 0; i < cfg->nummaps;)
+ for (i = 0; i < cfg->nummaps;) {
+ /*
+ * Skip quirked resources.
+ */
+ for (q = &pci_quirks[0]; q->devid != 0; q++)
+ if (q->devid == devid &&
+ q->type == PCI_QUIRK_UNMAP_REG &&
+ q->arg1 == PCIR_BAR(i))
+ break;
+ if (q->devid != 0) {
+ i++;
+ continue;
+ }
i += pci_add_map(bus, dev, PCIR_BAR(i), rl, force,
prefetchmask & (1 << i));
+ }
/*
* Add additional, quirked resources.
*/
- for (q = &pci_quirks[0]; q->devid; q++) {
- if (q->devid == ((cfg->device << 16) | cfg->vendor)
- && q->type == PCI_QUIRK_MAP_REG)
+ for (q = &pci_quirks[0]; q->devid != 0; q++)
+ if (q->devid == devid && q->type == PCI_QUIRK_MAP_REG)
pci_add_map(bus, dev, q->arg1, rl, force, 0);
- }
if (cfg->intpin > 0 && PCI_INTERRUPT_VALID(cfg->intline)) {
#ifdef __PCI_REROUTE_INTERRUPT
More information about the svn-src-stable-9
mailing list