Exemple #1
0
/* handle interrupt for specified sub device; DmaMode == DEV_READ_S */
PRIVATE void handle_int_read(int sub_dev_nr) 
{
	sub_dev_t *sub_dev_ptr; int r,i;

	sub_dev_ptr = &sub_dev[sub_dev_nr];

	dprint("Device filled dma[%d]\n", sub_dev_ptr->DmaFillNext);
	sub_dev_ptr->DmaLength += 1; 
	sub_dev_ptr->DmaFillNext = 
		(sub_dev_ptr->DmaFillNext + 1) % sub_dev_ptr->NrOfDmaFragments;

	/* possibly copy data to user (if it is waiting for us) */
	data_to_user(sub_dev_ptr);

	if (sub_dev_ptr->DmaLength == sub_dev_ptr->NrOfDmaFragments) { 
		/* if dma buffer full */

		if (sub_dev_ptr->BufLength == sub_dev_ptr->NrOfExtraBuffers) {
			error("All buffers full, we have a problem.\n");
			drv_stop(sub_dev_nr);        /* stop the sub device */
			sub_dev_ptr->DmaBusy = FALSE;
			sub_dev_ptr->ReviveStatus = 0;   /* no data for user, 
												this is a sad story */
			sub_dev_ptr->ReadyToRevive = TRUE; /* wake user up */
			return;
		} 
		else { /* dma full, still room in extra buf; 
				  copy from dma to extra buf */
			dprint("dma full: going to copy buf[%d] <- dma[%d]\n", 
					sub_dev_ptr->BufFillNext, sub_dev_ptr->DmaReadNext);
			memcpy(sub_dev_ptr->ExtraBuf + 
					sub_dev_ptr->BufFillNext * sub_dev_ptr->FragSize, 
					sub_dev_ptr->DmaPtr + 
					sub_dev_ptr->DmaReadNext * sub_dev_ptr->FragSize,
					sub_dev_ptr->FragSize);
			sub_dev_ptr->DmaLength -= 1;
			sub_dev_ptr->DmaReadNext = 
				(sub_dev_ptr->DmaReadNext + 1) % sub_dev_ptr->NrOfDmaFragments;
			sub_dev_ptr->BufFillNext = 
				(sub_dev_ptr->BufFillNext + 1) % sub_dev_ptr->NrOfExtraBuffers;
		}
	}
	/* confirm interrupt, and reenable interrupt from this sub dev*/
	drv_reenable_int(sub_dev_ptr->Nr);

#if 0
	/* reenable irq_hook*/
	if ((r=sys_irqenable(&irq_hook_id)) != OK) {
		error("%s: Couldn't reenable IRQ", drv.DriverName);
	}
#endif
}
PRIVATE void msg_sig_stop(void) 
{
  int i; char irq;
  for (i = 0; i < drv.NrOfSubDevices; i++) {
    drv_stop(i); /* stop all sub devices */
  }
  if (irq_hook_set) {
    if (sys_irqdisable(&irq_hook_id) != OK) {
      error("Could not disable IRQ\n");
    }
    /* get irq from device driver*/
  	if (drv_get_irq(&irq) != OK) {
  	  error("Msg SIG_STOP Couldn't get IRQ");
  	}
  	/* remove the policy */
    if (sys_irqrmpolicy(irq, &irq_hook_id) != OK) {
      error("%s: Could not disable IRQ\n",drv.DriverName);
    }
  }
}
Exemple #3
0
PRIVATE int close_sub_dev(int sub_dev_nr) {
	sub_dev_t *sub_dev_ptr;
	sub_dev_ptr = &sub_dev[sub_dev_nr];
	if (sub_dev_ptr->DmaMode == DEV_WRITE_S && !sub_dev_ptr->OutOfData) {
		/* do nothing, still data in buffers that has to be transferred */
		sub_dev_ptr->Opened = FALSE;  /* keep DMA busy */
		return OK;
	}
	if (sub_dev_ptr->DmaMode == NO_DMA) {
		/* do nothing, there is no dma going on */
		sub_dev_ptr->Opened = FALSE;
		return OK;
	}
	sub_dev_ptr->Opened = FALSE;
	sub_dev_ptr->DmaBusy = FALSE;
	/* stop the device */
	drv_stop(sub_dev_ptr->Nr);
	/* free the buffers */
	free(sub_dev_ptr->DmaBuf);
	free(sub_dev_ptr->ExtraBuf);
}
Exemple #4
0
static int reset(int chan) {
	drv_stop(chan);
	sub_dev[chan].OutOfData = 1;

	return OK;
}