From owner-svn-src-head@FreeBSD.ORG Fri Mar 18 12:13:04 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D9B061065676; Fri, 18 Mar 2011 12:13:04 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C93408FC1F; Fri, 18 Mar 2011 12:13:04 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p2ICD4AR066259; Fri, 18 Mar 2011 12:13:04 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p2ICD4Vr066256; Fri, 18 Mar 2011 12:13:04 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201103181213.p2ICD4Vr066256@svn.freebsd.org> From: John Baldwin Date: Fri, 18 Mar 2011 12:13:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r219737 - head/sys/dev/pci X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Mar 2011 12:13:04 -0000 Author: jhb Date: Fri Mar 18 12:13:04 2011 New Revision: 219737 URL: http://svn.freebsd.org/changeset/base/219737 Log: Fix a few issues with HyperTransport devices and MSI interrupts: - Always enable the HyperTransport MSI mapping window for HyperTransport to PCI bridges (these show up as HyperTransport slave devices). The mapping windows in PCI-PCI bridges are enabled by existing code in the PCI-PCI bridge driver as MSI requests propagate up the device tree, but Host-PCI bridges don't really show up in that tree. - If the PCI device at domain 0 bus 0 slot 0 function 0 is not a HyperTransport device, then blacklist MSI on any other HT devices in the system. Linux has a similar quirk. PR: kern/155442 Tested by: Zack Dannar zdannar of gmail MFC after: 1 week Modified: head/sys/dev/pci/pci.c head/sys/dev/pci/pcivar.h Modified: head/sys/dev/pci/pci.c ============================================================================== --- head/sys/dev/pci/pci.c Fri Mar 18 12:09:27 2011 (r219736) +++ head/sys/dev/pci/pci.c Fri Mar 18 12:13:04 2011 (r219737) @@ -236,7 +236,7 @@ struct pci_quirk pci_quirks[] = { struct devlist pci_devq; uint32_t pci_generation; uint32_t pci_numdevs = 0; -static int pcie_chipset, pcix_chipset; +static int ht_chipset, pcie_chipset, pcix_chipset; /* sysctl vars */ SYSCTL_NODE(_hw, OID_AUTO, pci, CTLFLAG_RD, 0, "PCI bus tuning parameters"); @@ -612,10 +612,24 @@ pci_read_extcap(device_t pcib, pcicfgreg cfg->pp.pp_data = ptr + PCIR_POWER_DATA; } break; -#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) case PCIY_HT: /* HyperTransport */ /* Determine HT-specific capability type. */ val = REG(ptr + PCIR_HT_COMMAND, 2); + + if ((val & 0xe000) == PCIM_HTCAP_SLAVE) { + cfg->ht.ht_slave = ptr; + + /* + * If device 0:0:0:0 is an HT slave, + * then this is an HT chipset and MSI + * should be enabled for HT devices. + */ + if (cfg->domain == 0 && cfg->bus == 0 && + cfg->slot == 0 && cfg->func == 0) + ht_chipset = 1; + } + +#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) switch (val & PCIM_HTCMD_CAP_MASK) { case PCIM_HTCAP_MSI_MAPPING: if (!(val & PCIM_HTCMD_MSI_FIXED)) { @@ -627,7 +641,7 @@ pci_read_extcap(device_t pcib, pcicfgreg 4); if (addr != MSI_INTEL_ADDR_BASE) device_printf(pcib, - "HT Bridge at pci%d:%d:%d:%d has non-default MSI window 0x%llx\n", + "HT device at pci%d:%d:%d:%d has non-default MSI window 0x%llx\n", cfg->domain, cfg->bus, cfg->slot, cfg->func, (long long)addr); @@ -639,8 +653,8 @@ pci_read_extcap(device_t pcib, pcicfgreg cfg->ht.ht_msiaddr = addr; break; } - break; #endif + break; case PCIY_MSI: /* PCI MSI */ cfg->msi.msi_location = ptr; cfg->msi.msi_ctrl = REG(ptr + PCIR_MSI_CTRL, 2); @@ -696,6 +710,24 @@ pci_read_extcap(device_t pcib, pcicfgreg break; } } + + +#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) + /* + * Enable the MSI mapping window for all HyperTransport + * slaves. PCI-PCI bridges have their windows enabled via + * PCIB_MAP_MSI(). + */ + if (cfg->ht.ht_slave != 0 && cfg->ht.ht_msimap != 0 && + !(cfg->ht.ht_msictrl & PCIM_HTCMD_MSI_ENABLE)) { + device_printf(pcib, + "Enabling MSI window for HyperTransport slave at pci%d:%d:%d:%d\n", + cfg->domain, cfg->bus, cfg->slot, cfg->func); + cfg->ht.ht_msictrl |= PCIM_HTCMD_MSI_ENABLE; + WREG(cfg->ht.ht_msimap + PCIR_HT_COMMAND, cfg->ht.ht_msictrl, + 2); + } +#endif /* REG and WREG use carry through to next functions */ } @@ -1837,6 +1869,13 @@ pci_msi_device_blacklisted(device_t dev) q->type == PCI_QUIRK_DISABLE_MSI) return (1); } + + /* + * Blacklist HyperTransport devices if the device at 0:0:0:0 + * is not a HyperTransport slave. + */ + if (!ht_chipset && pci_find_extcap(dev, PCIY_HT, NULL) == 0) + return (1); return (0); } Modified: head/sys/dev/pci/pcivar.h ============================================================================== --- head/sys/dev/pci/pcivar.h Fri Mar 18 12:09:27 2011 (r219736) +++ head/sys/dev/pci/pcivar.h Fri Mar 18 12:13:04 2011 (r219737) @@ -110,6 +110,7 @@ struct pcicfg_msix { /* Interesting values for HyperTransport */ struct pcicfg_ht { + uint8_t ht_slave; /* Non-zero if device is an HT slave. */ uint8_t ht_msimap; /* Offset of MSI mapping cap registers. */ uint16_t ht_msictrl; /* MSI mapping control */ uint64_t ht_msiaddr; /* MSI mapping base address */