#include "apci1032-private.h"
#include <apci1032-kapi.h>

#include <asm/uaccess.h>

/** @par LICENCE
* @verbatim
Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
        
        ADDI-DATA GmbH 
        Dieselstrasse 3 
        D-77833 Ottersweier 
        Tel: +19(0)7223/9493-0 
        Fax: +49(0)7223/9493-92 
        http://www.addi-data-com 
        info@addi-data.com 
        
This program is free software; you can redistribute it and/or modify it under 
the terms of the GNU General Public License as published by the Free Software 
Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with 
this program; if not, write to the Free Software Foundation, 
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

You shoud also find the complete GPL in the COPYING file 
accompanying this source code.

* @endverbatim
*/

EXPORT_NO_SYMBOLS;
//------------------------------------------------------------------------------
/** open() function of the module for the APCI-1032, with lookup though global OS PCI list 
* this is for files unmanaged by the driver itself and use the minor device number to identify the board.
*
* When opening, the pci_dev associated to the minor number is looked up
* and associated with the file structure. It avoid further lookup when calling ioctl()
* 
*
*/
int apci1032_open_lookup (struct inode *inode, struct file *filp)
{
   if ( apci1032_INDEX_NOT_VALID(&apci1032_count, MINOR(inode->i_rdev) ) )
   {
   	return -ENODEV;
   }
      
   filp->private_data = apci1032_lookup_board_by_index(MINOR(inode->i_rdev) );  
   
   MOD_INC_USE_COUNT;
   return 0;   
}
//------------------------------------------------------------------------------
/** release() function of the module for the APCI-1032, with lookup though global OS PCI list 
* this is for files unmanaged by the driver itself and use the minor device number to identify the board
*/
int apci1032_release_lookup (struct inode *inode,struct file *filp)
{

   if ( apci1032_INDEX_NOT_VALID(&apci1032_count, MINOR(inode->i_rdev) ) )
   {
   	return -ENODEV;
   }

   MOD_DEC_USE_COUNT;
   return 0;
}
//------------------------------------------------------------------------------
/** ioctl() function of the module for the APCI-1032, with lookup though global OS PCI list 
* this is for files unmanaged by the driver itself and use the minor device number to identify the board
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
int apci1032_ioctl_lookup(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
#else
long apci1032_ioctl_lookup(struct file *filp, unsigned int cmd, unsigned long arg)
#endif
{

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0)
        struct inode *inode = filp->f_path.dentry->d_inode;
    #else
        struct inode *inode = filp->f_dentry->d_inode;
    #endif
#endif

   if (apci1032_INDEX_NOT_VALID(&apci1032_count, MINOR(inode->i_rdev)))
   {
   	return -ENODEV;
   }  
     
   if (!filp->private_data) // private data is initialised to NULL
   {
   	printk(KERN_CRIT "%s: %s: board data should be affected but is not (did you call open() before ioctl() ?) \n",__DRIVER_NAME, __FUNCTION__);
	return -EBADFD;
   }

   return apci1032_do_ioctl( (struct pci_dev*) filp->private_data, cmd,arg);     
}
