Date: Mon, 19 Mar 2012 22:26:02 +0000 (UTC) From: Jung-uk Kim <jkim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r233214 - stable/8/sys/dev/pci Message-ID: <201203192226.q2JMQ2oi089271@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jkim Date: Mon Mar 19 22:26:02 2012 New Revision: 233214 URL: http://svn.freebsd.org/changeset/base/233214 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/8/sys/dev/pci/pci.c Directory Properties: stable/8/sys/ (props changed) Modified: stable/8/sys/dev/pci/pci.c ============================================================================== --- stable/8/sys/dev/pci/pci.c Mon Mar 19 22:23:52 2012 (r233213) +++ stable/8/sys/dev/pci/pci.c Mon Mar 19 22:26:02 2012 (r233214) @@ -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 } }; @@ -2790,12 +2801,18 @@ ehci_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) && @@ -2804,18 +2821,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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203192226.q2JMQ2oi089271>