Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Apr 2012 01:22:59 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r234365 - head/sys/mips/atheros
Message-ID:  <201204170122.q3H1MxYP059606@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -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,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204170122.q3H1MxYP059606>