patch-2.3.40 linux/drivers/net/3c527.c
Next file: linux/drivers/net/Config.in
Previous file: linux/drivers/net/3c509.c
Back to the patch index
Back to the overall index
- Lines: 88
- Date:
Thu Jan 20 10:44:46 2000
- Orig file:
v2.3.39/linux/drivers/net/3c527.c
- Orig date:
Mon Oct 4 15:49:29 1999
diff -u --recursive --new-file v2.3.39/linux/drivers/net/3c527.c linux/drivers/net/3c527.c
@@ -16,7 +16,7 @@
*/
static const char *version =
- "3c527.c:v0.05 1999/09/06 Alan Cox (alan@redhat.com)\n";
+ "3c527.c:v0.07 2000/01/18 Alan Cox (alan@redhat.com)\n";
/*
* Things you need
@@ -447,10 +447,22 @@
/*
- * Send exec commands
+ * Send exec commands. This requires a bit of explaining.
+ *
+ * You feed the card a command, you wait, it interrupts you get a
+ * reply. All well and good. The complication arises because you use
+ * commands for filter list changes which come in at bh level from things
+ * like IPV6 group stuff.
+ *
+ * We have a simple state machine
+ *
+ * 0 - nothing issued
+ * 1 - command issued, wait reply
+ * 2 - reply waiting - reader then goes to state 0
+ * 3 - command issued, trash reply. In which case the irq
+ * takes it back to state 0
*/
-
/*
* Send command from interrupt state
*/
@@ -463,7 +475,7 @@
if(lp->exec_pending)
return -1;
- lp->exec_pending=1;
+ lp->exec_pending=3;
lp->exec_box->mbox=0;
lp->exec_box->mbox=cmd;
memcpy((void *)lp->exec_box->data, data, len);
@@ -492,6 +504,9 @@
* Wait for a command
*/
+ save_flags(flags);
+ cli();
+
while(lp->exec_pending)
sleep_on(&lp->event);
@@ -500,6 +515,9 @@
*/
lp->exec_pending=1;
+
+ restore_flags(flags);
+
lp->exec_box->mbox=0;
lp->exec_box->mbox=cmd;
memcpy((void *)lp->exec_box->data, data, len);
@@ -826,6 +844,10 @@
wmb();
np->length = skb->len;
+
+ if(np->length < 60)
+ np->length = 60;
+
np->data = virt_to_bus(skb->data);
np->status = 0;
np->control = (1<<7)|(1<<6); /* EOP EOL */
@@ -1015,8 +1037,11 @@
status>>=3;
if(status&1)
{
- /* 0=no 1=yes 2=reply clearing */
- lp->exec_pending=2;
+ /* 0=no 1=yes 2=replied, get cmd, 3 = wait reply & dump it */
+ if(lp->exec_pending!=3)
+ lp->exec_pending=2;
+ else
+ lp->exec_pending=0;
wake_up(&lp->event);
}
if(status&2)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)