diff options
Diffstat (limited to 'drivers/net/irda/nsc-ircc.c')
-rw-r--r-- | drivers/net/irda/nsc-ircc.c | 49 |
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 */ |