
/*+-----------------------------------------------------------------------+  */
/*| (C) ADDI-DATA GmbH Dieselstra?e 3 D-77833 Ottersweier                 |  */
/*+-----------------------------------------------------------------------+  */
/*| Tel : +49 (0) 7223/9493-0     | email : info@addi-data.com            |  */
/*| Fax : +49 (0) 7223/9493-92    | Internet : http:$/$/www.addi-data.com   |*/
/*+-------------------------------+---------------------------------------+  */
/*| Project : APCI-3600           | Compiler : Microsoft Visual C++       |  */
/*| Module name : 3600INT.C       |  Version : 6.0                        |  */
/*+-------------------------------+---------------------------------------+  */
/*| Author : Guinot Catherine       Date : 05/08/2004                     |  */
/*+-----------------------------------------------------------------------+  */
/*| Description : Interrupt API Functions of the APCI-3600                |  */
/*+-----------------------------------------------------------------------+  */
/*|                             UPDATES                                   |  */
/*+----------+-----------+------------------------------------------------+  */
/*| Date     | Author    | Description of updates                         |  */
/*+----------+-----------+------------------------------------------------+  */
/*|          |           |                                                |  */
/*+----------+-----------+------------------------------------------------+  */
#include "apci3600-private.h"


#ifdef _3600INT_DEBUG
#define PRINTKIF(fmt, args...)		printk(fmt "(%s:%d): \n" , __FILE__,__LINE__ , ## args)
#define _3600INT_DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)
#define _3600INT_MARK() 					printk("%s:%i",__FUNCTION__ , __LINE__)
#else
#define PRINTKIF(fmt, args...)
#define _3600INT_DPRINTK(fmt, args...)
#define _3600INT_MARK()
#endif

// #define DEBUG_
#ifdef DEBUG_
#define PRINTKIF(fmt, args...)		printk(fmt, ## args)
#endif

EXPORT_SYMBOL(i_PCI3600_SetBoardIntKernelRoutine);
EXPORT_SYMBOL(i_PCI3600_ResetBoardIntKernelRoutine);

/* pdw_ComputerBufferAddressKernelLevel : an array of pointer to uint32_t
 *
 * count: size of the array
 *  
 */
//--------------------------------------------------------------------------------
static int __needlock apci3600_save_data_chunk(struct pci_dev * pdev, uint32_t* pdw_ComputerBufferAddressKernelLevel, int count)
{
	int i;
	int number_of_byte = 0;
	_3600INT_MARK();
	for(i=0; i<count; i++)
	{
		/* allocate */
		struct apci3600_data_t * new = kmalloc( sizeof(struct apci3600_data_t), GFP_ATOMIC );
		if ( !new )
		{
			printk("could not allocate enough memory !\n");
			return -1;
		}
		/* save information */
		new->pbuffer = (uint32_t *)(uintptr_t)pdw_ComputerBufferAddressKernelLevel[i];
		/* size in unit of 32 bits is given encoded in bits 4 - 31 of the first uint32_t - add 1 for header ! */
		new->number_of_value = 1 + ((*((uint32_t *)(uintptr_t)pdw_ComputerBufferAddressKernelLevel[i])) >> 4);
		/* add to linked list at the end of the data list */
		list_add_tail( &(new->list), &(APCI3600_PRIVDATA(pdev)->data_list));

		/* Compute the number of bytes that are copied in the list */
		number_of_byte += (new->number_of_value * 4);
	}

	return number_of_byte;
}
//--------------------------------------------------------------------------------
int __needlock apci3600_clear_available_data(struct pci_dev * pdev)
{
	struct list_head * head = &(APCI3600_PRIVDATA(pdev)->data_list); 
	
	while(1)
	{
		struct apci3600_data_t * data_entry = NULL;
		struct list_head * list_entry = NULL;
		register uint32_t amount32 = 0; 
		
		if ( list_empty( head) )
			return 0;
	
	 	list_entry = head->next;
		data_entry = list_entry( list_entry , struct apci3600_data_t, list);
		amount32=data_entry->number_of_value; /* amount in 32-bits units of data. including header */
		/* remove from list and free memory */
		list_del(list_entry);
		kfree(data_entry);
		i_PCI3600_Intern_IncrAnaInpChronoBufferReadPointer (pdev, amount32);
	}
}
//--------------------------------------------------------------------------------
/* copy the first entry available in user buffer  */
int __needlock apci3600_do_read_available_data(struct pci_dev * pdev, struct file *filp, char __user * pdata, size_t count, loff_t* off)
{
	size_t written = 0; /* amount of bytes written in user buffer */

	_3600INT_MARK();

	/* copy as much as possible from data list */
	while(1)
	{
		/* if data list is empty, returns */
		if ( list_empty( & APCI3600_PRIVDATA(pdev)->data_list) )
			return written;

		/* copy the next available data entry in the user buffer */
		{
			struct list_head * list_entry = APCI3600_PRIVDATA(pdev)->data_list.next;
			struct apci3600_data_t * data_entry = list_entry( list_entry , struct apci3600_data_t, list);
			register uint32_t amount32 = data_entry->number_of_value; /* amount in 32-bits unit of data */
			register uint32_t amount8 = sizeof(uint32_t) * amount32; /* amount in 8-bits unit of data */

			/* will the amount of data fit in user buffer - if not, return ? */
			if ( (amount8+written)  > count )
			{
				/* nothing has been written, then we got a situation, because the data will never fit in user provided buffer
				 * give a chance to calling process to adjust its buffer size */
				if (!written)
					return -ENOMEM;
				else
					return written;
			}

			*off=0;

			if (copy_to_user ( pdata + written, (char*) data_entry->pbuffer, amount8))
				return -EFAULT;

			written += amount8;

			/* remove from list and free memory */
			list_del(list_entry);
			kfree(data_entry);

			/* increment read pointer */
			i_PCI3600_Intern_IncrAnaInpChronoBufferReadPointer (pdev, amount32);
		}
	}
	return written;
}

/*v_PCI3600_Intern_UserInterruptManagement*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : v_PCI3600_Intern_UserInterruptManagement ()                |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*+----------------------------------------------------------------------------+*/

static void  __needlock v_PCI3600_Intern_UserInterruptManagement (struct pci_dev *pdev,
		uint32_t dw_InterruptSource,
		uint32_t  dw_InterruptMask,
		uint32_t  dw_NbrOfComputerBuffer,
		uint32_t* pdw_ComputerBufferAddressKernelLevel,
		uint32_t* pdw_ComputerBufferAddressApplicLevel)
{
	uint32_t * pdw_Pointer;
	long unsigned read;
	int nb_values_to_read;
	apci3600_event_t evt;
	int ret = 0;
	
	//TODO : Write to User fifo the infos

	if (!APCI3600_PRIVDATA(pdev)->
				  s_PCI3600_BoardInformation.
				  s_AnaInpChronomPCDMABufferInfos.
				  b_Empty)
		_3600INT_DPRINTK ("The ring buffer is not leer\n");
	else
		_3600INT_DPRINTK ("The ring buffer is leer\n");


	if (!APCI3600_PRIVDATA(pdev)->s_PCI3600_BoardInformation.s_AnaInpChronomPCDMABufferInfos.b_Full)
		_3600INT_DPRINTK ("The ring buffer is not full\n");
	else
		_3600INT_DPRINTK ("The ring buffer is full\n");
	
	pdw_Pointer = (uint32_t *)(uintptr_t)APCI3600_PRIVDATA(pdev)->s_PCI3600_BoardInformation.s_AnaInpChronomPCDMABufferInfos.pdw_DMABuffer[0];
	
 	_3600INT_DPRINTK ("Address in kernel space of the ring buffer:0x%08lX\n",(long unsigned)pdw_Pointer);


	#if  defined(__MIPSEL__)
	_3600INT_DPRINTK ("Phys address of the ring buffer:0x%08lX\n",(long unsigned)PHYSADDR(pdw_Pointer));
	#elif defined(__MIPSEB__)
	_3600INT_DPRINTK ("Phys address of the ring buffer:0x%08lX\n",(long unsigned)PHYSADDR(pdw_Pointer));
	#else
	_3600INT_DPRINTK ("Phys address of the ring buffer:0x%08lX\n",(long unsigned)virt_to_phys(pdw_Pointer));
	#endif
	
	_3600INT_DPRINTK ("Read Pointer : %lX\tFirst value : 	%lu\n",
			(long unsigned)APCI3600_PRIVDATA(pdev)->s_PCI3600_BoardInformation.s_AnaInpChronomPCDMABufferInfos.dw_ReadPointer,
			(long unsigned)pdw_Pointer[APCI3600_PRIVDATA(pdev)->s_PCI3600_BoardInformation.s_AnaInpChronomPCDMABufferInfos.dw_ReadPointer+1]
		   );

	read=APCI3600_PRIVDATA(pdev)->s_PCI3600_BoardInformation.s_AnaInpChronomPCDMABufferInfos.dw_ReadPointer;
	
	nb_values_to_read=(pdw_Pointer[read]>>4)&0x0FFFFFFF;

	_3600INT_DPRINTK ("Write Pointer : %lX\n",
			(long unsigned)APCI3600_PRIVDATA(pdev)->s_PCI3600_BoardInformation.s_AnaInpChronomPCDMABufferInfos.dw_WritePointer);
	_3600INT_DPRINTK ("Number of values (fb): %d 0x%08X\n",nb_values_to_read,nb_values_to_read);

	evt.mask = dw_InterruptMask;
			
	/* save data information */ 
	if ((ret = apci3600_save_data_chunk(pdev, pdw_ComputerBufferAddressKernelLevel, dw_NbrOfComputerBuffer)) < 0)
	{
		/* Set the mask defined in the interrupt routine and add the "Internal FIFO error interrupt" bit
		 * to inform the user that there is a problem with the memory allocation.
		 */
		evt.mask |= 0x2;		
		evt.numberbytes = 0;
	}
	else
		evt.numberbytes = ret;

	
	/* send SIGIO to registered processes */
	apci3600_kill_fasync(pdev);
	
	// generates an event - waiting processes will be waked up  
	evt.source = dw_InterruptSource;
	evt.buffnumber =  dw_NbrOfComputerBuffer;		
		
	/* save event in FIFO */
	apci3600_evt_add(pdev,&evt,1);
	apci3600_evt_wakeup(pdev);
	
	_3600INT_DPRINTK("event sent: ReadPointer %lX\n",(long unsigned) APCI3600_PRIVDATA(pdev)->s_PCI3600_BoardInformation.s_AnaInpChronomPCDMABufferInfos.dw_ReadPointer);

	

/*	Under Windows, a user function can be called by the driver
	Linux concept is to separate user and kernel mode
*/
//	
//	/* Test if user function installed */
//	
//	if (APCI3600_PRIVDATA(pdev)->
//			s_PCI3600_BoardInformation.
//			s_InterruptInformations.
//			b_UserInterruptHandlerInstalled == 1)
//	{
//		APCI3600_PRIVDATA(pdev)->
//		s_PCI3600_BoardInformation.
//		s_InterruptInformations.
//		v_UserInterrupt(pdev,
//						dw_InterruptSource,
//						dw_InterruptMask,
//						dw_NbrOfComputerBuffer,
//						pdw_ComputerBufferAddressKernelLevel,
//						pdw_ComputerBufferAddressApplicLevel);
//		/*if installed then execute*/
//	}
//	else
//		_3600INT_DPRINTK("No user function installed!\n");

	//BEGIN 18/04/2006  BF151
	

	//END 18/04/2006  BF151

	//           
	//           /* Save the Interrupt source */
	//           
	//           APCI3600_PRIVDATA(pdev)->
	//           s_PCI3600_BoardInformation.
	//           s_InterruptInformations.
	//           s_SaveInterruptEvent.
	//           s_SaveInterruptEventFIFO[APCI3600_PRIVDATA(pdev)->
	//                                    s_PCI3600_BoardInformation.
	//                                    s_InterruptInformations.
	//                                    s_SaveInterruptEvent.
	//                                    w_Write].
	//           dw_InterruptSource = dw_InterruptSource;
	//
	//           
	//           /* Save the Interrupt mask */
	//           
	//           APCI3600_PRIVDATA(pdev)->
	//           s_PCI3600_BoardInformation.
	//           s_InterruptInformations.
	//           s_SaveInterruptEvent.
	//           s_SaveInterruptEventFIFO[APCI3600_PRIVDATA(pdev)->
	//                                    s_PCI3600_BoardInformation.
	//                                    s_InterruptInformations.
	//                                    s_SaveInterruptEvent.
	//                                    w_Write].
	//           dw_InterruptMask = dw_InterruptMask;
	//
	//           
	//           /* Save the nbr of buffer */
	//           
	//           APCI3600_PRIVDATA(pdev)->
	//           s_PCI3600_BoardInformation.
	//           s_InterruptInformations.
	//           s_SaveInterruptEvent.
	//           s_SaveInterruptEventFIFO[APCI3600_PRIVDATA(pdev)->
	//                                    s_PCI3600_BoardInformation.
	//                                    s_InterruptInformations.
	//                                    s_SaveInterruptEvent.
	//                                    w_Write].
	//           dw_NbrOfComputerBuffer = dw_NbrOfComputerBuffer;
	//
	//           for (dw_Cpt = 0; dw_Cpt < dw_NbrOfComputerBuffer; dw_Cpt ++)
	//              {
	//              
	//              /* Save the pdw_ComputerRAMAddressKernelLevel */
	//              
	//              APCI3600_PRIVDATA(pdev)->
	//              s_PCI3600_BoardInformation.
	//              s_InterruptInformations.
	//              s_SaveInterruptEvent.
	//              s_SaveInterruptEventFIFO[APCI3600_PRIVDATA(pdev)->
	//                                       s_PCI3600_BoardInformation.
	//                                       s_InterruptInformations.
	//                                       s_SaveInterruptEvent.
	//                                       w_Write].
	//              pdw_ComputerRAMAddressKernelLevel[dw_Cpt] = pdw_ComputerBufferAddressKernelLevel[dw_Cpt];
	//
	//              
	//              /* Save the pdw_ComputerRAMAddressApplicationLevel */
	//              
	//              APCI3600_PRIVDATA(pdev)->
	//              s_PCI3600_BoardInformation.
	//              s_InterruptInformations.
	//              s_SaveInterruptEvent.
	//              s_SaveInterruptEventFIFO[APCI3600_PRIVDATA(pdev)->
	//                                       s_PCI3600_BoardInformation.
	//                                       s_InterruptInformations.
	//                                       s_SaveInterruptEvent.
	//                                       w_Write].
	//              pdw_ComputerRAMAddressApplicationLevel[dw_Cpt] = pdw_ComputerBufferAddressApplicLevel[dw_Cpt];
	//
	//              }
	//           
	//           /* Incr the write FIFO */
	//           
	//           APCI3600_PRIVDATA(pdev)->
	//           s_PCI3600_BoardInformation.
	//           s_InterruptInformations.
	//           s_SaveInterruptEvent.
	//           w_Write = (APCI3600_PRIVDATA(pdev)->
	//                      s_PCI3600_BoardInformation.
	//                      s_InterruptInformations.
	//                      s_SaveInterruptEvent.
	//                      w_Write + 1) % PCI3600_INTERRUPT_FIFO_SIZE;

}

/*v_PCI3600_Intern_InterruptFunction*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : v_PCI3600_Intern_InterruptFunction ()                      |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*        Interrupt Function of the driver                                      */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*+----------------------------------------------------------------------------+*/

int __needlock i_PCI3600_Intern_InterruptFunction (struct pci_dev *pdev)
{
	uint8_t b_InterruptOccur = 0;
	uint8_t b_Channel = 0;
	uint8_t b_Module = 0;
	uint8_t b_Source = 0;
	int i_Return = 0;
	uint32_t dw_InterruptMask = 0;
	uint32_t dw_InterruptSource = 0;
	uint32_t dw_NbrOfComputerBuffer = 0;
	uint32_t dw_ValueToWrite = 0;
	uint32_t dw_NbrOfData = 0;
	uint32_t dw_FIFOErrorStatus = 0;
	uint32_t dw_NbrOfDataToBeTransfered = 0;
	uint32_t dw_NbrOfDescriptorUsed = 0;
	uint32_t dw_OnBoardReadPointer = 0;
	uint32_t dw_OnBoardWritePointer = 0;
	uint32_t dw_OnBoardNbrOfData = 0;
	uint32_t pdw_ComputerBufferAddressKernelLevel [PCI3600_MAX_NBR_COMPUTER_BUFFER];
	uint32_t pdw_ComputerBufferAddressApplicLevel [PCI3600_MAX_NBR_COMPUTER_BUFFER];
	uint32_t dw_InterruptStatus = 0;
	uint32_t dw_ReadValue = 0;
	uint32_t dw_AnaInpChronoPCBuffer_TempWritePointer = 0;
	uint8_t b_AnaInpChronoPCBuffer_TempFull = 0;
	uint32_t dw_DMAStatus = 0;
	uint32_t dw_ActualDescriptorPCIAddress = 0;

	uint8_t b_ManageTheNextDescriptor = 0;
	uint32_t dw_DescriptorCpt = 0;


	b_InterruptOccur = 0;


	
	/* Read the board interrupt status */
	
	INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,&dw_InterruptStatus);
	_3600INT_DPRINTK("Interrupt Routine called!!!! dw_InterruptStatus %X\n",dw_InterruptStatus);


	
	/* Test if DMA Interrupt */
	
	if ((dw_InterruptStatus >> 28) & 1)
	{
PRINTKIF("1: DMA interrupt");
		
		/* Read the DMA Status */
		
		INPDW_MEM (GET_MEM_BAR0(pdev),0xA8,&dw_DMAStatus);

		
		/* Test if the DMA Done occur -> End of descriptor */
		
		if (dw_DMAStatus & 0x10) {
			
			/* Release the DMA Interrupt                                    */
			
			/*HR068 DMA IRQ Release must be released for the PCI IRQ Release*/
			OUTPDW_MEM (GET_MEM_BAR0(pdev),0xA8,0x8);
PRINTKIF("1.1: DMA Done");

		} else {
			
			/* Release the DMA Interrupt                                    */
			
			/*HR068 DMA IRQ Release must be released for the PCI IRQ Release*/
			OUTPDW_MEM (GET_MEM_BAR0(pdev),0xA8,0xB);
PRINTKIF("1.2: NO DMA Done");
		}
		
		/* Read the Address of the actual descriptor */
		
		INPDW_MEM (GET_MEM_BAR0(pdev),0x84,&dw_ActualDescriptorPCIAddress);

	}
	
	/* Test if this board has generate the interrupt */
	
	if ((dw_InterruptStatus & 0x1FFC0000UL) != 0)
	{
		
		/* Release the interrupt */
		
PRINTKIF("2");
		OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,0x1FFC0000UL);

	}

	
	/* Test if this board has generate a compare or auto-stop interrupt */
	
	if ((dw_InterruptStatus & 0x0003FFFFUL) != 0)
	{
PRINTKIF("3: compare or auto-stop interrupt");
		
		/* Release the interrupt */
		
		OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,0x80000000UL);

	}



	
	/* Test if a DMA Interupt occur */
	
	if ((dw_InterruptStatus >> 28) & 1)
	{
PRINTKIF("4: DMA Interupt occur");
		do {
			
			/* Manage the DMA Interrupt */
			
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
					b_InUse == 1) {
PRINTKIF("4.1");
				
				/* Test if analog output DMA transfer */
				
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
						ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
										   s_PCI3600_BoardInformation.
										   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
										   b_DMATranferIndex].
						b_RessourceID < 2) {
PRINTKIF("4.1.1: analog output DMA transfer");
					b_Channel = APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												   b_DMATranferIndex].
								b_RessourceID;

					
					/* Update the write pointer of the board Buffer */
					
					INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
							   164 + (4 * b_Channel),
							   &dw_ReadValue);

					dw_ValueToWrite = (dw_ReadValue + APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									   ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
														  s_PCI3600_BoardInformation.
														  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
														  b_DMATranferIndex].
									   dw_NbrOfByteTransfered) %
									  APCI3600_PRIVDATA(pdev)->
									  s_PCI3600_BoardInformation.
									  ps_OnBoardRAMReservedBuffer [b_Channel].
									  dw_BufferSize;

					OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								164 + (4 * b_Channel),
								dw_ValueToWrite);

					
					/* Release the Interrupt Flag */
					
					
					/* Release the interrupt */
					
					OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << (8 + b_Channel)));

					
					/* Update the read pointer of the Computer Buffer */
					
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					s_AnalogOutPCDMABufferInfos.
					dw_ReadPointer = (APCI3600_PRIVDATA(pdev)->
									  s_PCI3600_BoardInformation.
									  s_AnalogOutInfos[b_Channel].
									  s_AnalogOutPCDMABufferInfos.
									  dw_ReadPointer + (APCI3600_PRIVDATA(pdev)->
														s_PCI3600_BoardInformation.
														s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
														ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
																		   s_PCI3600_BoardInformation.
																		   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
																		   b_DMATranferIndex].
														dw_NbrOfByteTransfered / 4)) %
									 (APCI3600_PRIVDATA(pdev)->
									  s_PCI3600_BoardInformation.
									  s_AnalogOutInfos[b_Channel].
									  s_AnalogOutPCDMABufferInfos.
									  dw_BufferSize / 4);

					
					/* Update the Flag of the computer buffer */
					
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					s_AnalogOutPCDMABufferInfos.
					b_Full = 0;

					
					/* Test if PC Buffer is empty */
					
					if (APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnalogOutInfos[b_Channel].
							s_AnalogOutPCDMABufferInfos.
							dw_ReadPointer == APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnalogOutInfos[b_Channel].
							s_AnalogOutPCDMABufferInfos.
							dw_WritePointer) {
						APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnalogOutInfos[b_Channel].
						s_AnalogOutPCDMABufferInfos.
						b_Empty = 1;
PRINTKIF("4.1.1.1");
					}
					
					/* Set the parameters for the user interrupt routine */
					
					dw_InterruptSource = (1 << b_Channel);

					dw_InterruptMask = dw_InterruptMask | 1;

					dw_NbrOfComputerBuffer = 0;

					pdw_ComputerBufferAddressKernelLevel[0] = 0;
					pdw_ComputerBufferAddressApplicLevel[0] = 0;

					
					/* User interrupt routine Management */
					
					v_PCI3600_Intern_UserInterruptManagement (pdev,
							dw_InterruptSource,
							dw_InterruptMask,
							dw_NbrOfComputerBuffer,
							pdw_ComputerBufferAddressKernelLevel,
							pdw_ComputerBufferAddressApplicLevel);

				}
				
				/* Test if analog input / Chronometer DMA transfer */
				
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
						ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
										   s_PCI3600_BoardInformation.
										   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
										   b_DMATranferIndex].
						b_RessourceID > 1) {
PRINTKIF("4.1.2: analog input / Chronometer DMA transfer");
					if (APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_DMATranferIndex].
							b_RessourceID < 6) {
PRINTKIF("4.1.2.1:Source = ADC ");
						/****************/
						/* Source = ADC */
						/****************/
						b_Source = 0;
						b_Module = APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								   ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
													  s_PCI3600_BoardInformation.
													  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
													  b_DMATranferIndex].
								   b_RessourceID - 2;

					} else {
PRINTKIF("4.1.2.2: Source = Chronometer");
						/************************/
						/* Source = Chronometer */
						/************************/
						b_Source = 1;
						b_Module = APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								   ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
													  s_PCI3600_BoardInformation.
													  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
													  b_DMATranferIndex].
								   b_RessourceID - 6;

					}
					
					/* Update the read pointer of the board Buffer  */
					
					INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
							   132 + (4 * (APCI3600_PRIVDATA(pdev)->
										   s_PCI3600_BoardInformation.
										   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
										   ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
															  s_PCI3600_BoardInformation.
															  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
															  b_DMATranferIndex].
										   b_RessourceID - 2)),
							   &dw_ReadValue);

					dw_ValueToWrite = (dw_ReadValue + APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									   ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
														  s_PCI3600_BoardInformation.
														  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
														  b_DMATranferIndex].
									   dw_NbrOfByteTransfered) %
									  APCI3600_PRIVDATA(pdev)->
									  s_PCI3600_BoardInformation.
									  ps_OnBoardRAMReservedBuffer [APCI3600_PRIVDATA(pdev)->
																   s_PCI3600_BoardInformation.
																   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
																   ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
																					  s_PCI3600_BoardInformation.
																					  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
																					  b_DMATranferIndex].
																   b_RessourceID].
									  dw_BufferSize;

					OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								132 + (4 * (APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
															   s_PCI3600_BoardInformation.
															   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
															   b_DMATranferIndex].
											b_RessourceID - 2)),
								dw_ValueToWrite);

					
					/* Release the Interrupt Flag */
					
					/********************************************************/
					/* Test if Compare Interrupt has started the DMA transfer */
					/********************************************************/
					if (APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_DMATranferIndex].
							b_Mode == 0) {
PRINTKIF("4.1.3.1: Compare Interrupt has start the DMA transfer");
						
						/* Release the interrupt */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << (APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
													   s_PCI3600_BoardInformation.
													   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
													   b_DMATranferIndex].
									b_RessourceID - 2)));

					} else {
PRINTKIF("4.1.3.2");
						
						/* Release the interrupt */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << (10 + APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
													   s_PCI3600_BoardInformation.
													   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
													   b_DMATranferIndex].
									b_RessourceID - 2)));

					}
					
					/* Set the parameters for the user interrupt routine */
					
					dw_InterruptSource = (1 << APCI3600_PRIVDATA(pdev)->
										  s_PCI3600_BoardInformation.
										  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
										  ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
															 s_PCI3600_BoardInformation.
															 s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
															 b_DMATranferIndex].
										  b_RessourceID);

					/********************************************************/
					/* Test if Compare Interrupt has start the DMA transfer */
					/********************************************************/
					if (APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_DMATranferIndex].
							b_Mode == 0) {
						dw_InterruptMask = dw_InterruptMask | 1;
PRINTKIF("4.1.4.1 Compare Interrupt has start the DMA transfer ");
					} else {
						dw_InterruptMask = dw_InterruptMask | 0x10;
PRINTKIF("4.1.4.2");
					}
					i_PCI3600_Intern_UpdatePCBufferWithHeaderAndReturnPointer (PCI3600_RING_0,
							b_Module,
							b_Source,
							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							pdw_DMABuffer,
							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							dw_BufferSize,
							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							dw_ReadPointer,
							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							dw_WritePointer,
							(uint32_t)(APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
													   s_PCI3600_BoardInformation.
													   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
													   b_DMATranferIndex].
									dw_NbrOfByteTransfered / 4),
							pdw_ComputerBufferAddressKernelLevel,
							pdw_ComputerBufferAddressApplicLevel,
							&dw_NbrOfComputerBuffer);

					
					/* Update the write pointer of the Computer Buffer */
					
					
					/* Test if the last uint32_t of the buffer */
					
					if ((APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							dw_WritePointer + 1) == (APCI3600_PRIVDATA(pdev)->
													 s_PCI3600_BoardInformation.
													 s_AnaInpChronomPCDMABufferInfos.
													 dw_BufferSize / 4)) {
PRINTKIF("4.1.5");
						APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnaInpChronomPCDMABufferInfos.
						dw_WritePointer = 0;

					}
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnaInpChronomPCDMABufferInfos.
					dw_WritePointer = (APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_AnaInpChronomPCDMABufferInfos.
									   dw_WritePointer + (APCI3600_PRIVDATA(pdev)->
														  s_PCI3600_BoardInformation.
														  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
														  ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
																			 s_PCI3600_BoardInformation.
																			 s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
																			 b_DMATranferIndex].
														  dw_NbrOfByteTransfered / 4) + dw_NbrOfComputerBuffer) %
									  (APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_AnaInpChronomPCDMABufferInfos.
									   dw_BufferSize / 4);

					
					/* Update the Flag of the computer buffer */
					
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnaInpChronomPCDMABufferInfos.
					b_Empty = 0;

					
					/* Test if PC Buffer is full */
					
					if ((APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							dw_ReadPointer == APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							dw_WritePointer)) {
						APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnaInpChronomPCDMABufferInfos.
						b_Full = 1;
PRINTKIF("4.1.6.1");
					} else {
PRINTKIF("4.1.6.2");
						
						/* Test if the last uint32_t of the buffer */
						
						if ((APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnaInpChronomPCDMABufferInfos.
								dw_WritePointer + 1) == (APCI3600_PRIVDATA(pdev)->
														 s_PCI3600_BoardInformation.
														 s_AnaInpChronomPCDMABufferInfos.
														 dw_BufferSize / 4)) {
PRINTKIF("4.1.6.2.1:last uint32_t of the buffer ");
							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							dw_WritePointer = 0;

							
							/* Test if PC Buffer is full */
							
							if ((APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_AnaInpChronomPCDMABufferInfos.
									dw_ReadPointer == APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_AnaInpChronomPCDMABufferInfos.
									dw_WritePointer)) {
PRINTKIF("4.1.6.2.1.1: PC Buffer is full ");
								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnaInpChronomPCDMABufferInfos.
								b_Full = 1;

							}
						}
						
						/* Test if only 1 uint32_t free in the PC Buffer */
						
						if (((APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnaInpChronomPCDMABufferInfos.
								dw_WritePointer + 1) % (APCI3600_PRIVDATA(pdev)->
														s_PCI3600_BoardInformation.
														s_AnaInpChronomPCDMABufferInfos.
														dw_BufferSize / 4)) == APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnaInpChronomPCDMABufferInfos.
								dw_ReadPointer) {
PRINTKIF("4.1.6.2.2:only 1 uint32_t free in the PC Buffer ");
							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							dw_WritePointer = APCI3600_PRIVDATA(pdev)->
											  s_PCI3600_BoardInformation.
											  s_AnaInpChronomPCDMABufferInfos.
											  dw_ReadPointer;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnaInpChronomPCDMABufferInfos.
							b_Full = 1;

						}
					}

					
					/* User interrupt routine Management */
					
					v_PCI3600_Intern_UserInterruptManagement (pdev,
							dw_InterruptSource,
							dw_InterruptMask,
							dw_NbrOfComputerBuffer,
							pdw_ComputerBufferAddressKernelLevel,
							pdw_ComputerBufferAddressApplicLevel);

				}
				
				/* Incr the DMA transfer index */
				
				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
				b_DMATranferIndex = APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									b_DMATranferIndex + 1;

				
				/* Test if the last DMA transfer descriptor */
				
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
						b_DMATranferIndex == APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
						b_NbrDMATranfer) {
PRINTKIF("4.1.7: last DMA transfer descriptor");
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
					b_DMATranferIndex = 0;

					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
					b_NbrDMATranfer = 0;

					
					/* Set the DMA Channel as not used */
					

					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
					b_InUse = 0;

					
					/* Release new compare/Auto-Stop IRQ */
					
					OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,0x40000000UL);

				}
			} else {
	PRINTKIF("4.2");
				break;

			}
			
			/* Test if another descriptor is finish */
			
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
					b_InUse == 1) {
	PRINTKIF("5.1 (was 5)");
				b_ManageTheNextDescriptor = 1;

				for (dw_DescriptorCpt = 0; dw_DescriptorCpt < APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						ps_DescriptorsInfos[APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
															   s_PCI3600_BoardInformation.
															   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
															   b_DMATranferIndex - 1].
											b_RessourceID].
						dw_NbrOfDescriptorUsed; dw_DescriptorCpt ++) {
					if (APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							ps_DescriptorsInfos[APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
																   s_PCI3600_BoardInformation.
																   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
																   b_DMATranferIndex - 1].
												b_RessourceID].
							ps_PCI9054DMADescriptor[dw_DescriptorCpt].
							dw_BufferPhysicalAddress == dw_ActualDescriptorPCIAddress) {
PRINTKIF("5.1.1 (was 5.1)");
						b_ManageTheNextDescriptor = 0;

					}
				}
			} else {
PRINTKIF("5.2");
				b_ManageTheNextDescriptor = 0;

			}
		} while (b_ManageTheNextDescriptor == 1);
		b_InterruptOccur = 1;

	}


	/*----------------------------------------------------------------------------*/
	/*                AUTO-STOP / COMPARE IRQ MANAGEMENT                          */
	/*----------------------------------------------------------------------------*/

	
	/* Test if compare/Auto-Stop interrupt occur */
	
	if ((dw_InterruptStatus & 0x3FFFF) != 0)
	{
PRINTKIF("6: compare/Auto-Stop interrupt occured");
		
		/* Manage the compare / Auto-Stop Interrupt */
		
		
		/* Test if the DMA channel is free to use */
		
		if (APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
				b_InUse == 0) {
PRINTKIF("6.1: DMA channel is freed to use");
			
			/* Initialise the nbr of DMA transfer to do */
			
			APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
			b_NbrDMATranfer = 0;

			APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
			b_DMATranferIndex = 0;

			dw_AnaInpChronoPCBuffer_TempWritePointer = APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnaInpChronomPCDMABufferInfos.
					dw_WritePointer;
			b_AnaInpChronoPCBuffer_TempFull = APCI3600_PRIVDATA(pdev)->
											  s_PCI3600_BoardInformation.
											  s_AnaInpChronomPCDMABufferInfos.
											  b_Full;

			/*$/$/ CG 24/02/2005 : change the management order :*/
			/*Before : DAC Compare                              */
			/*         ADC Compare                              */
			/*         CHRONO Compare                           */
			/*         ADC Auto-Stop                            */
			/*         CHRONO Auto-Stop                         */
			/*After :  CHRONO Compare                           */
			/*         ADC Compare                              */
			/*         DAC Compare                              */
			/*         ADC Auto-Stop                            */
			/*         CHRONO Auto-Stop                         */
			
			/* Test if a Chronometer Compare Interrupt */
			
			for (b_Module = 0; b_Module < 4; b_Module ++) {
				if (((dw_InterruptStatus >> 4) & (1 << b_Module))!= 0) {
PRINTKIF("6.1.1: Chronometer Compare Interrupt");
					
					/* Test if the PC Buffer is not full */
					
					if (b_AnaInpChronoPCBuffer_TempFull == 0) {
PRINTKIF("6.1.1.1: PC Buffer is not full");
						
						/* Determine the number of data in the PC RAM buffer */
						
						if (APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnaInpChronomPCDMABufferInfos.
								dw_ReadPointer > dw_AnaInpChronoPCBuffer_TempWritePointer  ) {
PRINTKIF("6.1.1.1.1");
							dw_NbrOfData = ((APCI3600_PRIVDATA(pdev)->
											 s_PCI3600_BoardInformation.
											 s_AnaInpChronomPCDMABufferInfos.
											 dw_BufferSize / 4) - APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer) + dw_AnaInpChronoPCBuffer_TempWritePointer;

						} else {
PRINTKIF("6.1.1.1.2");
							dw_NbrOfData = dw_AnaInpChronoPCBuffer_TempWritePointer - APCI3600_PRIVDATA(pdev)->
										   s_PCI3600_BoardInformation.
										   s_AnaInpChronomPCDMABufferInfos.
										   dw_ReadPointer;

						}
						
						/* Read On board information */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   148 + (4 * b_Module),&dw_OnBoardReadPointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   108 + (4 * b_Module),&dw_OnBoardWritePointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   188 + (4 * b_Module),&dw_OnBoardNbrOfData);

						
						/* Complete the descriptor list */
						
						dw_NbrOfDescriptorUsed = 0;
						dw_NbrOfDataToBeTransfered = 0;

						i_Return = i_PCI3600_Intern_PCI9054_CompleteScatterGatherDescriptor (PCI3600_DMA_BOARD_TO_PC,
								   PCI3600_ENABLE,
								   1, // Reserve Header place
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnaInpChronomPCDMABufferInfos.
								   dw_PhysicalAddress,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnaInpChronomPCDMABufferInfos.
								   dw_BufferSize,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnaInpChronomPCDMABufferInfos.
								   dw_ReadPointer,
								   dw_AnaInpChronoPCBuffer_TempWritePointer,
								   dw_NbrOfData,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_OnBoardRAMReservedBuffer[b_Module + 6].
								   dw_Address,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_OnBoardRAMReservedBuffer[b_Module + 6].
								   dw_BufferSize,
								   (dw_OnBoardReadPointer / 4), // In uint32_t 
								   (dw_OnBoardWritePointer / 4), // In uint32_t 
								   (dw_OnBoardNbrOfData / 4), // In uint32_t 
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_DescriptorsInfos[b_Module + 6].
								   dw_NbrOfDescriptorAllocated,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_DescriptorsInfos[b_Module + 6].
								   dw_DescriptorListPhysicalAddress,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_DescriptorsInfos[b_Module + 6].
								   ps_PCI9054DMADescriptor,
								   &dw_NbrOfDescriptorUsed,
								   &dw_NbrOfDataToBeTransfered);

						
						/* Test if no Error occur */
						
						if (i_Return == 0) {
PRINTKIF("6.1.1.2");
							
							/* Save the DMA transfer information */
							
							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							ps_DescriptorsInfos[b_Module + 6].
							dw_NbrOfDescriptorUsed = dw_NbrOfDescriptorUsed;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							b_RessourceID = (uint8_t)(b_Module + 6);

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							dw_NbrOfByteTransfered = (dw_NbrOfDataToBeTransfered * 4);

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							b_Mode = 0;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							b_ProcessIndex = APCI3600_PRIVDATA(pdev)->
											 s_PCI3600_BoardInformation.
											 s_ChronometerInfos[b_Module].
											 b_ChronometerCyclicAcquisitionStartProcessIndex;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							b_NbrDMATranfer = APCI3600_PRIVDATA(pdev)->
											  s_PCI3600_BoardInformation.
											  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											  b_NbrDMATranfer + 1;

							
							/* Update the temp Write Pointer of the PC Buffer */
							
							dw_AnaInpChronoPCBuffer_TempWritePointer = (dw_AnaInpChronoPCBuffer_TempWritePointer +
									dw_NbrOfDataToBeTransfered +
									dw_NbrOfDescriptorUsed) %
									(APCI3600_PRIVDATA(pdev)->
									 s_PCI3600_BoardInformation.
									 s_AnaInpChronomPCDMABufferInfos.
									 dw_BufferSize / 4);

							
							/* Update the Temp Flag of the computer buffer */
							
							
							/* Test if PC Buffer is full */
							
							if (APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_AnaInpChronomPCDMABufferInfos.
									dw_ReadPointer == dw_AnaInpChronoPCBuffer_TempWritePointer) {
								b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("6.1.1.2.1");
							} else {
PRINTKIF("6.1.1.2.2");
								
								/* Test if the last uint32_t of the buffer */
								
								if ((dw_AnaInpChronoPCBuffer_TempWritePointer + 1) == (APCI3600_PRIVDATA(pdev)->
										s_PCI3600_BoardInformation.
										s_AnaInpChronomPCDMABufferInfos.
										dw_BufferSize / 4)) {
PRINTKIF("6.1.1.2.2.1");
									dw_AnaInpChronoPCBuffer_TempWritePointer = 0;

									
									/* Test if PC Buffer is full */
									
									if ((APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer == dw_AnaInpChronoPCBuffer_TempWritePointer)) {
										b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("6.1.1.2.2.1.1");
									}
								}
								
								/* Test if only 1 uint32_t free in the PC Buffer */
								
								if (((dw_AnaInpChronoPCBuffer_TempWritePointer + 1) % (APCI3600_PRIVDATA(pdev)->
										s_PCI3600_BoardInformation.
										s_AnaInpChronomPCDMABufferInfos.
										dw_BufferSize / 4)) == APCI3600_PRIVDATA(pdev)->
										s_PCI3600_BoardInformation.
										s_AnaInpChronomPCDMABufferInfos.
										dw_ReadPointer) {
									dw_AnaInpChronoPCBuffer_TempWritePointer = APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer;
PRINTKIF("6.1.1.2.2.2");
									b_AnaInpChronoPCBuffer_TempFull = 1;

								}
							}
						}
					} else {

PRINTKIF("7");
						
						/* Set the parameters for the user interrupt routine */
						
						dw_InterruptSource =(1 << (b_Module + 6));

						dw_InterruptMask = 8;

						dw_NbrOfComputerBuffer = 0;

						pdw_ComputerBufferAddressKernelLevel[0] = 0;
						pdw_ComputerBufferAddressApplicLevel[0] = 0;

						
						/* User interrupt routine Management */
						
						v_PCI3600_Intern_UserInterruptManagement (pdev,
								dw_InterruptSource,
								dw_InterruptMask,
								dw_NbrOfComputerBuffer,
								pdw_ComputerBufferAddressKernelLevel,
								pdw_ComputerBufferAddressApplicLevel);


						/*$/$/ CG 24/02/2005 : Reset the start bit*/
						
						/* Reset the start bit                    */
						
						
						/* Read the start register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,&dw_ReadValue);

						
						/* write the start register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,dw_ReadValue & (0xFFFFFFFFUL - (1 << (b_Module + 4))));

						
						/* Deactivate the module */
						
						
						/* Read the enable register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,&dw_ReadValue);

						
						/* write the enable register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,dw_ReadValue & (0xFFFFFFFFUL - (1 << (4 + b_Module)) - (1 << (14 + b_Module))));

						/*$/$/ CG 24/02/2005 : Release the interrupt*/
						
						/* Release the Interrupt Flag               */
						
						
						/* Release the interrupt */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << (b_Module + 4)));

					}
				}
			}
			
			/* Test if an ADC Compare Interrupt */
			
			for (b_Module = 0; b_Module < 4; b_Module ++) {
				if ((dw_InterruptStatus & (1 << b_Module))!= 0) {

PRINTKIF("8: ADC Compare Interrupt");
					
					/* Test if the PC Buffer is not full */
					
					if (b_AnaInpChronoPCBuffer_TempFull == 0) {
PRINTKIF("9: PC Buffer is not full");
						
						/* Determine the number of data in the PC RAM buffer */
						
						if (APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnaInpChronomPCDMABufferInfos.
								dw_ReadPointer > dw_AnaInpChronoPCBuffer_TempWritePointer  ) {
PRINTKIF("10");
							dw_NbrOfData = ((APCI3600_PRIVDATA(pdev)->
											 s_PCI3600_BoardInformation.
											 s_AnaInpChronomPCDMABufferInfos.
											 dw_BufferSize / 4) - APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer) + dw_AnaInpChronoPCBuffer_TempWritePointer;

						} else {
PRINTKIF("11");
							dw_NbrOfData = dw_AnaInpChronoPCBuffer_TempWritePointer - APCI3600_PRIVDATA(pdev)->
										   s_PCI3600_BoardInformation.
										   s_AnaInpChronomPCDMABufferInfos.
										   dw_ReadPointer;

						}
						
						/* Read On board information */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   132 + (4 * b_Module),&dw_OnBoardReadPointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   92 + (4 * b_Module),&dw_OnBoardWritePointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   172 + (4 * b_Module),&dw_OnBoardNbrOfData);

						
						/* Complete the descriptor list */
						
						dw_NbrOfDescriptorUsed = 0;
						dw_NbrOfDataToBeTransfered = 0;

						i_Return = i_PCI3600_Intern_PCI9054_CompleteScatterGatherDescriptor (PCI3600_DMA_BOARD_TO_PC,
								   PCI3600_ENABLE,
								   1,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnaInpChronomPCDMABufferInfos.
								   dw_PhysicalAddress,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnaInpChronomPCDMABufferInfos.
								   dw_BufferSize,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnaInpChronomPCDMABufferInfos.
								   dw_ReadPointer,
								   dw_AnaInpChronoPCBuffer_TempWritePointer,
								   dw_NbrOfData,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_OnBoardRAMReservedBuffer[b_Module + 2].
								   dw_Address,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_OnBoardRAMReservedBuffer[b_Module + 2].
								   dw_BufferSize,
								   (dw_OnBoardReadPointer / 4), // In uint32_t 
								   (dw_OnBoardWritePointer / 4), // In uint32_t 
								   (dw_OnBoardNbrOfData / 4), // In uint32_t 
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_DescriptorsInfos[b_Module + 2].
								   dw_NbrOfDescriptorAllocated,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_DescriptorsInfos[b_Module + 2].
								   dw_DescriptorListPhysicalAddress,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_DescriptorsInfos[b_Module + 2].
								   ps_PCI9054DMADescriptor,
								   &dw_NbrOfDescriptorUsed,
								   &dw_NbrOfDataToBeTransfered);

						
						/* Test if no Error occur */
						
						if (i_Return == 0) {
PRINTKIF("12:no Error occur");
							
							/* Save the DMA transfer information */
							
							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							ps_DescriptorsInfos[b_Module + 2].
							dw_NbrOfDescriptorUsed = dw_NbrOfDescriptorUsed;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							b_RessourceID = (uint8_t)(b_Module + 2);

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							dw_NbrOfByteTransfered = (dw_NbrOfDataToBeTransfered * 4);

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							b_Mode = 0;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							b_ProcessIndex = APCI3600_PRIVDATA(pdev)->
											 s_PCI3600_BoardInformation.
											 s_AnalogInModuleInfos[b_Module].
											 b_ModuleCyclicAcquisitionStartProcessIndex;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							b_NbrDMATranfer = APCI3600_PRIVDATA(pdev)->
											  s_PCI3600_BoardInformation.
											  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											  b_NbrDMATranfer + 1;

							
							/* Update the temp Write Pointer of the PC Buffer */
							
							dw_AnaInpChronoPCBuffer_TempWritePointer = (dw_AnaInpChronoPCBuffer_TempWritePointer +
									dw_NbrOfDataToBeTransfered +
									dw_NbrOfDescriptorUsed) %
									(APCI3600_PRIVDATA(pdev)->
									 s_PCI3600_BoardInformation.
									 s_AnaInpChronomPCDMABufferInfos.
									 dw_BufferSize / 4);

							
							/* Update the Temp Flag of the computer buffer */
							
							
							/* Test if PC Buffer is full */
							
							if (APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_AnaInpChronomPCDMABufferInfos.
									dw_ReadPointer == dw_AnaInpChronoPCBuffer_TempWritePointer) {
								b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("13: PC Buffer is full");
							} else {	
PRINTKIF("14: PC Buffer is not full");								
								/* Test if the last uint32_t of the buffer */
								
								if ((dw_AnaInpChronoPCBuffer_TempWritePointer + 1) == (APCI3600_PRIVDATA(pdev)->
										s_PCI3600_BoardInformation.
										s_AnaInpChronomPCDMABufferInfos.
										dw_BufferSize / 4)) {
PRINTKIF("15");
									dw_AnaInpChronoPCBuffer_TempWritePointer = 0;

									
									/* Test if PC Buffer is full */
									
									if ((APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer == dw_AnaInpChronoPCBuffer_TempWritePointer)) {
										b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("16");

									}
								}
								
								/* Test if only 1 uint32_t free in the PC Buffer */
								
								if (((dw_AnaInpChronoPCBuffer_TempWritePointer + 1) % (APCI3600_PRIVDATA(pdev)->
										s_PCI3600_BoardInformation.
										s_AnaInpChronomPCDMABufferInfos.
										dw_BufferSize / 4)) == APCI3600_PRIVDATA(pdev)->
										s_PCI3600_BoardInformation.
										s_AnaInpChronomPCDMABufferInfos.
										dw_ReadPointer) {
PRINTKIF("17");
									dw_AnaInpChronoPCBuffer_TempWritePointer = APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer;

									b_AnaInpChronoPCBuffer_TempFull = 1;

								}
							}
						}
					} else {
PRINTKIF("18");
						
						/* Set the parameters for the user interrupt routine */
						
						dw_InterruptSource =(1 << (b_Module + 2));

						dw_InterruptMask = 8;

						dw_NbrOfComputerBuffer = 0;

						pdw_ComputerBufferAddressKernelLevel[0] = 0;
						pdw_ComputerBufferAddressApplicLevel[0] = 0;

						
						/* User interrupt routine Management */
						
						v_PCI3600_Intern_UserInterruptManagement (pdev,
								dw_InterruptSource,
								dw_InterruptMask,
								dw_NbrOfComputerBuffer,
								pdw_ComputerBufferAddressKernelLevel,
								pdw_ComputerBufferAddressApplicLevel);


						/*$/$/ CG 24/02/2005 : Reset the start bit*/
						
						/* Reset the start bit                    */
						
						
						/* Read the start register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,&dw_ReadValue);

						
						/* write the start register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,dw_ReadValue & (0xFFFFFFFFUL - (1 << (b_Module))));

						
						/* Deactivate the module */
						
						
						/* Read the enable register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,&dw_ReadValue);

						
						/* write the enable register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,dw_ReadValue & (0xFFFFFFFFUL - (1 << b_Module) - (1 << (10 + b_Module))));

						/*$/$/ CG 24/02/2005 : Release the interrupt*/
						
						/* Release the Interrupt Flag               */
						
						
						/* Release the interrupt */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << b_Module));

					}
				}
			}
			
			/* Test if an DAC Compare Interrupt */
			
			for (b_Channel = 0; b_Channel < 2; b_Channel ++) {
				if (((dw_InterruptStatus >> 8) & (1 << b_Channel))!= 0) {
PRINTKIF("19");
					
					/* Test if the PC Buffer is not empty */
					
					if (APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnalogOutInfos[b_Channel].
							s_AnalogOutPCDMABufferInfos.
							b_Empty == 0) {
PRINTKIF("20");
						
						/* Determine the number of data in the PC RAM buffer */
						
						if (APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnalogOutInfos[b_Channel].
								s_AnalogOutPCDMABufferInfos.
								b_Full == 0) {
PRINTKIF("21");
							if (APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_AnalogOutInfos[b_Channel].
									s_AnalogOutPCDMABufferInfos.
									dw_ReadPointer > APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_AnalogOutInfos[b_Channel].
									s_AnalogOutPCDMABufferInfos.
									dw_WritePointer  ) {
PRINTKIF("22");
								dw_NbrOfData = ((APCI3600_PRIVDATA(pdev)->
												 s_PCI3600_BoardInformation.
												 s_AnalogOutInfos[b_Channel].
												 s_AnalogOutPCDMABufferInfos.
												 dw_BufferSize / 4) - APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_AnalogOutInfos[b_Channel].
												s_AnalogOutPCDMABufferInfos.
												dw_ReadPointer) + APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_AnalogOutInfos[b_Channel].
											   s_AnalogOutPCDMABufferInfos.
											   dw_WritePointer;

							} else {
PRINTKIF("23");
								dw_NbrOfData = APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_AnalogOutInfos[b_Channel].
											   s_AnalogOutPCDMABufferInfos.
											   dw_WritePointer - APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_AnalogOutInfos[b_Channel].
											   s_AnalogOutPCDMABufferInfos.
											   dw_ReadPointer;

							}
						} else {
PRINTKIF("24");
							dw_NbrOfData = APCI3600_PRIVDATA(pdev)->
										   s_PCI3600_BoardInformation.
										   s_AnalogOutInfos[b_Channel].
										   s_AnalogOutPCDMABufferInfos.
										   dw_BufferSize / 4;

						}
						
						/* Read On board information */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   124 + (4 * b_Channel),&dw_OnBoardReadPointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   164 + (4 * b_Channel),&dw_OnBoardWritePointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   204 + (4 * b_Channel),&dw_OnBoardNbrOfData);

						dw_OnBoardNbrOfData = APCI3600_PRIVDATA(pdev)->
											  s_PCI3600_BoardInformation.
											  ps_OnBoardRAMReservedBuffer[b_Channel].
											  dw_BufferSize - dw_OnBoardNbrOfData;

						
						/* Complete the descriptor list */
						
						dw_NbrOfDescriptorUsed = 0;
						dw_NbrOfDataToBeTransfered = 0;

						i_Return = i_PCI3600_Intern_PCI9054_CompleteScatterGatherDescriptor (PCI3600_DMA_PC_TO_BOARD,
								   PCI3600_ENABLE,
								   0,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnalogOutInfos[b_Channel].
								   s_AnalogOutPCDMABufferInfos.
								   dw_PhysicalAddress,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnalogOutInfos[b_Channel].
								   s_AnalogOutPCDMABufferInfos.
								   dw_BufferSize,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnalogOutInfos[b_Channel].
								   s_AnalogOutPCDMABufferInfos.
								   dw_ReadPointer,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   s_AnalogOutInfos[b_Channel].
								   s_AnalogOutPCDMABufferInfos.
								   dw_WritePointer,
								   dw_NbrOfData,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_OnBoardRAMReservedBuffer[b_Channel].
								   dw_Address,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_OnBoardRAMReservedBuffer[b_Channel].
								   dw_BufferSize,
								   (dw_OnBoardReadPointer / 4), // In uint32_t 
								   (dw_OnBoardWritePointer / 4), // In uint32_t 
								   (dw_OnBoardNbrOfData / 4), // In uint32_t 
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_DescriptorsInfos[0 + b_Channel].
								   dw_NbrOfDescriptorAllocated,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_DescriptorsInfos[0 + b_Channel].
								   dw_DescriptorListPhysicalAddress,
								   APCI3600_PRIVDATA(pdev)->
								   s_PCI3600_BoardInformation.
								   ps_DescriptorsInfos[0 + b_Channel].
								   ps_PCI9054DMADescriptor,
								   &dw_NbrOfDescriptorUsed,
								   &dw_NbrOfDataToBeTransfered);

						
						/* Test if no Error occur */
						
						if (i_Return == 0) {
PRINTKIF("25");
							
							/* Save the DMA transfer information */
							
							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							ps_DescriptorsInfos[b_Channel].
							dw_NbrOfDescriptorUsed = dw_NbrOfDescriptorUsed;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							b_RessourceID = b_Channel;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							dw_NbrOfByteTransfered = (dw_NbrOfDataToBeTransfered * 4);

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							b_Mode = 0;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											   b_NbrDMATranfer].
							b_ProcessIndex = APCI3600_PRIVDATA(pdev)->
											 s_PCI3600_BoardInformation.
											 s_AnalogOutInfos[b_Channel].
											 b_ChannelSignalGeneratorStartProcessIndex;

							APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
							b_NbrDMATranfer = APCI3600_PRIVDATA(pdev)->
											  s_PCI3600_BoardInformation.
											  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											  b_NbrDMATranfer + 1;

						}
					} else {
PRINTKIF("26");
						
						/* Set the parameters for the user interrupt routine */
						
						dw_InterruptSource = b_Channel + 1;

						dw_InterruptMask = 8;

						dw_NbrOfComputerBuffer = 0;

						pdw_ComputerBufferAddressKernelLevel[0] = 0;
						pdw_ComputerBufferAddressApplicLevel[0] = 0;

						
						/* User interrupt routine Management */
						
						v_PCI3600_Intern_UserInterruptManagement (pdev,
								dw_InterruptSource,
								dw_InterruptMask,
								dw_NbrOfComputerBuffer,
								pdw_ComputerBufferAddressKernelLevel,
								pdw_ComputerBufferAddressApplicLevel);

						/*$/$/ CG 24/02/2005 : Reset the start bit*/
						
						/* Reset the start bit                    */
						
						
						/* Read the start register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,&dw_ReadValue);

						
						/* write the start register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,dw_ReadValue & (0xFFFFFFFFUL - (1 << (b_Channel + 8))));

						
						/* Deactivate the module */
						
						
						/* Read the enable register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,&dw_ReadValue);

						
						/* write the enable register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,dw_ReadValue & (0xFFFFFFFFUL - (1 << (8 + b_Channel)) - (1 << (18 + b_Channel))));

						/*$/$/ CG 24/02/2005 : Release the interrupt*/
						
						/* Release the Interrupt Flag               */
						
						
						/* Release the interrupt */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << (8 + b_Channel)));

					}
				}
			}
			
			/* Test if an ADC Auto-Stop Interrupt */
			
			for (b_Module = 0; b_Module < 4; b_Module++) {
				if (((dw_InterruptStatus >> 10) & (1 << b_Module))!= 0) {
PRINTKIF("27: ADC Auto-Stop Interrupt");
					
					/* Test if the PC Buffer is not full */
					
					if (b_AnaInpChronoPCBuffer_TempFull == 0) {
PRINTKIF("28: PC Buffer is not full");
						
						/* Determine the number of data in the PC RAM buffer */
						
						if (APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnaInpChronomPCDMABufferInfos.
								dw_ReadPointer > dw_AnaInpChronoPCBuffer_TempWritePointer  ) {
PRINTKIF("29");
							dw_NbrOfData = ((APCI3600_PRIVDATA(pdev)->
											 s_PCI3600_BoardInformation.
											 s_AnaInpChronomPCDMABufferInfos.
											 dw_BufferSize / 4) - APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer) + dw_AnaInpChronoPCBuffer_TempWritePointer;

						} else {
PRINTKIF("30");
							dw_NbrOfData = dw_AnaInpChronoPCBuffer_TempWritePointer - APCI3600_PRIVDATA(pdev)->
										   s_PCI3600_BoardInformation.
										   s_AnaInpChronomPCDMABufferInfos.
										   dw_ReadPointer;

						}
						
						/* Read On board information */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   132 + (4 * b_Module),&dw_OnBoardReadPointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   92 + (4 * b_Module),&dw_OnBoardWritePointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   172 + (4 * b_Module),&dw_OnBoardNbrOfData);

						
						/* The software calculate the number of value in the on board RAM */
						
						if (dw_OnBoardReadPointer > dw_OnBoardWritePointer  ) {
							dw_OnBoardNbrOfData = (APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   ps_OnBoardRAMReservedBuffer [(b_Module + 6)].
												   dw_BufferSize - dw_OnBoardReadPointer) + dw_OnBoardWritePointer;
PRINTKIF("31");
						} else {
PRINTKIF("32");
							dw_OnBoardNbrOfData = dw_OnBoardWritePointer - dw_OnBoardReadPointer;

						}
						if (dw_OnBoardNbrOfData != 0) {
PRINTKIF("33");
							
							/* Complete the descriptor list */
							
							dw_NbrOfDescriptorUsed = 0;
							dw_NbrOfDataToBeTransfered = 0;

							i_Return = i_PCI3600_Intern_PCI9054_CompleteScatterGatherDescriptor (PCI3600_DMA_BOARD_TO_PC,
									   PCI3600_ENABLE,
									   1,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_AnaInpChronomPCDMABufferInfos.
									   dw_PhysicalAddress,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_AnaInpChronomPCDMABufferInfos.
									   dw_BufferSize,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_AnaInpChronomPCDMABufferInfos.
									   dw_ReadPointer,
									   dw_AnaInpChronoPCBuffer_TempWritePointer,
									   dw_NbrOfData,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_OnBoardRAMReservedBuffer[b_Module + 2].
									   dw_Address,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_OnBoardRAMReservedBuffer[b_Module + 2].
									   dw_BufferSize,
									   (dw_OnBoardReadPointer / 4), // In uint32_t 
									   (dw_OnBoardWritePointer / 4), // In uint32_t 
									   (dw_OnBoardNbrOfData / 4), // In uint32_t 
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_DescriptorsInfos[b_Module + 2].
									   dw_NbrOfDescriptorAllocated,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_DescriptorsInfos[b_Module + 2].
									   dw_DescriptorListPhysicalAddress,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_DescriptorsInfos[b_Module + 2].
									   ps_PCI9054DMADescriptor,
									   &dw_NbrOfDescriptorUsed,
									   &dw_NbrOfDataToBeTransfered);

							
							/* Test if no Error occur */
							
							if (i_Return == 0) {
PRINTKIF("34");
								
								/* Save the DMA transfer information */
								
								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								ps_DescriptorsInfos[b_Module + 2].
								dw_NbrOfDescriptorUsed = dw_NbrOfDescriptorUsed;

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												   b_NbrDMATranfer].
								b_RessourceID = (uint8_t)(b_Module + 2);

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												   b_NbrDMATranfer].
								dw_NbrOfByteTransfered = (dw_NbrOfDataToBeTransfered * 4);

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												   b_NbrDMATranfer].
								b_Mode = 1;

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												   b_NbrDMATranfer].
								b_ProcessIndex = APCI3600_PRIVDATA(pdev)->
												 s_PCI3600_BoardInformation.
												 s_AnalogInModuleInfos[b_Module].
												 b_ModuleCyclicAcquisitionStartProcessIndex;

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								b_NbrDMATranfer = APCI3600_PRIVDATA(pdev)->
												  s_PCI3600_BoardInformation.
												  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												  b_NbrDMATranfer + 1;

								
								/* Update the temp Write Pointer of the PC Buffer */
								
								dw_AnaInpChronoPCBuffer_TempWritePointer = (dw_AnaInpChronoPCBuffer_TempWritePointer +
										dw_NbrOfDataToBeTransfered +
										dw_NbrOfDescriptorUsed) %
										(APCI3600_PRIVDATA(pdev)->
										 s_PCI3600_BoardInformation.
										 s_AnaInpChronomPCDMABufferInfos.
										 dw_BufferSize / 4);

								
								/* Update the Temp Flag of the computer buffer */
								
								
								/* Test if PC Buffer is full */
								
								if (APCI3600_PRIVDATA(pdev)->
										s_PCI3600_BoardInformation.
										s_AnaInpChronomPCDMABufferInfos.
										dw_ReadPointer == dw_AnaInpChronoPCBuffer_TempWritePointer) {
									b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("35");
								} else {
PRINTKIF("36");
									
									/* Test if the last uint32_t of the buffer */
									
									if ((dw_AnaInpChronoPCBuffer_TempWritePointer + 1) == (APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_BufferSize / 4)) {
										dw_AnaInpChronoPCBuffer_TempWritePointer = 0;
PRINTKIF("37");
										
										/* Test if PC Buffer is full */
										
										if ((APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_AnaInpChronomPCDMABufferInfos.
												dw_ReadPointer == dw_AnaInpChronoPCBuffer_TempWritePointer)) {
											b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("38");
										}
									}
									
									/* Test if only 1 uint32_t free in the PC Buffer */
									
									if (((dw_AnaInpChronoPCBuffer_TempWritePointer + 1) % (APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_BufferSize / 4)) == APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer) {
										dw_AnaInpChronoPCBuffer_TempWritePointer = APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_AnaInpChronomPCDMABufferInfos.
												dw_ReadPointer;

										b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("39");
									}
								}
							}
						} else {
PRINTKIF("40");
							
							/* Release the Interrupt Flag */
							
							
							/* Release the interrupt */
							
							OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << (10 + b_Module)));

							
							/* Set the parameters for the user interrupt routine */
							
							dw_InterruptSource =(1 << (b_Module + 2));

							dw_InterruptMask = 0x10;

							dw_NbrOfComputerBuffer = 0;

							pdw_ComputerBufferAddressKernelLevel[0] = 0;
							pdw_ComputerBufferAddressApplicLevel[0] = 0;

							
							/* User interrupt routine Management */
							
							v_PCI3600_Intern_UserInterruptManagement (pdev,
									dw_InterruptSource,
									dw_InterruptMask,
									dw_NbrOfComputerBuffer,
									pdw_ComputerBufferAddressKernelLevel,
									pdw_ComputerBufferAddressApplicLevel);

						}
					} else {
PRINTKIF("41: PC Buffer FULL !!!!!!!");
						
						/* Set the parameters for the user interrupt routine */
						
						dw_InterruptSource =(1 << (b_Module + 2));

						dw_InterruptMask = 8;

						dw_NbrOfComputerBuffer = 0;

						pdw_ComputerBufferAddressKernelLevel[0] = 0;
						pdw_ComputerBufferAddressApplicLevel[0] = 0;

						
						/* User interrupt routine Management */
						
						v_PCI3600_Intern_UserInterruptManagement (pdev,
								dw_InterruptSource,
								dw_InterruptMask,
								dw_NbrOfComputerBuffer,
								pdw_ComputerBufferAddressKernelLevel,
								pdw_ComputerBufferAddressApplicLevel);

						/*$/$/ CG 24/02/2005 : Reset the start bit*/
						
						/* Reset the start bit                    */
						
						
						/* Read the start register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,&dw_ReadValue);

						
						/* write the start register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,dw_ReadValue & (0xFFFFFFFFUL - (1 << (b_Module))));

						
						/* Deactivate the module */
						
						
						/* Read the enable register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,&dw_ReadValue);

						
						/* write the enable register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,dw_ReadValue & (0xFFFFFFFFUL - (1 << b_Module) - (1 << (10 + b_Module))));

						/*$/$/ CG 24/02/2005 : Release the interrupt*/
						
						/* Release the Interrupt Flag               */
						
						
						/* Release the interrupt */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << (b_Module + 10)));

					}
				}
			}
			
			/* Test if an Chronometer Auto-Stop Interrupt */
			
			for (b_Module = 0; b_Module < 4; b_Module ++) {
				if (((dw_InterruptStatus >> 14) & (1 << b_Module))!= 0) {
PRINTKIF("42");
					
					/* Test if the PC Buffer is not full */
					
					if (b_AnaInpChronoPCBuffer_TempFull == 0) {
PRINTKIF("43");
						
						/* Determine the number of data in the PC RAM buffer */
						
						if (APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnaInpChronomPCDMABufferInfos.
								dw_ReadPointer > dw_AnaInpChronoPCBuffer_TempWritePointer  ) {
PRINTKIF("44");
							dw_NbrOfData = ((APCI3600_PRIVDATA(pdev)->
											 s_PCI3600_BoardInformation.
											 s_AnaInpChronomPCDMABufferInfos.
											 dw_BufferSize / 4) - APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer) + dw_AnaInpChronoPCBuffer_TempWritePointer;

						} else {
PRINTKIF("45");
							dw_NbrOfData = dw_AnaInpChronoPCBuffer_TempWritePointer - APCI3600_PRIVDATA(pdev)->
										   s_PCI3600_BoardInformation.
										   s_AnaInpChronomPCDMABufferInfos.
										   dw_ReadPointer;

						}
						
						/* Read On board information */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   148 + (4 * b_Module),&dw_OnBoardReadPointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   108 + (4 * b_Module),&dw_OnBoardWritePointer);

						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
								   188 + (4 * b_Module),&dw_OnBoardNbrOfData);

						
						/* The software calculate the number of value in the on board RAM */
						
						if (dw_OnBoardReadPointer > dw_OnBoardWritePointer  ) {
							dw_OnBoardNbrOfData = (APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   ps_OnBoardRAMReservedBuffer [(b_Module + 6)].
												   dw_BufferSize - dw_OnBoardReadPointer) + dw_OnBoardWritePointer;
PRINTKIF("46");

						} else {
							dw_OnBoardNbrOfData = dw_OnBoardWritePointer - dw_OnBoardReadPointer;
PRINTKIF("47");

						}
						if (dw_OnBoardNbrOfData != 0) {
PRINTKIF("48");
							
							/* Complete the descriptor list */
							
							dw_NbrOfDescriptorUsed = 0;
							dw_NbrOfDataToBeTransfered = 0;

							i_Return = i_PCI3600_Intern_PCI9054_CompleteScatterGatherDescriptor (PCI3600_DMA_BOARD_TO_PC,
									   PCI3600_ENABLE,
									   1,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_AnaInpChronomPCDMABufferInfos.
									   dw_PhysicalAddress,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_AnaInpChronomPCDMABufferInfos.
									   dw_BufferSize,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   s_AnaInpChronomPCDMABufferInfos.
									   dw_ReadPointer,
									   dw_AnaInpChronoPCBuffer_TempWritePointer,
									   dw_NbrOfData,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_OnBoardRAMReservedBuffer[b_Module + 6].
									   dw_Address,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_OnBoardRAMReservedBuffer[b_Module + 6].
									   dw_BufferSize,
									   (dw_OnBoardReadPointer / 4),
									   (dw_OnBoardWritePointer / 4),
									   (dw_OnBoardNbrOfData / 4),
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_DescriptorsInfos[b_Module + 6].
									   dw_NbrOfDescriptorAllocated,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_DescriptorsInfos[b_Module + 6].
									   dw_DescriptorListPhysicalAddress,
									   APCI3600_PRIVDATA(pdev)->
									   s_PCI3600_BoardInformation.
									   ps_DescriptorsInfos[b_Module + 6].
									   ps_PCI9054DMADescriptor,
									   &dw_NbrOfDescriptorUsed,
									   &dw_NbrOfDataToBeTransfered);

							
							/* Test if no Error occur */
							
							if (i_Return == 0) {
PRINTKIF("49");
								
								/* Save the DMA transfer information */
								
								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								ps_DescriptorsInfos[b_Module + 6].
								dw_NbrOfDescriptorUsed = dw_NbrOfDescriptorUsed;

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												   b_NbrDMATranfer].
								b_RessourceID = (uint8_t)(b_Module + 6);

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												   b_NbrDMATranfer].
								dw_NbrOfByteTransfered = (dw_NbrOfDataToBeTransfered * 4);

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												   b_NbrDMATranfer].
								b_Mode = 1;

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								ps_DMATransferInfo[APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												   b_NbrDMATranfer].
								b_ProcessIndex = APCI3600_PRIVDATA(pdev)->
												 s_PCI3600_BoardInformation.
												 s_ChronometerInfos[b_Module].
												 b_ChronometerCyclicAcquisitionStartProcessIndex;

								APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								b_NbrDMATranfer = APCI3600_PRIVDATA(pdev)->
												  s_PCI3600_BoardInformation.
												  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												  b_NbrDMATranfer + 1;

								
								/* Update the temp Write Pointer of the PC Buffer */
								
								dw_AnaInpChronoPCBuffer_TempWritePointer = (dw_AnaInpChronoPCBuffer_TempWritePointer +
										dw_NbrOfDataToBeTransfered +
										dw_NbrOfDescriptorUsed) %
										(APCI3600_PRIVDATA(pdev)->
										 s_PCI3600_BoardInformation.
										 s_AnaInpChronomPCDMABufferInfos.
										 dw_BufferSize / 4);

								
								/* Update the Temp Flag of the computer buffer */
								
								
								/* Test if PC Buffer is full */
								
								if (APCI3600_PRIVDATA(pdev)->
										s_PCI3600_BoardInformation.
										s_AnaInpChronomPCDMABufferInfos.
										dw_ReadPointer == dw_AnaInpChronoPCBuffer_TempWritePointer) {
									b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("50");
								} else {
PRINTKIF("51");
									
									/* Test if the last uint32_t of the buffer */
									
									if ((dw_AnaInpChronoPCBuffer_TempWritePointer + 1) == (APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_BufferSize / 4)) {
										dw_AnaInpChronoPCBuffer_TempWritePointer = 0;
PRINTKIF("52");
										
										/* Test if PC Buffer is full */
										
										if ((APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_AnaInpChronomPCDMABufferInfos.
												dw_ReadPointer == dw_AnaInpChronoPCBuffer_TempWritePointer)) {
											b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("53");
										}
									}
									
									/* Test if only 1 uint32_t free in the PC Buffer */
									
									if (((dw_AnaInpChronoPCBuffer_TempWritePointer + 1) % (APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_BufferSize / 4)) == APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_AnaInpChronomPCDMABufferInfos.
											dw_ReadPointer) {
										dw_AnaInpChronoPCBuffer_TempWritePointer = APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_AnaInpChronomPCDMABufferInfos.
												dw_ReadPointer;

										b_AnaInpChronoPCBuffer_TempFull = 1;
PRINTKIF("54");
									}
								}
							}
						} else {
PRINTKIF("55");
							
							/* Release the Interrupt Flag */
							
							
							/* Release the interrupt */
							
							OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << (14 + b_Module)));

							
							/* Set the parameters for the user interrupt routine */
							
							dw_InterruptSource =(1 << (b_Module + 6));

							dw_InterruptMask = 0x10;

							dw_NbrOfComputerBuffer = 0;

							pdw_ComputerBufferAddressKernelLevel[0] = 0;
							pdw_ComputerBufferAddressApplicLevel[0] = 0;

							
							/* User interrupt routine Management */
							
							v_PCI3600_Intern_UserInterruptManagement (pdev,
									dw_InterruptSource,
									dw_InterruptMask,
									dw_NbrOfComputerBuffer,
									pdw_ComputerBufferAddressKernelLevel,
									pdw_ComputerBufferAddressApplicLevel);

						}
					} else {
PRINTKIF("56");
						
						/* Set the parameters for the user interrupt routine */
						
						dw_InterruptSource =(1 << (b_Module + 6));

						dw_InterruptMask = 8;

						dw_NbrOfComputerBuffer = 0;

						pdw_ComputerBufferAddressKernelLevel[0] = 0;
						pdw_ComputerBufferAddressApplicLevel[0] = 0;

						
						/* User interrupt routine Management */
						
						v_PCI3600_Intern_UserInterruptManagement (pdev,
								dw_InterruptSource,
								dw_InterruptMask,
								dw_NbrOfComputerBuffer,
								pdw_ComputerBufferAddressKernelLevel,
								pdw_ComputerBufferAddressApplicLevel);

						/*$/$/ CG 24/02/2005 : Reset the start bit*/
						
						/* Reset the start bit                    */
						
						
						/* Read the start register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,&dw_ReadValue);

						
						/* write the start register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,4,dw_ReadValue & (0xFFFFFFFFUL - (1 << (b_Module + 4))));

						
						/* Deactivate the module */
						
						
						/* Read the enable register */
						
						INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,&dw_ReadValue);

						
						/* write the enable register */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,0,dw_ReadValue & (0xFFFFFFFFUL - (1 << (4 + b_Module)) - (1 << (14 + b_Module))));

						/*$/$/ CG 24/02/2005 : Release the interrupt*/
						
						/* Release the Interrupt Flag               */
						
						
						/* Release the interrupt */
						
						OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,(1 << (b_Module + 14)));

					}
				}
			}
			
			/* Test if a DMA transfer must be started */
			
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
					b_NbrDMATranfer != 0) {
PRINTKIF("57: a DMA transfer must be started");
				
				/* Chaining the descriptor list */
				
				i_PCI3600_Intern_PCI9054_ChainingScatterGatherDescriptors (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_DMAControllersInfos,
						PCI3600_DMA_CHANNEL_0,
						APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						ps_DescriptorsInfos);

				_3600INT_DPRINTK("Init DMA Transfer Descriptor Physical Address : %X\n",APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   ps_DescriptorsInfos[APCI3600_PRIVDATA(pdev)->
										   s_PCI3600_BoardInformation.
										   s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
										   ps_DMATransferInfo[0].
										   b_RessourceID].
					   dw_DescriptorListPhysicalAddress);

				_3600INT_DPRINTK("dw_BufferPhysicalAddress : %08X dw_LocalBusPhysicalAddress : %08X,\ndw_BufferSize : %08X,dw_NextDescriptorAddress : %08X \n"
				,
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					ps_DescriptorsInfos	[
									APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									ps_DMATransferInfo[0].
									b_RessourceID
								]
					.ps_PCI9054DMADescriptor[0]->
					dw_BufferPhysicalAddress
				,
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					ps_DescriptorsInfos[
									APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									ps_DMATransferInfo[0].
									b_RessourceID
								]
					.ps_PCI9054DMADescriptor[0]->
					dw_LocalBusPhysicalAddress
				,
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					ps_DescriptorsInfos[
									APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									ps_DMATransferInfo[0].
									b_RessourceID
								]
					.ps_PCI9054DMADescriptor[0]->
					dw_BufferSize
				,
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					ps_DescriptorsInfos[
									APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
									ps_DMATransferInfo[0].
									b_RessourceID
								]
					.ps_PCI9054DMADescriptor[0]->
					dw_NextDescriptorAddress
				);
	
	
	
				
				/* Init the DMA transfer */
				
				i_PCI3600_Primary_PCI9054InitDMAScatterGatherTransfer (GET_MEM_BAR0(pdev),
						PCI3600_DMA_CHANNEL_0,
						PCI3600_ENABLE,
						APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						ps_DescriptorsInfos[APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
											ps_DMATransferInfo[0].
											b_RessourceID].
						dw_DescriptorListPhysicalAddress);

				
				/* Start the DMA transfer */
				
				i_PCI3600_Primary_PCI9054StartDMATransfer (GET_MEM_BAR0(pdev),
						PCI3600_DMA_CHANNEL_0);

				
				/* Set the DMA channel as used */
				


				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
				b_InUse = 1;

			} else {
PRINTKIF("58: NO DMA transfer must be started");	
			
				/* Release new compare/Auto-Stop IRQ */
				
				OUTPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,4,0x40000000UL);

			}
			b_InterruptOccur = 1;

		}
	}



	/*----------------------------------------------------------------------------*/
	/*                   ERROR MANAGEMENT                                         */
	/*----------------------------------------------------------------------------*/
	
	/* Test if an error interrupt occur */
	
	if ((dw_InterruptStatus & 0xFFC0000UL)!= 0 )
	{
PRINTKIF("59");
		
		/* Manage the Error interrupt */
		
		
		/* Read the FIFO interrupt status */
		
		INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,8,&dw_FIFOErrorStatus);

		
		/* Test if DAC FIFO Error */
		
		if ((dw_InterruptStatus >> 26) & 3) {
PRINTKIF("60");
			
			/* Set the parameters for the user interrupt routine */
			
			dw_InterruptSource = (dw_InterruptStatus >> 26) & 3;

			
			/* Test if FIFO Error */
			
			if ((dw_FIFOErrorStatus >> 28) & 3) {
				dw_InterruptMask = 2;
PRINTKIF("61");
			}
			
			/* Test if SDRAM Error */
			
			if ((((dw_FIFOErrorStatus >> 16) & 0x3) == 3) ||
					(((dw_FIFOErrorStatus >> 16) & 0xC) == 0xC)) {
				dw_InterruptMask = dw_InterruptMask | 4;
PRINTKIF("62");
			}
			dw_NbrOfComputerBuffer = 0;

			pdw_ComputerBufferAddressKernelLevel[0] = 0;
			pdw_ComputerBufferAddressApplicLevel[0] = 0;

			
			/* User interrupt routine Management */
			
			v_PCI3600_Intern_UserInterruptManagement (pdev,
					dw_InterruptSource,
					dw_InterruptMask,
					dw_NbrOfComputerBuffer,
					pdw_ComputerBufferAddressKernelLevel,
					pdw_ComputerBufferAddressApplicLevel);

		}
		
		/* Test if ADC FIFO Error */
		
		if ((dw_InterruptStatus >> 18) & 0xF) {
			
			/* Set the parameters for the user interrupt routine */
			
			dw_InterruptSource = ((dw_InterruptStatus >> 18) & 0xF) << 2;
PRINTKIF("63");
			
			/* Test if FIFO Error */
			
			if ((dw_FIFOErrorStatus >> 20) & 0xF) {
				dw_InterruptMask = 2;
PRINTKIF("64");
			}
			
			/* Test if SDRAM Error */
			
			if (((dw_FIFOErrorStatus & 0x3) == 3) ||
					((dw_FIFOErrorStatus & 0xC) == 0xC) ||
					((dw_FIFOErrorStatus & 0x30) == 0x30) ||
					((dw_FIFOErrorStatus & 0xC0) == 0xC0)) {
				dw_InterruptMask = dw_InterruptMask | 4;
PRINTKIF("65");
			}
			dw_NbrOfComputerBuffer = 0;

			pdw_ComputerBufferAddressKernelLevel[0] = 0;
			pdw_ComputerBufferAddressApplicLevel[0] = 0;

			
			/* User interrupt routine Management */
			
			v_PCI3600_Intern_UserInterruptManagement (pdev,
					dw_InterruptSource,
					dw_InterruptMask,
					dw_NbrOfComputerBuffer,
					pdw_ComputerBufferAddressKernelLevel,
					pdw_ComputerBufferAddressApplicLevel);

		}
		
		/* Test if Chronometer FIFO Error */
		
		if ((dw_InterruptStatus >> 22) & 0xF) {
			
			/* Set the parameters for the user interrupt routine */
			
			dw_InterruptSource = ((dw_InterruptStatus >> 22) & 0xF) << 6;
PRINTKIF("66");
			
			/* Test if FIFO Error */
			
			if ((dw_FIFOErrorStatus >> 24) & 0xF) {
				dw_InterruptMask = 2;
PRINTKIF("67");
			}
			
			/* Test if SDRAM Error */
			
			if ((((dw_FIFOErrorStatus >> 8) & 0x3) == 3) ||
					(((dw_FIFOErrorStatus >> 8) & 0xC) == 0xC) ||
					(((dw_FIFOErrorStatus >> 8) & 0x30) == 0x30) ||
					(((dw_FIFOErrorStatus >> 8) & 0xC0) == 0xC0)) {
				dw_InterruptMask = dw_InterruptMask | 4;

			}
			dw_NbrOfComputerBuffer = 0;

			pdw_ComputerBufferAddressKernelLevel[0] = 0;
			pdw_ComputerBufferAddressApplicLevel[0] = 0;

			
			/* User interrupt routine Management */
			
			v_PCI3600_Intern_UserInterruptManagement (pdev,
					dw_InterruptSource,
					dw_InterruptMask,
					dw_NbrOfComputerBuffer,
					pdw_ComputerBufferAddressKernelLevel,
					pdw_ComputerBufferAddressApplicLevel);

		}
		b_InterruptOccur = 1;

	}




	return (b_InterruptOccur);
}






/*i_PCI3600_SetBoardIntRoutine*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_SetBoardIntRoutine ()                            |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : This function cannot be call in kernel level                    */
/*         -3 : Wrong calling mode                                              */
/*         -4 : Not any memory free for the user globale buffer                 */
/*         -5 : The interrupt management is not supported by this compiler      */
/*         -6 : User interrupt routine calling mode selection wrong             */
/*         -7 : Interrupt already installed                                     */
/*         -8 : Interrupt not attribuate                                        */
/*         -9 : ACPI activ but Windows NT 4 used                                */
/*        -10 : PNP OS activ but Windows NT 4 used                              */
/*        -11 : Create user shared memory Error                                 */
/*        -12 : Prepare user function to kernel execution error                 */
/*        -13 : Create API interrupt event error                                */
/*        -14 : Create API interrupt thread function error                      */
/*        -15 : Create call back API function error                             */
/*        -16 : Install API interrupt function error                            */
/*        -17 : Create Interrupt Parameter shared memory error                  */
/*        -18 : Critical section preparation error                              */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_SetBoardIntKernelRoutine (struct pci_dev *pdev,
		v_PCI3600_UserInterruptHandler v_UserInterruptHandler)
{
	int   i_ReturnValue     = 0;


	if (!pdev)
		return -1;


	
	/* Test if user function not installed */
	
	if (APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			s_InterruptInformations.
			b_UserInterruptHandlerInstalled == 0)
	{
		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_InterruptInformations.
		v_UserInterrupt = v_UserInterruptHandler;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_InterruptInformations.
		b_UserInterruptHandlerInstalled = 1;

	} else
	{
		
		/* -7 : Interrupt already installed */
		
		i_ReturnValue = -7;
	}
	return (i_ReturnValue);

}
/*i_PCI3600_ResetBoardIntRoutine*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_ResetBoardIntRoutine ()                          |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : This function cannot be call in kernel level                    */
/*         -3 : Interrupt Routine not installed                                 */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_ResetBoardIntKernelRoutine (struct pci_dev *pdev)
{
	int   i_ReturnValue     = 0;

	if (!pdev)
		return -1;
	
	/* Test if user function installed */
	
	if (APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			s_InterruptInformations.
			b_UserInterruptHandlerInstalled == 1)
	{
		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_InterruptInformations.
		v_UserInterrupt = NULL;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_InterruptInformations.
		b_UserInterruptHandlerInstalled = 0;

	} else
	{
		
		/* -3 : Interrupt Routine not installed */
		
		i_ReturnValue = -3;
	}
	return (i_ReturnValue);

}

