bnx2: Fix panic in bnx2_poll_work().

Add barrier() to bnx2_get_hw_{tx|rx}_cons() to fix this issue:

http://bugzilla.kernel.org/show_bug.cgi?id=12698

This issue was reported by multiple i386 users. Without barrier(),
the compiled code looks like the following where %eax contains the
address of the tx_cons or rx_cons in the DMA status block. The
status block contents can change between the cmpb and the movzwl
instruction. The driver would crash if the value was not 0xff during
the cmpb instruction, but changed to 0xff during the movzwl
instruction.

6828: 80 38 ff cmpb $0xff,(%eax)
682b: 0f b7 10 movzwl (%eax),%edx

With the added barrier(), the compiled code now looks correct:

683d: 0f b7 10 movzwl (%eax),%edx
6840: 0f b6 c2 movzbl %dl,%eax
6843: 3d ff 00 00 00 cmp $0xff,%eax

Thanks to Pascal de Bruijn <pmjdebruijn@pcode.nl> for reporting the
problem and Holger Noefer <hnoefer@pironet-ndh.com> for patiently
testing test patches for us.

Also updated version to 2.0.1.

Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Michael Chan and committed by David S. Miller 581daf7e 6473990c

+4 -2
+4 -2
drivers/net/bnx2.c
··· 54 55 #define DRV_MODULE_NAME "bnx2" 56 #define PFX DRV_MODULE_NAME ": " 57 - #define DRV_MODULE_VERSION "2.0.0" 58 - #define DRV_MODULE_RELDATE "April 2, 2009" 59 #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-4.6.16.fw" 60 #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-4.6.16.fw" 61 #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-4.6.17.fw" ··· 2600 /* Tell compiler that status block fields can change. */ 2601 barrier(); 2602 cons = *bnapi->hw_tx_cons_ptr; 2603 if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT)) 2604 cons++; 2605 return cons; ··· 2880 /* Tell compiler that status block fields can change. */ 2881 barrier(); 2882 cons = *bnapi->hw_rx_cons_ptr; 2883 if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)) 2884 cons++; 2885 return cons;
··· 54 55 #define DRV_MODULE_NAME "bnx2" 56 #define PFX DRV_MODULE_NAME ": " 57 + #define DRV_MODULE_VERSION "2.0.1" 58 + #define DRV_MODULE_RELDATE "May 6, 2009" 59 #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-4.6.16.fw" 60 #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-4.6.16.fw" 61 #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-4.6.17.fw" ··· 2600 /* Tell compiler that status block fields can change. */ 2601 barrier(); 2602 cons = *bnapi->hw_tx_cons_ptr; 2603 + barrier(); 2604 if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT)) 2605 cons++; 2606 return cons; ··· 2879 /* Tell compiler that status block fields can change. */ 2880 barrier(); 2881 cons = *bnapi->hw_rx_cons_ptr; 2882 + barrier(); 2883 if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)) 2884 cons++; 2885 return cons;