From 5f359b4492ba49bdd28a9453c92bad66ee420087 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 6 May 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-05-06 --- pc/ether509.c | 139 +++++++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 65 deletions(-) diff --git a/pc/ether509.c b/pc/ether509.c index 0b523a8e35119494a92a573b5305d4fdd6664ba7..94b153f49be1ba19d0d1e9effd1b7852cd9ff0d2 100644 --- a/pc/ether509.c +++ b/pc/ether509.c @@ -283,79 +283,88 @@ interrupt(Ureg *ur, void *arg) ether = arg; port = ether->port; - status = ins(port+Status); - - if(status & Failure){ + for(;;){ /* - * Adapter failure, try to find out why. - * Reset if necessary. - * What happens if Tx is active and we reset, - * need to retransmit? - * This probably isn't right. + * Clear the interrupt latch. + * It's possible to receive a packet and for another + * to become complete before we exit the interrupt + * handler so this must be done first to ensure another + * interrupt will occur. */ - diag = getdiag(ether); - print("ether509: status #%ux, diag #%ux\n", status, diag); - - if(diag & TxOverrun){ - COMMAND(port, TxReset, 0); + COMMAND(port, AckIntr, Latch); + status = ins(port+Status); + if((status & AllIntr) == 0) + break; + + if(status & Failure){ + /* + * Adapter failure, try to find out why. + * Reset if necessary. + * What happens if Tx is active and we reset, + * need to retransmit? + * This probably isn't right. + */ + diag = getdiag(ether); + print("ether509: status #%ux, diag #%ux\n", status, diag); + + if(diag & TxOverrun){ + COMMAND(port, TxReset, 0); + COMMAND(port, TxEnable, 0); + wakeup(ðer->tr); + } + + if(diag & RxUnderrun){ + COMMAND(port, RxReset, 0); + attach(ether); + } + + return; + } + + if(status & RxComplete){ + receive(ether); + status &= ~RxComplete; + } + + if(status & TxComplete){ + /* + * Pop the TX Status stack, accumulating errors. + * If there was a Jabber or Underrun error, reset + * the transmitter. For all conditions enable + * the transmitter. + */ + txstatus = 0; + do{ + if(x = inb(port+TxStatus)) + outb(port+TxStatus, 0); + txstatus |= x; + }while(ins(port+Status) & TxComplete); + + if(txstatus & (TxJabber|TxUnderrun)) + COMMAND(port, TxReset, 0); COMMAND(port, TxEnable, 0); - wakeup(ðer->tr); + ether->oerrs++; } - - if(diag & RxUnderrun){ - COMMAND(port, RxReset, 0); - attach(ether); + + if(status & (TxAvailable|TxComplete)){ + /* + * Reset the Tx FIFO threshold. + */ + if(status & TxAvailable){ + COMMAND(port, AckIntr, TxAvailable); + wakeup(ðer->tr); + } + status &= ~(TxAvailable|TxComplete); } - - return; - } - - if(status & RxComplete){ - receive(ether); - status &= ~RxComplete; - } - - if(status & TxComplete){ - /* - * Pop the TX Status stack, accumulating errors. - * If there was a Jabber or Underrun error, reset - * the transmitter. For all conditions enable - * the transmitter. - */ - txstatus = 0; - do{ - if(x = inb(port+TxStatus)) - outb(port+TxStatus, 0); - txstatus |= x; - }while(ins(port+Status) & TxComplete); - - if(txstatus & (TxJabber|TxUnderrun)) - COMMAND(port, TxReset, 0); - COMMAND(port, TxEnable, 0); - ether->oerrs++; - } - - if(status & (TxAvailable|TxComplete)){ + /* - * Reset the Tx FIFO threshold. + * Panic if there are any interrupt bits on we haven't + * dealt with. Should deal with UP (Update Statistics) + * for happier coexistence with Windows drivers. */ - if(status & TxAvailable){ - COMMAND(port, AckIntr, TxAvailable); - wakeup(ðer->tr); + if(status & AllIntr) + panic("ether509 interrupt: #%lux, #%ux\n", status, getdiag(ether)); } - status &= ~(TxAvailable|TxComplete); - } - - /* - * Panic if there are any interrupt bits on we haven't - * dealt with other than Latch. Should deal with UP (Update - * Statistics) for happier coexistence with Windows drivers. - * Otherwise, acknowledge the interrupt. - */ - if(status & AllIntr) - panic("ether509 interrupt: #%lux, #%ux\n", status, getdiag(ether)); - - COMMAND(port, AckIntr, Latch); } typedef struct Adapter Adapter;