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, &regs->dma_status);

	/* Spurious Interrupt? */
	if ( !pDev->running )
		return;

	if ( status )
		WRITE_REG(pDev, &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 && 
		     (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, &regs->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
}
Ejemplo n.º 2
0
Archivo: grtm.c Proyecto: gedare/rtems
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(&regs->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(&regs->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
}