Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: slicoss: fix occasionally writing out only half of a dma address

curaddrupper caches the last written upper 32-bits of a dma address
(the device has one register for the upper 32-bits of all dma
address registers). The problem is, not every dma address write
checks and sets curaddrupper. This causes the driver to occasionally
not write the upper 32-bits of a dma address to the device when it
really should.

I've seen this manifest particularly when the driver is trying to
read config data from the device (RCONFIG) in order to checksum the
device's eeprom. Since the device writes its config data to the
wrong DMA address the driver reads 0 as the eeprom size and the
eeprom checksum fails.

This patch fixes the issue by removing curaddrupper and always
writing the upper 32-bits of dma addresses.

Signed-off-by: David Matlack <dmatlack@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

David Matlack and committed by
Greg Kroah-Hartman
36bf51ac eafe6002

+1 -5
-1
drivers/staging/slicoss/slic.h
··· 414 414 u32 intrregistered; 415 415 uint isp_initialized; 416 416 uint gennumber; 417 - u32 curaddrupper; 418 417 struct slic_shmem *pshmem; 419 418 dma_addr_t phys_shmem; 420 419 u32 isrcopy;
+1 -4
drivers/staging/slicoss/slicoss.c
··· 147 147 unsigned long flags; 148 148 149 149 spin_lock_irqsave(&adapter->bit64reglock, flags); 150 - if (paddrh != adapter->curaddrupper) { 151 - adapter->curaddrupper = paddrh; 152 - writel(paddrh, regh); 153 - } 150 + writel(paddrh, regh); 154 151 writel(value, reg); 155 152 if (flush) 156 153 mb();