summaryrefslogtreecommitdiffstats
path: root/drivers/net/irda/nsc-ircc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/irda/nsc-ircc.c')
-rw-r--r--drivers/net/irda/nsc-ircc.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 1886ec73a..7a6cc5091 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -6,7 +6,7 @@
* Status: Stable.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat Nov 7 21:43:15 1998
- * Modified at: Fri Jan 28 12:10:10 2000
+ * Modified at: Fri Feb 18 01:48:51 2000
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
@@ -42,6 +42,7 @@
********************************************************************/
#include <linux/module.h>
+
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/skbuff.h>
@@ -1431,8 +1432,10 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase)
/* We must empty the status FIFO no matter what */
len = inb(iobase+RFLFL) | ((inb(iobase+RFLFH) & 0x1f) << 8);
- if (st_fifo->tail >= MAX_RX_WINDOW)
+ if (st_fifo->tail >= MAX_RX_WINDOW) {
+ IRDA_DEBUG(0, __FUNCTION__ "(), window is full!\n");
continue;
+ }
st_fifo->entries[st_fifo->tail].status = status;
st_fifo->entries[st_fifo->tail].len = len;
@@ -1492,7 +1495,18 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase)
st_fifo->pending_bytes += len;
st_fifo->entries[st_fifo->head].status = status;
st_fifo->entries[st_fifo->head].len = len;
-
+ /*
+ * DMA not finished yet, so try again
+ * later, set timer value, resolution
+ * 125 us
+ */
+ switch_bank(iobase, BANK4);
+ outb(0x02, iobase+TMRL); /* x 125 us */
+ outb(0x00, iobase+TMRH);
+
+ /* Start timer */
+ outb(IRCR1_TMR_EN, iobase+IRCR1);
+
/* Restore bank register */
outb(bank, iobase+BSR);
@@ -1597,7 +1611,7 @@ static void nsc_ircc_sir_interrupt(struct nsc_ircc_cb *self, int eir)
else {
self->stats.tx_packets++;
- netif_wakeup_queue(self->netdev);
+ netif_wake_queue(self->netdev);
self->ier = IER_TXEMP_IE;
}
@@ -1648,21 +1662,12 @@ static void nsc_ircc_fir_interrupt(struct nsc_ircc_cb *self, int iobase,
/* Status FIFO event*/
if (eir & EIR_SFIF_EV) {
+ /* Check if DMA has finished */
if (nsc_ircc_dma_receive_complete(self, iobase)) {
/* Wait for next status FIFO interrupt */
self->ier = IER_SFIF_IE;
} else {
- /*
- * DMA not finished yet, so try again later, set
- * timer value, resolution 125 us
- */
- switch_bank(iobase, BANK4);
- outb(0x02, iobase+TMRL); /* 2 * 125 us */
- outb(0x00, iobase+TMRH);
-
- /* Start timer */
- outb(IRCR1_TMR_EN, iobase+IRCR1);
- self->ier = IER_TMR_IE | IER_SFIF_IE;
+ self->ier = IER_SFIF_IE | IER_TMR_IE;
}
} else if (eir & EIR_TMR_EV) { /* Timer finished */
/* Disable timer */
@@ -1677,15 +1682,17 @@ static void nsc_ircc_fir_interrupt(struct nsc_ircc_cb *self, int iobase,
if (self->io.direction == IO_XMIT) {
nsc_ircc_dma_xmit(self, iobase);
- /* Interrupt on DMA */
+ /* Interrupt on DMA */
self->ier = IER_DMA_IE;
} else {
- /* Check if DMA has now finished */
- nsc_ircc_dma_receive_complete(self, iobase);
-
- self->ier = IER_SFIF_IE;
+ /* Check (again) if DMA has finished */
+ if (nsc_ircc_dma_receive_complete(self, iobase)) {
+ self->ier = IER_SFIF_IE;
+ } else {
+ self->ier = IER_SFIF_IE | IER_TMR_IE;
+ }
}
- } else if (eir & EIR_DMA_EV) {
+ } else if (eir & EIR_DMA_EV) {
/* Finished with all transmissions? */
if (nsc_ircc_dma_xmit_complete(self)) {
/* Check if there are more frames to be transmitted */