diff options
author | Michael Brown <mcb30@etherboot.org> | 2009-06-27 16:36:21 +0100 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2009-06-27 16:36:21 +0100 |
commit | c26a38b313389af157880efa8557ef894906e317 (patch) | |
tree | f058da3f63671b12f2608dc8b2ff4f7bfac12f1a /src/arch | |
parent | f186ada2d3ab7f4f03f3c3ac8e9bf3577fb00504 (diff) | |
download | ipxe-c26a38b313389af157880efa8557ef894906e317.tar.gz |
[pxe] Update UNDI transmit count before transmitting packet
It is possible that the UNDI ISR may be triggered before netdev_tx()
returns control to pxenv_undi_transmit(). This means that
pxenv_undi_isr() may see a zero undi_tx_count, and so not check for TX
completions. This is not a significant problem, since it will check
for TX completions on the next call to pxenv_undi_isr() anyway; it
just means that the NBP will see a spurious IRQ that was apparently
caused by nothing.
Fix by updating the undi_tx_count before calling netdev_tx(), so that
pxenv_undi_isr() can decrement it and report the TX completion.
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/i386/interface/pxe/pxe_undi.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/arch/i386/interface/pxe/pxe_undi.c b/src/arch/i386/interface/pxe/pxe_undi.c index e284c905..bd387ea5 100644 --- a/src/arch/i386/interface/pxe/pxe_undi.c +++ b/src/arch/i386/interface/pxe/pxe_undi.c @@ -316,18 +316,22 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT } } + /* Flag transmission as in-progress. Do this before starting + * to transmit the packet, because the ISR may trigger before + * we return from netdev_tx(). + */ + undi_tx_count++; + /* Transmit packet */ - DBG2 ( "\n" ); /* ISR may trigger before we return from netdev_tx() */ + DBG2 ( "\n" ); if ( ( rc = netdev_tx ( pxe_netdev, iobuf ) ) != 0 ) { DBG2 ( "PXENV_UNDI_TRANSMIT could not transmit: %s\n", strerror ( rc ) ); + undi_tx_count--; undi_transmit->Status = PXENV_STATUS ( rc ); return PXENV_EXIT_FAILURE; } - /* Flag transmission as in-progress */ - undi_tx_count++; - undi_transmit->Status = PXENV_STATUS_SUCCESS; return PXENV_EXIT_SUCCESS; } |