The following patch seems to fix the problem for me. I think the
cmpxchg should be #ifdef'd on HAVE_CMPXCHG but in our experience,
atomicity is important for updating cmd_status, so if you can't do
this atomically, you're probably hosed anyhow (you'll get lots of Tx
timeouts, at least).
--david
--- drivers/net/eepro100.c~ Fri Feb 11 00:30:21 2000
+++ drivers/net/eepro100.c Sat Feb 12 17:19:31 2000
@@ -385,15 +385,15 @@
};
/* The Speedo3 Rx and Tx frame/buffer descriptors. */
-struct descriptor { /* A generic descriptor. */
- s32 cmd_status; /* All command and status fields. */
+struct descriptor { /* A generic descriptor. */
+ volatile s32 cmd_status; /* All command and status fields. */
u32 link; /* struct descriptor * */
unsigned char params[0];
};
/* The Speedo3 Rx and Tx buffer descriptors. */
struct RxFD { /* Receive frame descriptor. */
- s32 status;
+ volatile s32 status;
u32 link; /* struct RxFD * */
u32 rx_buf_addr; /* void * */
u32 count;
@@ -1291,7 +1291,18 @@
{
struct descriptor *last_cmd = sp->last_cmd;
sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
+#if 0
last_cmd->cmd_status &= cpu_to_le32(~(CmdSuspend | CmdIntr));
+#else
+ {
+ s32 old, new;
+
+ do {
+ old = last_cmd->cmd_status;
+ new = old & ~(CmdSuspend | CmdIntr);
+ } while (cmpxchg(&last_cmd->cmd_status, old, new) != old);
+ }
+#endif
}
if (sp->cur_tx - sp->dirty_tx >= TX_QUEUE_LIMIT) {
sp->tx_full = 1;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Tue Feb 15 2000 - 21:00:23 EST