#include <linux/config.h>
#define MODULE
#include <linux/module.h>

#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif 

#include <asm/uaccess.h>
/* Necessary includes */
#include <linux/fs.h>
#include <linux/init.h>

static int sMajorNumber;          /* Major number of the tracer */
static int sOpenCount;            /* record the count of open */
int     tracer_open(struct inode*, struct file*);
int     tracer_release(struct inode*, struct file*);
static struct file_operations sTracerFileOps =
{
  owner:         THIS_MODULE,
  open:             tracer_open,
  release:          tracer_release,  
};

#define TRACER_NAME "tracer"
/*************************************************************
 * Function : tracer_open()
 * Description : "Open" file op
 * Parameters : 
 *     pmInode, the inode associated with the device
 *     pmFile, file structure given to the acting process
 * Return values :
 *     0, everything went OK
 *     -ENODEV, no such device.
 *     -EBUSY, the tracer is already in use.
 ************************************************************/
int tracer_open(struct inode* pmInode,
		struct file*  pmFile)
{
  int lDevMinor = MINOR(pmInode->i_dev) & 0xf;  /* Device minor number */

  /* Don't allow more than one device of this type */
  if(lDevMinor > 0)
    return -ENODEV;

  /* Don't allow the device to be open more than once */
  if(sOpenCount)
    return -EBUSY;

  /* DEBUG */
  printk("<1> Open correctly\n");


  /* Lock the device */
  sOpenCount++;

#ifdef MODULE
  /* Increment module usage */
  MOD_INC_USE_COUNT;
#endif
  /* Everything is OK */
  return 0;
}


int tracer_release(struct inode* pmInode,  struct file*  pmFile)
{
	printk("<5> release the driver\n");
  	/* Unlock the device */
  	sOpenCount--;

#ifdef MODULE
  	/* Decrement module usage */
  	MOD_DEC_USE_COUNT;
#endif

  	/* Tell the caller that everything is OK */
  	return 0;
}

#ifdef MODULE
/**************************************************************
 * Function : cleanup_module()
 * Description : Cleanup of the tracer.
 * Parameters : NONE
 * Return values : NONE
 * Note : The order of the unregesterings is important. First,
 *        rule out any possibility of getting more trace 
 *        data. Second, rule out any possibility of being read
 *        by the tracing daemon. Last, free the tracing
 *        buffer.
 **************************************************************/
 void tracer_exit(void)
{
  unregister_chrdev(sMajorNumber, TRACER_NAME);

  return;
}
module_exit(tracer_exit);
#endif

/**************************************************************
 * Function : tracer_init()
 * Description : Tracer initialization function.
 * Parameters :
 *     NONE
 * Return values : 
 *    0, everything went OK
 *    -ENOMEM, unable to get a hold of memory for tracer
 **************************************************************/
int __init tracer_init(void)
{
  int  lError = 0; /* Error, if any */
  /* Initialize open count */
  sOpenCount = 0;
  
  // reffun();

  /* Register the tracer as a char device */ 
  /* sMajorNumber = register_chrdev(0, TRACER_NAME, &sTracerFileOps); */
  sMajorNumber = 100;
  register_chrdev(sMajorNumber, TRACER_NAME, &sTracerFileOps); 

  /* Let the user know about it */
  printk("<1>Tracer: Initialization complete \n");
  /* Return error code */
  return lError;
}
module_init(tracer_init);








