-
Patrick Robbe authoredPatrick Robbe authored
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