aboutsummaryrefslogtreecommitdiff
path: root/hw/pcnet.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-07-13 23:25:11 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2006-07-13 23:25:11 +0000
commitec607da7c2f2199a486f8df243f23f509f6ab5c0 (patch)
treed3342e1c654314e2e0cbfe6b5257fa51319496d3 /hw/pcnet.c
parent1dce7c3c2244a6f149e7afd7b1d84963ed57b7fd (diff)
avoid recursive tx
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2050 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/pcnet.c')
-rw-r--r--hw/pcnet.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/hw/pcnet.c b/hw/pcnet.c
index a375f27d92..0826cee16e 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -57,6 +57,7 @@ struct PCNetState_st {
uint64_t timer;
int xmit_pos, recv_pos;
uint8_t buffer[4096];
+ int tx_busy;
};
#ifdef __GNUC__
@@ -659,6 +660,8 @@ static void pcnet_s_reset(PCNetState *s)
s->csr[114] = 0x0000;
s->csr[122] = 0x0000;
s->csr[124] = 0x0000;
+
+ s->tx_busy = 0;
}
static void pcnet_update_irq(PCNetState *s)
@@ -1104,7 +1107,9 @@ static void pcnet_transmit(PCNetState *s)
s->csr[0] &= ~0x0008;
return;
}
-
+
+ s->tx_busy = 1;
+
txagain:
if (pcnet_tdte_poll(s)) {
struct pcnet_TMD tmd;
@@ -1167,6 +1172,8 @@ static void pcnet_transmit(PCNetState *s)
if (count--)
goto txagain;
}
+
+ s->tx_busy = 0;
}
static void pcnet_poll(PCNetState *s)
@@ -1177,7 +1184,13 @@ static void pcnet_poll(PCNetState *s)
if (CSR_TDMD(s) ||
(CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
+ {
+ /* prevent recursion */
+ if (s->tx_busy)
+ return;
+
pcnet_transmit(s);
+ }
}
static void pcnet_poll_timer(void *opaque)