From owner-svn-src-head@FreeBSD.ORG Tue Apr 17 01:23:00 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 1C365106564A; Tue, 17 Apr 2012 01:23:00 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 06C368FC15; Tue, 17 Apr 2012 01:23:00 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q3H1MxcP059608; Tue, 17 Apr 2012 01:22:59 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q3H1MxYP059606; Tue, 17 Apr 2012 01:22:59 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201204170122.q3H1MxYP059606@svn.freebsd.org> From: Adrian Chadd Date: Tue, 17 Apr 2012 01:22:59 +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: r234365 - head/sys/mips/atheros 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: Tue, 17 Apr 2012 01:23:00 -0000 Author: adrian Date: Tue Apr 17 01:22:59 2012 New Revision: 234365 URL: http://svn.freebsd.org/changeset/base/234365 Log: Protect the PCI space registers behind a mutex. Obtained from: Linux/OpenWRT, Atheros Modified: head/sys/mips/atheros/ar71xx_pci.c Modified: head/sys/mips/atheros/ar71xx_pci.c ============================================================================== --- head/sys/mips/atheros/ar71xx_pci.c Tue Apr 17 00:54:38 2012 (r234364) +++ head/sys/mips/atheros/ar71xx_pci.c Tue Apr 17 01:22:59 2012 (r234365) @@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -72,6 +74,10 @@ __FBSDID("$FreeBSD$"); #define dprintf(x, arg...) #endif +struct mtx ar71xx_pci_mtx; +MTX_SYSINIT(ar71xx_pci_mtx, &ar71xx_pci_mtx, "ar71xx PCI space mutex", + MTX_SPIN); + struct ar71xx_pci_softc { device_t sc_dev; @@ -97,6 +103,7 @@ ar71xx_pci_mask_irq(void *source) uint32_t reg; unsigned int irq = (unsigned int)source; + /* XXX is the PCI lock required here? */ reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); /* flush */ reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); @@ -109,6 +116,7 @@ ar71xx_pci_unmask_irq(void *source) uint32_t reg; unsigned int irq = (unsigned int)source; + /* XXX is the PCI lock required here? */ reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg | (1 << irq)); /* flush */ @@ -140,6 +148,9 @@ static int ar71xx_pci_check_bus_error(void) { uint32_t error, addr, has_errors = 0; + + mtx_assert(&ar71xx_pci_mtx, MA_OWNED); + error = ATH_READ_REG(AR71XX_PCI_ERROR) & 0x3; dprintf("%s: PCI error = %02x\n", __func__, error); if (error) { @@ -185,7 +196,9 @@ ar71xx_pci_conf_setup(int bus, int slot, { uint32_t addr = ar71xx_pci_make_addr(bus, slot, func, (reg & ~3)); cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 4); - + + mtx_assert(&ar71xx_pci_mtx, MA_OWNED); + ATH_WRITE_REG(AR71XX_PCI_CONF_ADDR, addr); ATH_WRITE_REG(AR71XX_PCI_CONF_CMD, cmd); @@ -216,11 +229,13 @@ ar71xx_pci_read_config(device_t dev, u_i dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, func, reg, bytes); + mtx_lock_spin(&ar71xx_pci_mtx); if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, PCI_CONF_CMD_READ) == 0) data = ATH_READ_REG(AR71XX_PCI_CONF_READ_DATA); else data = -1; + mtx_unlock_spin(&ar71xx_pci_mtx); /* get request bytes from 32-bit word */ data = (data >> shift) & mask; @@ -241,8 +256,10 @@ ar71xx_pci_local_write(device_t dev, uin cmd = PCI_LCONF_CMD_WRITE | (reg & ~3); cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 20); + mtx_lock_spin(&ar71xx_pci_mtx); ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd); ATH_WRITE_REG(AR71XX_PCI_LCONF_WRITE_DATA, data); + mtx_unlock_spin(&ar71xx_pci_mtx); } static void @@ -255,9 +272,11 @@ ar71xx_pci_write_config(device_t dev, u_ data = data << (8*(reg % 4)); + mtx_lock_spin(&ar71xx_pci_mtx); if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, PCI_CONF_CMD_WRITE) == 0) ATH_WRITE_REG(AR71XX_PCI_CONF_WRITE_DATA, data); + mtx_unlock_spin(&ar71xx_pci_mtx); } #ifdef AR71XX_ATH_EEPROM @@ -457,7 +476,9 @@ ar71xx_pci_attach(device_t dev) ATH_WRITE_REG(AR71XX_PCI_WINDOW7, PCI_WINDOW7_CONF_ADDR); DELAY(100000); + mtx_lock_spin(&ar71xx_pci_mtx); ar71xx_pci_check_bus_error(); + mtx_unlock_spin(&ar71xx_pci_mtx); /* Fixup internal PCI bridge */ ar71xx_pci_local_write(dev, PCIR_COMMAND,