#ifndef __APCI2032_KAPI_H__
#define __APCI2032_KAPI_H__

#ifndef __KERNEL__
#error This header is intended for use in kernel context only
#endif

#ifdef __KERNEL__

#include <linux/pci.h>

/** find a apci 2032 device of a given index in the system PCI device list.
 * @param index The index (minor number) to lookup
 * @return A pointer to the device or NULL
 *
 * This function is used to map a minor number to an actual device.
 */
static __inline__  struct pci_dev * apci2032_lookup_board_by_index(unsigned int index)
{
	struct pci_dev * dev = NULL;	
	int i = 0;
	
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)		
	while ( (dev = pci_find_device(APCI2032_BOARD_VENDOR_ID,APCI2032_BOARD_DEVICE_ID,dev)) )
#else
	while ( (dev = pci_get_device(APCI2032_BOARD_VENDOR_ID,APCI2032_BOARD_DEVICE_ID,dev)) )
#endif
	{
		if (i == index) return dev;
		i++;
	}      

	return NULL;

}

//----------------------------------------------------------------------------
/** return a pointer to the lock protecting the board */
extern spinlock_t * apci2032_get_lock(struct pci_dev *pdev);
//----------------------------------------------------------------------------
/** lock the board using spin_lock_irqsave(), disabling local software and hardware interrupts
 * @param[in] pdev The device to acquire.
 * @param[out] flags interuption flag used with unlock() 
 *
 * This function is to be used before calling any kAPI function; BUT not in user interrupt handler where the board is already acquired.
 *  
 * @warning lock aren't reentrant, that means that you can not nest call to lock() 
 *  
 */
static inline void apci2032_lock(struct pci_dev *pdev, unsigned long * flags)
{
        spin_lock_irqsave(apci2032_get_lock(pdev), *flags);
}

//----------------------------------------------------------------------------
/** unlock the board using spin_lock_irqrestore()
 * @param[in] pdev The device to acquire.
 * @param[out] flags interuption flag initialised by lock() 
 *
 * This function is to be used before calling any kAPI function; BUT not in user interrupt handler where the board is already acquired.
 * 
 *  
 *  
 */
static inline void apci2032_unlock(struct pci_dev *pdev, unsigned long flags)
{
        spin_unlock_irqrestore(apci2032_get_lock(pdev), flags);
}


#endif // __KERNEL__


#endif // __APCI2032_KAPI_H__
