Skip to content
Snippets Groups Projects
ecs.h 2.85 KiB
#ifndef __PCIE40_DRIVER_ECS_H
#define __PCIE40_DRIVER_ECS_H
//p40driver``+

#include "common.h"
#include <linux/fs.h>

#define P40_ECS_CDEV_BASEMINOR (0)
#define P40_ECS_CDEV_COUNT (2)

#define P40_ECS_BARS_MASK ((1<<0)|(1<<2)) //BAR0, BAR2

//ug`pcie40_driver.files`bar0 _ /dev/pcie40_?_bar0::
// Device to access user registers on the FPGA.
#define BAR0_CDEV_MINOR (P40_ECS_CDEV_BASEMINOR + 0)
static const char BAR0_CDEV_NAME[] = "bar0";

//ug`pcie40_driver.files`bar2 _ /dev/pcie40_?_bar2::
// Device to access low-level registers on the FPGA.
#define BAR2_CDEV_MINOR (P40_ECS_CDEV_BASEMINOR + 1)
static const char BAR2_CDEV_NAME[] = "bar2";

//+`pcie40_ecs_state`
struct pcie40_ecs_state {
  struct pcie40_state *common;

  dev_t dev_num; //base MAJOR/MINOR numbers for device files
  struct cdev bar0_cdev;
  struct cdev bar2_cdev;
};

//+`ecs_open`
static int ecs_open(struct inode *inode, struct file *filp)//;?>
{
  struct pcie40_ecs_state *state = NULL;
  switch (iminor(inode)) {
    case BAR0_CDEV_MINOR:
      printk(P40_INFO "BAR0", P40_PARM);
      state = container_of(inode->i_cdev, struct pcie40_ecs_state, bar0_cdev);
      break;
    case BAR2_CDEV_MINOR:
      printk(P40_INFO "BAR2", P40_PARM);
      state = container_of(inode->i_cdev, struct pcie40_ecs_state, bar2_cdev);
      break;
    default:
      printk(P40_INFO "invalid BAR", P40_PARM);
      return -EINVAL;
  }
  filp->private_data = state;

  return 0;
}

//+`ecs_release`
static int ecs_release(struct inode *inode, struct file *filp)//;?>
{
  struct pcie40_ecs_state *state = NULL;
  switch (iminor(inode)) {
    case BAR0_CDEV_MINOR:
      printk(P40_INFO "BAR0", P40_PARM);
      state = container_of(inode->i_cdev, struct pcie40_ecs_state, bar0_cdev);
      break;
    case BAR2_CDEV_MINOR:
      printk(P40_INFO "BAR2", P40_PARM);
      state = container_of(inode->i_cdev, struct pcie40_ecs_state, bar2_cdev);
      break;
    default:
      printk(P40_INFO "invalid BAR", P40_PARM);
      return -EINVAL;
  }
  if (filp->private_data != state) {
    printk(P40_ERR "inconsistent private_data\n", P40_PARM);
    return -EINVAL;
  }
  filp->private_data = NULL;

  return 0;
}

static struct class *pcie40_ecs_class = NULL;

//+`pcie40_ecs_init` Register ECS device class.
int pcie40_ecs_init(void)//;?>
{
  int rc = 0;

  //? This functions registers a dedicated device class used to create ECS device files.
  pcie40_ecs_class = class_create(THIS_MODULE, PCIE40_ECS_CLASS);
  if (IS_ERR(pcie40_ecs_class)) {
    rc = PTR_ERR(pcie40_ecs_class);
    printk(P40_WARN "failed to register class, %d\n", P40_PARM, rc);
    goto err_class_create;
  }
  //pcie40_ecs_class->dev_uevent = pcie40_dev_uevent;
  pcie40_ecs_class->devnode = pcie40_devnode;

err_class_create:
  return rc;
}

//+`pcie40_ecs_exit` Destroy ECS device class.
void pcie40_ecs_exit(void)//;?>
{
  class_destroy(pcie40_ecs_class);
}

#endif//__PCIE40_DRIVER_ECS_H