From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
Catalin Marinas <catalin.marinas@arm.com>,
"David S. Miller" <davem@davemloft.net>
Subject: [28/54] smsc911x: Add spinlocks around registers access
Date: Wed, 11 Aug 2010 17:00:43 -0700 [thread overview]
Message-ID: <20100812000125.829562364@clark.site> (raw)
In-Reply-To: <20100812000249.GA30948@kroah.com>
2.6.34-stable review patch. If anyone has any objections, please let us know.
------------------
From: Catalin Marinas <catalin.marinas@arm.com>
commit 492c5d943d6a04b124ba3a719dc746dc36b14cfb upstream.
On SMP systems, the SMSC911x registers may be accessed by multiple CPUs
and this seems to put the chip in an inconsistent state. The patch adds
spinlocks to the smsc911x_reg_read, smsc911x_reg_write,
smsc911x_rx_readfifo and smsc911x_tx_writefifo functions.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/net/smsc911x.c | 92 +++++++++++++++++++++++++++----------------------
1 file changed, 52 insertions(+), 40 deletions(-)
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -84,8 +84,7 @@ struct smsc911x_data {
*/
spinlock_t mac_lock;
- /* spinlock to ensure 16-bit accesses are serialised.
- * unused with a 32-bit bus */
+ /* spinlock to ensure register accesses are serialised */
spinlock_t dev_lock;
struct phy_device *phy_dev;
@@ -118,37 +117,33 @@ struct smsc911x_data {
unsigned int hashlo;
};
-/* The 16-bit access functions are significantly slower, due to the locking
- * necessary. If your bus hardware can be configured to do this for you
- * (in response to a single 32-bit operation from software), you should use
- * the 32-bit access functions instead. */
-
-static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
+static inline u32 __smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
{
if (pdata->config.flags & SMSC911X_USE_32BIT)
return readl(pdata->ioaddr + reg);
- if (pdata->config.flags & SMSC911X_USE_16BIT) {
- u32 data;
- unsigned long flags;
-
- /* these two 16-bit reads must be performed consecutively, so
- * must not be interrupted by our own ISR (which would start
- * another read operation) */
- spin_lock_irqsave(&pdata->dev_lock, flags);
- data = ((readw(pdata->ioaddr + reg) & 0xFFFF) |
+ if (pdata->config.flags & SMSC911X_USE_16BIT)
+ return ((readw(pdata->ioaddr + reg) & 0xFFFF) |
((readw(pdata->ioaddr + reg + 2) & 0xFFFF) << 16));
- spin_unlock_irqrestore(&pdata->dev_lock, flags);
-
- return data;
- }
BUG();
return 0;
}
-static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg,
- u32 val)
+static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
+{
+ u32 data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdata->dev_lock, flags);
+ data = __smsc911x_reg_read(pdata, reg);
+ spin_unlock_irqrestore(&pdata->dev_lock, flags);
+
+ return data;
+}
+
+static inline void __smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg,
+ u32 val)
{
if (pdata->config.flags & SMSC911X_USE_32BIT) {
writel(val, pdata->ioaddr + reg);
@@ -156,44 +151,54 @@ static inline void smsc911x_reg_write(st
}
if (pdata->config.flags & SMSC911X_USE_16BIT) {
- unsigned long flags;
-
- /* these two 16-bit writes must be performed consecutively, so
- * must not be interrupted by our own ISR (which would start
- * another read operation) */
- spin_lock_irqsave(&pdata->dev_lock, flags);
writew(val & 0xFFFF, pdata->ioaddr + reg);
writew((val >> 16) & 0xFFFF, pdata->ioaddr + reg + 2);
- spin_unlock_irqrestore(&pdata->dev_lock, flags);
return;
}
BUG();
}
+static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg,
+ u32 val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdata->dev_lock, flags);
+ __smsc911x_reg_write(pdata, reg, val);
+ spin_unlock_irqrestore(&pdata->dev_lock, flags);
+}
+
/* Writes a packet to the TX_DATA_FIFO */
static inline void
smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf,
unsigned int wordcount)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdata->dev_lock, flags);
+
if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
while (wordcount--)
- smsc911x_reg_write(pdata, TX_DATA_FIFO, swab32(*buf++));
- return;
+ __smsc911x_reg_write(pdata, TX_DATA_FIFO,
+ swab32(*buf++));
+ goto out;
}
if (pdata->config.flags & SMSC911X_USE_32BIT) {
writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount);
- return;
+ goto out;
}
if (pdata->config.flags & SMSC911X_USE_16BIT) {
while (wordcount--)
- smsc911x_reg_write(pdata, TX_DATA_FIFO, *buf++);
- return;
+ __smsc911x_reg_write(pdata, TX_DATA_FIFO, *buf++);
+ goto out;
}
BUG();
+out:
+ spin_unlock_irqrestore(&pdata->dev_lock, flags);
}
/* Reads a packet out of the RX_DATA_FIFO */
@@ -201,24 +206,31 @@ static inline void
smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf,
unsigned int wordcount)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdata->dev_lock, flags);
+
if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
while (wordcount--)
- *buf++ = swab32(smsc911x_reg_read(pdata, RX_DATA_FIFO));
- return;
+ *buf++ = swab32(__smsc911x_reg_read(pdata,
+ RX_DATA_FIFO));
+ goto out;
}
if (pdata->config.flags & SMSC911X_USE_32BIT) {
readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount);
- return;
+ goto out;
}
if (pdata->config.flags & SMSC911X_USE_16BIT) {
while (wordcount--)
- *buf++ = smsc911x_reg_read(pdata, RX_DATA_FIFO);
- return;
+ *buf++ = __smsc911x_reg_read(pdata, RX_DATA_FIFO);
+ goto out;
}
BUG();
+out:
+ spin_unlock_irqrestore(&pdata->dev_lock, flags);
}
/* waits for MAC not busy, with timeout. Only called by smsc911x_mac_read
next prev parent reply other threads:[~2010-08-12 0:25 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-12 0:02 [00/54] 2.6.34.4 -stable review Greg KH
2010-08-12 0:00 ` [01/54] x86, vmware: Preset lpj values when on VMware Greg KH
2010-08-14 12:22 ` Sven Joachim
2010-08-14 16:21 ` Alok Kataria
2010-08-12 0:00 ` [02/54] ata_piix: fix locking around SIDPR access Greg KH
2010-08-12 0:00 ` [03/54] powerpc: fix build with make 3.82 Greg KH
2010-08-12 0:00 ` [04/54] x86, kmmio/mmiotrace: Fix double free of kmmio_fault_pages Greg KH
2010-08-12 0:00 ` [05/54] x86/PCI: use host bridge _CRS info on ASRock ALiveSATA2-GLAN Greg KH
2010-08-12 0:00 ` [06/54] x86: Add memory modify constraints to xchg() and cmpxchg() Greg KH
2010-08-12 0:00 ` [07/54] staging: rt2870: Add USB ID for Belkin F6D4050 v2 Greg KH
2010-08-12 0:00 ` [08/54] Staging: line6: needs to select SND_PCM Greg KH
2010-08-12 0:00 ` [09/54] Staging: panel: Prevent double-calling of parport_release - fix oops Greg KH
2010-08-12 0:00 ` [10/54] PCI: Do not run NVidia quirks related to MSI with MSI disabled Greg KH
2010-08-12 0:00 ` [11/54] PCI: disable MSI on VIA K8M800 Greg KH
2010-08-12 0:00 ` [12/54] solos-pci: Fix race condition in tasklet RX handling Greg KH
2010-08-12 0:00 ` [13/54] splice: fix misuse of SPLICE_F_NONBLOCK Greg KH
2010-08-12 0:00 ` [14/54] Char: nozomi, fix tty->count counting Greg KH
2010-08-12 0:00 ` [15/54] Char: nozomi, set tty->driver_data appropriately Greg KH
2010-08-12 0:00 ` [16/54] mm: fix corruption of hibernation caused by reusing swap during image saving Greg KH
2010-08-12 0:00 ` [17/54] drivers/video/w100fb.c: ignore void return value / fix build failure Greg KH
2010-08-12 0:00 ` [18/54] iwlwifi: fix TX tracer Greg KH
2010-08-12 0:00 ` [19/54] ide-cd: Do not access completed requests in the irq handler Greg KH
2010-08-12 0:00 ` [20/54] md/raid10: fix deadlock with unaligned read during resync Greg KH
2010-08-12 0:00 ` [21/54] blkdev: cgroup whitelist permission fix Greg KH
2010-08-12 0:00 ` [22/54] eCryptfs: Handle ioctl calls with unlocked and compat functions Greg KH
2010-08-12 0:00 ` [23/54] ecryptfs: release reference to lower mount if interpose fails Greg KH
2010-08-12 0:00 ` [24/54] fs/ecryptfs/file.c: introduce missing free Greg KH
2010-08-12 0:00 ` [25/54] [ARM] pxa/cm-x300: fix ffuart registration Greg KH
2010-08-12 0:00 ` [26/54] signalfd: fill in ssi_int for posix timers and message queues Greg KH
2010-08-12 0:00 ` [27/54] bio, fs: update RWA_MASK, READA and SWRITE to match the corresponding BIO_RW_* bits Greg KH
2010-08-12 0:00 ` Greg KH [this message]
2010-08-12 0:00 ` [29/54] ARM: 6299/1: errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID Greg KH
2010-08-12 0:00 ` [30/54] ARM: 6280/1: imx: Fix build failure when including <mach/gpio.h> without <linux/spinlock.h> Greg KH
2010-08-12 0:00 ` [31/54] USB: EHCI: remove PCI assumption Greg KH
2010-08-12 0:00 ` [32/54] USB: resizing usbmon binary interface buffer causes protection faults Greg KH
2010-08-12 0:00 ` [33/54] USB delay init quirk for logitech Harmony 700-series devices Greg KH
2010-08-12 0:00 ` [34/54] USB: serial: enabling support for Segway RMP in ftdi_sio Greg KH
2010-08-12 0:00 ` [35/54] USB: option: Huawei ETS 1220 support added Greg KH
2010-08-12 0:00 ` [36/54] USB: option: add huawei k3765 k4505 devices to work properly Greg KH
2010-08-12 0:00 ` [37/54] USB: ftdi_sio: device id for Navitator Greg KH
2010-08-12 0:00 ` [38/54] USB: cp210x: Add four new device IDs Greg KH
2010-08-12 0:00 ` [39/54] USB: usbtest: avoid to free coherent buffer in atomic context Greg KH
2010-08-12 0:00 ` [40/54] USB: fix thread-unsafe anchor utiliy routines Greg KH
2010-08-12 0:00 ` [41/54] drm/edid: Fix the HDTV hack sync adjustment Greg KH
2010-08-12 0:00 ` [42/54] Bluetooth: Added support for controller shipped with iMac i5 Greg KH
2010-08-12 0:00 ` [43/54] mtd: gen_nand: fix support for multiple chips Greg KH
2010-08-12 0:00 ` [44/54] jfs: dont allow os2 xattr namespace overlap with others Greg KH
2010-08-12 0:01 ` [45/54] arp_notify: allow drivers to explicitly request a notification event Greg KH
2010-08-12 0:01 ` [46/54] xen: netfront: explicitly generate arp_notify event after migration Greg KH
2010-08-12 0:01 ` [47/54] net: Fix NETDEV_NOTIFY_PEERS to not conflict with NETDEV_BONDING_DESLAVE Greg KH
2010-08-12 0:01 ` [48/54] irq: Add new IRQ flag IRQF_NO_SUSPEND Greg KH
2010-08-12 0:01 ` [49/54] xen: Do not suspend IPI IRQs Greg KH
2010-08-12 0:01 ` [50/54] drm/i915: Use RSEN instead of HTPLG for tfp410 monitor detection Greg KH
2010-08-12 0:01 ` [51/54] i915: fix ironlake edp panel setup (v4) Greg KH
2010-08-12 0:01 ` [52/54] [SCSI] ibmvfc: Fix command completion handling Greg KH
2010-08-12 0:01 ` [53/54] [SCSI] ibmvfc: Reduce error recovery timeout Greg KH
2010-08-12 0:01 ` [54/54] md/raid1: delay reads that could overtake behind-writes Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100812000125.829562364@clark.site \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=catalin.marinas@arm.com \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=stable-review@kernel.org \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).