static void grtm_interrupt(void *arg) { struct grtm_priv *pDev = arg; struct grtm_regs *regs = pDev->regs; unsigned int status; int num; /* Clear interrupt by reading it */ status = READ_REG(pDev, ®s->dma_status); /* Spurious Interrupt? */ if ( !pDev->running ) return; if ( status ) WRITE_REG(pDev, ®s->dma_status, status); if ( status & GRTM_DMA_STS_TFF ){ pDev->stats.err_transfer_frame++; } if ( status & GRTM_DMA_STS_TA ){ pDev->stats.err_ahb++; } if ( status & GRTM_DMA_STS_TE ){ pDev->stats.err_tx++; } if ( status & GRTM_DMA_STS_TI ){ if ( pDev->config.isr_desc_proc && (rtems_semaphore_obtain(pDev->handling_transmission, RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL) ) { /* Free used descriptors and put the sent frame into the "Sent queue" * (SCHEDULED->SENT) */ num = grtm_free_sent(pDev); pDev->scheduled_cnt -= num; pDev->sent_cnt += num; /* Use all available free descriptors there are frames for * in the ready queue. * (READY->SCHEDULED) */ num = grtm_schedule_ready(pDev,1); pDev->ready_cnt -= num; pDev->scheduled_cnt += num; rtems_semaphore_release(pDev->handling_transmission); #if 0 if ( (pDev->config.blocking==GRTM_BLKMODE_COMPLETE) && pDev->timeout ){ /* Signal to thread only if enough data is available */ if ( pDev->wait_for_frames > grtm_data_avail(pDev) ){ /* Not enough data available */ goto procceed_processing_interrupts; } /* Enough number of frames has been transmitted which means that * the waiting thread should be woken up. */ rtems_semaphore_release(pDev->sem_tx); } #endif } if ( pDev->config.blocking == GRTM_BLKMODE_BLK ) { /* Blocking mode */ #if 0 /* Disable further Interrupts until handled by waiting task. */ regs->dma_ctrl = READ_REG(pDev, ®s->dma_ctrl) & ~GRTM_DMA_CTRL_IE; #endif /* Signal Semaphore to wake waiting thread in ioctl(SEND|RECLAIM) */ rtems_semaphore_release(pDev->sem_tx); } } #if 0 procceed_processing_interrupts: ; #endif }
static void grtm_interrupt(void *arg) { struct grtm_priv *pDev = arg; struct grtm_regs *regs = pDev->regs; unsigned int status; /* Clear interrupt by reading it */ status = READ_REG(®s->dma_status); /* Spurious Interrupt? */ if ( !pDev->running || !status) return; regs->dma_status = status; if ( status & GRTM_DMA_STS_TFF ){ pDev->stats.err_transfer_frame++; } if ( status & GRTM_DMA_STS_TA ){ pDev->stats.err_ahb++; } if ( status & GRTM_DMA_STS_TE ){ pDev->stats.err_tx++; } if ( status & GRTM_DMA_STS_TI ){ if ( pDev->config.isr_desc_proc) { if (grtm_request_txlock_isr(pDev)) { grtm_tx_process(pDev); grtm_release_txlock(pDev); } #if 0 if ( (pDev->config.blocking==GRTM_BLKMODE_COMPLETE) && pDev->timeout ){ /* Signal to thread only if enough data is available */ if ( pDev->wait_for_frames > grtm_data_avail(pDev) ){ /* Not enough data available */ goto procceed_processing_interrupts; } /* Enough number of frames has been transmitted which means that * the waiting thread should be woken up. */ rtems_semaphore_release(pDev->sem_tx); } #endif } if ( pDev->config.blocking == GRTM_BLKMODE_BLK ) { /* Blocking mode */ #if 0 /* Disable further Interrupts until handled by waiting task. */ regs->dma_ctrl = READ_REG(®s->dma_ctrl) & ~GRTM_DMA_CTRL_IE; #endif /* Signal Semaphore to wake waiting thread in ioctl(SEND|RECLAIM) */ rtems_semaphore_release(pDev->sem_tx); } } #if 0 procceed_processing_interrupts: ; #endif }