Commit fad012d4 authored by Jaco Hofmann's avatar Jaco Hofmann Committed by Jens Korinth
Browse files

Closes #90 - Implement INTC-less MSI-X architecture

* removed all interrupt controllers for VC709
* replaced by 132 MSI-X interrupts (128 PE, 4 other)
* replaced driver code
parent f31e734b
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file dual_dma_ctrl.c
* @file dual_dma_ctrl.c
* @brief Implementation of custom dma engine specific code
Strips the layout of the dma-registers and setup stuff to start a dma transfer
in addition calls to acknowledge the interrupt in hw is given
......@@ -70,7 +70,7 @@ void blue_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle,
fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr);
//if(mutex_lock_interruptible(&dma_regs_mutex))
// fflink_warn("got killed while aquiring the mutex\n");
/* SA */
pcie_writel((unsigned long)device_buffer, device_base_addr + REG_FPGA_ADDR);
/* DA */
......@@ -81,7 +81,7 @@ void blue_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle,
wmb();
/* start cmd */
pcie_writel(CMD_READ, device_base_addr + REG_CMD);
//mutex_unlock(&dma_regs_mutex);
}
......@@ -98,7 +98,7 @@ void blue_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, i
fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr);
//if(mutex_lock_interruptible(&dma_regs_mutex))
// fflink_warn("got killed while aquiring the mutex\n");
/* SA */
pcie_writel(host_handle, device_base_addr + REG_HOST_ADDR);
/* DA */
......@@ -109,7 +109,7 @@ void blue_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, i
wmb();
/* start cmd */
pcie_writel(CMD_WRITE, device_base_addr + REG_CMD);
//mutex_unlock(&dma_regs_mutex);
}
......
......@@ -18,12 +18,12 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file char_device_dma.c
* @file char_device_dma.c
* @brief Implementation of char device system calls of the dma engine
this is the entry point for user-space software (platform_api) to start dma_transfers on the pcie_bus
the device allocates memory for buffering and mmap and allows to choose between bounce and double buffering
these methods are implemented in a blocking manner, thus the calling process is put into sleep-state until transfer has finished
in addition zero-copy is implemented with a mmapped buffer
in addition zero-copy is implemented with a mmapped buffer
* */
/******************************************************************************/
......@@ -47,7 +47,7 @@ static struct file_operations dma_fops = {
static struct priv_data_struct priv_data;
/* char device structure basically for dev_t and fops */
static struct cdev char_dma_cdev;
static struct cdev char_dma_cdev;
/* char device number for f3_char_driver major and minor number */
static dev_t char_dma_dev_t;
/* device class entry for sysfs */
......@@ -71,13 +71,13 @@ static void transmit_to_user(void * user_buffer, void * kvirt_buffer, dma_addr_t
{
int copy_count;
fflink_info("user_buf %lX kvirt_buf %lX \nsize %d dma_handle %lX\n", (unsigned long) user_buffer, (unsigned long) kvirt_buffer, btt, (unsigned long) dma_handle);
dma_sync_single_for_cpu(&get_pcie_dev()->dev, dma_handle, dma_cache_fit(btt), PCI_DMA_FROMDEVICE);
copy_count = copy_to_user(user_buffer, kvirt_buffer, btt);
if(copy_count)
fflink_warn("left copy %u bytes - cache flush %u bytes\n", copy_count, dma_cache_fit(btt));
dma_sync_single_for_device(&get_pcie_dev()->dev, dma_handle, dma_cache_fit(btt), PCI_DMA_FROMDEVICE);
}
......@@ -93,13 +93,13 @@ static void transmit_from_user(void * user_buffer, void * kvirt_buffer, dma_addr
{
int copy_count;
fflink_info("user_buf %lX kvirt_buf %lX \nsize %d dma_handle %lX\n", (unsigned long) user_buffer, (unsigned long) kvirt_buffer, dma_cache_fit(btt), (unsigned long) dma_handle);
dma_sync_single_for_cpu(&get_pcie_dev()->dev, dma_handle, dma_cache_fit(btt), PCI_DMA_TODEVICE);
// copy data from user
copy_count = copy_from_user(kvirt_buffer, user_buffer, btt);
if(copy_count)
fflink_warn("left copy %u bytes - cache flush %u bytes\n", copy_count, dma_cache_fit(btt));
dma_sync_single_for_device(&get_pcie_dev()->dev, dma_handle, dma_cache_fit(btt), PCI_DMA_TODEVICE);
}
......@@ -141,7 +141,7 @@ static int dma_alloc_pbufs(void** p, dma_addr_t *handle, gfp_t zone, int directi
fflink_warn("Couldn't retrieve enough memory\n");
err = -EFAULT;
}
return err;
}
......@@ -168,7 +168,7 @@ static void dma_free_pbufs(void *p, dma_addr_t handle, int direction)
* @param node Minor number
* @return none
* */
static void dma_init_pdata(struct priv_data_struct * p)
static void dma_init_pdata(struct priv_data_struct * p)
{
/* cache size and mask needed for alignemt */
p->cache_lsize = cache_line_size();
......@@ -179,14 +179,14 @@ static void dma_init_pdata(struct priv_data_struct * p)
p->kvirt_h2l = 0;
p->kvirt_l2h = 0;
p->ctrl_base_addr = (void *) AXI_CTRL_BASE_ADDR;
/* init control structures for synchron sys-calls */
mutex_init(&p->rw_mutex);
init_waitqueue_head(&p->rw_wait_queue);
p->condition_rw = false;
p->mem_addr_h2l = (void *) RAM_BASE_ADDR_0;
p->mem_addr_l2h = (void *) RAM_BASE_ADDR_0;
p->device_base_addr = (void *) DMA_BASE_ADDR_0;
......@@ -216,18 +216,18 @@ static inline int read_device(int count, char __user *buf, void * mem_addr, stru
* @return Zero, if transfer was successful, error code otherwise
* */
static int read_with_bounce(int count, char __user *buf, void * mem_addr, struct priv_data_struct *p)
{
{
int current_count = count;
unsigned int copy_size;
fflink_notice("Using bounce buffering\n");
while(current_count > 0) {
fflink_info("outstanding %d bytes - \n\t\t user addr %lX - mem addr %lx\n", current_count, (unsigned long) buf, (unsigned long) mem_addr);
if(current_count <= BUFFER_SIZE)
copy_size = current_count;
else
copy_size = BUFFER_SIZE;
transmit_from_device(mem_addr, p->dma_handle_l2h, copy_size, p->device_base_addr);
if(wait_event_interruptible(p->rw_wait_queue, p->condition_rw == true)) {
fflink_warn("got killed while hanging in waiting queue\n");
......@@ -235,7 +235,7 @@ static int read_with_bounce(int count, char __user *buf, void * mem_addr, struct
}
p->condition_rw = false;
transmit_to_user(buf, p->kvirt_l2h, p->dma_handle_l2h, copy_size);
buf += BUFFER_SIZE;
mem_addr += BUFFER_SIZE;
current_count -= BUFFER_SIZE;
......@@ -270,7 +270,7 @@ static int write_with_bounce(int count, const char __user *buf, void * mem_addr,
{
int current_count = count;
fflink_notice("Using bounce buffering\n");
while(current_count > 0) {
fflink_info("outstanding %d bytes - \n\t\t user addr %lX - mem addr %lx\n", current_count, (unsigned long) buf, (unsigned long) mem_addr);
if(current_count <= BUFFER_SIZE) {
......@@ -283,13 +283,13 @@ static int write_with_bounce(int count, const char __user *buf, void * mem_addr,
buf += BUFFER_SIZE;
mem_addr += BUFFER_SIZE;
current_count -= BUFFER_SIZE;
if(wait_event_interruptible(p->rw_wait_queue, p->condition_rw == true)) {
fflink_warn("got killed while hanging in waiting queue\n");
return -EACCES;
}
p->condition_rw = false;
}
}
return 0;
}
......@@ -298,7 +298,7 @@ static int dma_initialize(void) {
gfp_t zone = GFP_DMA32;
fflink_notice("Initializing private data");
dma_init_pdata(&priv_data);
dma_set_mask_and_coherent(&get_pcie_dev()->dev, DMA_BIT_MASK(DMA_MAX_BIT));
......@@ -315,7 +315,7 @@ static int dma_initialize(void) {
err_1 = dma_alloc_pbufs(&priv_data.kvirt_h2l, &priv_data.dma_handle_h2l, zone, PCI_DMA_TODEVICE);
err_2 = dma_alloc_pbufs(&priv_data.kvirt_l2h, &priv_data.dma_handle_l2h, zone, PCI_DMA_FROMDEVICE);
if(err_1 != 0 || err_2 != 0) {
fflink_warn("Error during device creation. Error codes: Write direction: %d Read direction: %d\n", err_1, err_2);
err_return = -ENOSPC;
......@@ -333,7 +333,7 @@ open_failed:
static void dma_deinit(void) {
fflink_notice("Device not used anymore, removing it.\n");
dma_free_pbufs(priv_data.kvirt_h2l, priv_data.dma_handle_h2l, PCI_DMA_TODEVICE);
dma_free_pbufs(priv_data.kvirt_l2h, priv_data.dma_handle_l2h, PCI_DMA_FROMDEVICE);
}
......@@ -394,15 +394,15 @@ static ssize_t dma_read(struct file *filp, char __user *buf, size_t count, loff_
int err = 0;
struct priv_data_struct * p = (struct priv_data_struct *) filp->private_data;
fflink_notice("Called for device minor %d\n", 0);
if(mutex_lock_interruptible(&p->rw_mutex)) {
fflink_warn("got killed while aquiring the mutex\n");
return -EACCES;
}
err = read_device(count, buf, p->mem_addr_l2h, p);
mutex_unlock(&p->rw_mutex);
return err;
}
......@@ -420,15 +420,15 @@ static ssize_t dma_write(struct file *filp, const char __user *buf, size_t count
int err = 0;
struct priv_data_struct * p = (struct priv_data_struct *) filp->private_data;
fflink_notice("Called for device minor %d\n", 0);
if(mutex_lock_interruptible(&p->rw_mutex)) {
fflink_warn("got killed while aquiring the mutex\n");
return -EACCES;
}
err = write_device(count, buf, p->mem_addr_h2l, p);
mutex_unlock(&p->rw_mutex);
return err;
}
......@@ -447,7 +447,7 @@ static long dma_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long i
struct priv_data_struct * p = (struct priv_data_struct *) filp->private_data;
struct dma_ioctl_params params;
fflink_notice("Called with number %X for minor %u\n", ioctl_num, 0);
if(_IOC_SIZE(ioctl_num) != sizeof(struct dma_ioctl_params)) {
fflink_warn("Wrong size to read out registers %d vs %ld\n", _IOC_SIZE(ioctl_num), sizeof(struct dma_ioctl_params));
return -EACCES;
......@@ -460,26 +460,26 @@ static long dma_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long i
fflink_warn("got killed while aquiring the mutex\n");
return -EACCES;
}
switch(ioctl_num) {
case IOCTL_CMD_DMA_READ_MMAP:
fflink_info("IOCTL_CMD_DMA_READ_MMAP with Param-Size: %d byte\n", _IOC_SIZE(ioctl_num));
fflink_info("Btt: %d\n", params.btt);
dma_sync_single_for_device(&get_pcie_dev()->dev, p->dma_handle_l2h, dma_cache_fit(params.btt), PCI_DMA_TODEVICE);
transmit_from_device(p->mem_addr_l2h, p->dma_handle_l2h, params.btt, p->device_base_addr);
if(wait_event_interruptible(p->rw_wait_queue, p->condition_rw == true)) {
fflink_warn("got killed while hanging in waiting queue\n");
break;
}
p->condition_rw = false;
p->condition_rw = false;
dma_sync_single_for_cpu(&get_pcie_dev()->dev, p->dma_handle_l2h, dma_cache_fit(params.btt), PCI_DMA_TODEVICE);
break;
case IOCTL_CMD_DMA_WRITE_MMAP:
fflink_info("IOCTL_CMD_DMA_WRITE_MMAP with Param-Size: %d byte\n", _IOC_SIZE(ioctl_num));
fflink_info("Btt: %d\n", params.btt);
dma_sync_single_for_device(&get_pcie_dev()->dev, p->dma_handle_h2l, dma_cache_fit(params.btt), PCI_DMA_TODEVICE);
transmit_to_device(p->mem_addr_h2l, p->dma_handle_h2l, params.btt, p->device_base_addr);
if(wait_event_interruptible(p->rw_wait_queue, p->condition_rw == true)) {
......@@ -487,38 +487,38 @@ static long dma_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long i
break;
}
p->condition_rw = false;
dma_sync_single_for_cpu(&get_pcie_dev()->dev, p->dma_handle_h2l, dma_cache_fit(params.btt), PCI_DMA_TODEVICE);
break;
case IOCTL_CMD_DMA_READ_BUF:
fflink_info("IOCTL_CMD_DMA_READ_BUF with Param-Size: %d byte\n", _IOC_SIZE(ioctl_num));
fflink_info("Host_addr %llX Fpga_addr %llX btt %u\n", params.host_addr, params.fpga_addr, params.btt);
read_device(params.btt, (char __user *) params.host_addr, (void *) params.fpga_addr, p);
break;
case IOCTL_CMD_DMA_WRITE_BUF:
fflink_info("IOCTL_CMD_DMA_WRITE_BUF with Param-Size: %d byte\n", _IOC_SIZE(ioctl_num));
fflink_info("Host_addr %llX Fpga_addr %llX btt %d\n", params.host_addr, params.fpga_addr, params.btt);
write_device(params.btt, (char __user *) params.host_addr, (void *) params.fpga_addr, p);
break;
case IOCTL_CMD_DMA_SET_MEM_H2L:
fflink_info("IOCTL_CMD_DMA_SET_MEM_H2L with Param-Size: %d byte\n", _IOC_SIZE(ioctl_num));
fflink_info("Set new H2L addr to %llX:\n", params.fpga_addr);
p->mem_addr_h2l = (void *) params.fpga_addr;
break;
case IOCTL_CMD_DMA_SET_MEM_L2H:
fflink_info("IOCTL_CMD_DMA_SET_MEM_H2L with Param-Size: %d byte\n", _IOC_SIZE(ioctl_num));
fflink_info("Set new H2L addr to %llX:\n", params.fpga_addr);
p->mem_addr_l2h = (void *) params.fpga_addr;
break;
default:
fflink_warn("default case - nothing to do here\n");
break;
}
mutex_unlock(&p->rw_mutex);
return 0;
}
......@@ -558,26 +558,26 @@ int char_dma_register(void)
{
int err = 0;
struct device *device = NULL;
fflink_info("Try to add char_device to /dev\n");
/* create device class to register under sysfs */
err = alloc_chrdev_region(&char_dma_dev_t, 0, 1, FFLINK_DMA_NAME);
if (err < 0 || MINOR(char_dma_dev_t) != 0) {
fflink_warn("failed to allocate chrdev with %d minors\n", 1);
goto error_no_device;
}
/* create device class to register under udev/sysfs */
if (IS_ERR((char_dma_class = class_create(THIS_MODULE, FFLINK_DMA_NAME)))) {
fflink_warn("failed to create class\n");
goto error_class_invalid;
}
/* initialize char dev with fops to prepare for adding */
cdev_init(&char_dma_cdev, &dma_fops);
char_dma_cdev.owner = THIS_MODULE;
/* try to add char dev */
err = cdev_add(&char_dma_cdev, char_dma_dev_t, 1);
if (err) {
......@@ -592,11 +592,11 @@ int char_dma_register(void)
fflink_warn("failed while device create %d\n", MINOR(char_dma_dev_t));
goto error_device_create;
}
dma_ctrl_init((void *) DMA_BASE_ADDR_0);
return dma_initialize();
/* tidy up for everything successfully allocated */
error_device_create:
device_destroy(char_dma_class, MKDEV(MAJOR(char_dma_dev_t), MINOR(char_dma_dev_t)));
......@@ -615,17 +615,17 @@ error_no_device:
* @return none
* */
void char_dma_unregister(void)
{
{
fflink_info("Tidy up\n");
dma_deinit();
device_destroy(char_dma_class, MKDEV(MAJOR(char_dma_dev_t), MINOR(char_dma_dev_t)));
cdev_del(&char_dma_cdev);
class_destroy(char_dma_class);
unregister_chrdev_region(char_dma_dev_t, 1);
}
......
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file char_device_dma.h
* @file char_device_dma.h
* @brief Composition of everything needed to handle char-device calls for dma transfers
here all definitions of functions and structs are given, which are used by the char-device
the user can adapt the method used for transfers (bounce-/double-buffering)
......@@ -98,17 +98,17 @@ struct priv_data_struct {
dma_addr_t dma_handle_h2l;
dma_addr_t dma_handle_l2h;
void * mem_addr_l2h;
void * mem_addr_h2l;
void * device_base_addr;
void * ctrl_base_addr;
wait_queue_head_t rw_wait_queue;
bool condition_rw;
struct mutex rw_mutex;
unsigned int cache_lsize;
unsigned int cache_mask;
};
......
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file char_device_user.c
* @file char_device_user.c
* @brief Implementation of char-device calls for user-specific calls
the char-device allows access to the user-registers over pcie
besides it handles blocking execution of hw-function
......@@ -40,44 +40,22 @@ static struct file_operations user_fops = {
.unlocked_ioctl = user_ioctl,
.read = user_read,
.write = user_write,
.mmap = user_mmap
.mmap = user_mmap
};
/* struct array to hold data over multiple fops-calls */
static struct priv_data_struct priv_data[FFLINK_USER_NODES];
static struct priv_data_struct priv_data;
/* char device structure basically for dev_t and fops */
static struct cdev char_user_cdev;
static struct cdev char_user_cdev;
/* char device number for f3_char_driver major and minor number */
static dev_t char_user_dev_t;
/* device class entry for sysfs */
struct class *char_user_class;
/******************************************************************************/
static int device_opened = 0;
/**
* @brief Adds atomically all 32 bits of mask to condition
* @param condition Pointer to value that should be changed
* @param mask Contains all bits that should be added to condition
* @return None
* */
static inline void user_set_mask(unsigned long *condition, uint32_t mask)
{
/*
int i;
for(i = 0; i < 32; i++) {
if(BIT_MASK(i) & mask)
set_bit(i, &p->user_condition_0);
}
fflink_warn("Atomic value is %lX vs mask %X", p->user_condition_0, mask);
*/
unsigned long old, status;
do{
old = *condition;
status = cmpxchg(condition, old, old | mask);
}while(status != old);
fflink_info("Old value: %lX new value: %lX", old, *condition | mask);
}
static DEFINE_SPINLOCK(device_open_close_mutex);
/******************************************************************************/
/* functions for user-space interaction */
......@@ -92,71 +70,14 @@ static inline void user_set_mask(unsigned long *condition, uint32_t mask)
* */
static int user_open(struct inode *inode, struct file *filp)
{
int irq_state = 0, hw_id = 0;
spin_lock(&device_open_close_mutex);
fflink_notice("Called for device (<%d,%d>)\n", imajor(inode), iminor(inode));
/* check if ID core is readable */
hw_id = pcie_readl((void*) HW_ID_ADDR);
if(hw_id != HW_ID_MAGIC) {
fflink_warn("ID Core not found (was %X - should: %X)\n", hw_id, HW_ID_MAGIC);
return -ENOTEMPTY;
}
/* currently maximal four engines are supported - see switch case in dma_init */
if(iminor(inode) < FFLINK_USER_NODES && iminor(inode) >= 0 && iminor(inode) < 4)
/* set filp for further sys calls to this minor number */
filp->private_data = &priv_data[iminor(inode)];
else
return -ENODEV;
priv_data[iminor(inode)].minor = iminor(inode);
/* init control structures for synchron sys-calls */
mutex_init(&priv_data[iminor(inode)].rw_mutex);
init_waitqueue_head(&priv_data[iminor(inode)].user_wait_queue);
priv_data[iminor(inode)].user_condition = 0;
fflink_info("Activate interrupt controller %d\n", iminor(inode));
switch(iminor(inode)) {
case 0:
/* check of pending irqs interrupts */
if(pcie_readl((void*) IRQ_BASE_ADDR_0 + IRQ_REG_ISR)) {
fflink_warn("Interrupt controller already has irqs %X\n", irq_state);
return -ENOTEMPTY;
}
pcie_writel(CMD_IER_EN, (void*) IRQ_BASE_ADDR_0 + IRQ_REG_IER);
pcie_writel(CMD_MER_EN, (void*) IRQ_BASE_ADDR_0 + IRQ_REG_MER);
break;
case 1:
if(pcie_readl((void*) IRQ_BASE_ADDR_1 + IRQ_REG_ISR)) {
fflink_warn("Interrupt controller already has irqs\n");
return -ENOTEMPTY;
}
pcie_writel(CMD_IER_EN, (void*) IRQ_BASE_ADDR_1 + IRQ_REG_IER);
pcie_writel(CMD_MER_EN, (void*) IRQ_BASE_ADDR_1 + IRQ_REG_MER);
break;
case 2:
if(pcie_readl((void*) IRQ_BASE_ADDR_2 + IRQ_REG_ISR)) {
fflink_warn("Interrupt controller already has irqs\n");
return -ENOTEMPTY;
}
pcie_writel(CMD_IER_EN, (void*) IRQ_BASE_ADDR_2 + IRQ_REG_IER);
pcie_writel(CMD_MER_EN, (void*) IRQ_BASE_ADDR_2 + IRQ_REG_MER);
break;
case 3:
if(pcie_readl((void*) IRQ_BASE_ADDR_3 + IRQ_REG_ISR)) {
fflink_warn("Interrupt controller already has irqs\n");
return -ENOTEMPTY;
}
pcie_writel(CMD_IER_EN, (void*) IRQ_BASE_ADDR_3 + IRQ_REG_IER);
pcie_writel(CMD_MER_EN, (void*) IRQ_BASE_ADDR_3 + IRQ_REG_MER);
break;
default:
fflink_warn("wrong minor node opened %d\n", iminor(inode));
break;
}
fflink_notice("Already %d files in use.\n", device_opened);
++device_opened;
/* set filp for further sys calls to this minor number */
filp->private_data = &priv_data;
spin_unlock(&device_open_close_mutex);
return 0;
}
......@@ -168,8 +89,10 @@ static int user_open(struct inode *inode, struct file *filp)
* */
static int user_close(struct inode *inode, struct file *filp)
{
fflink_notice("Called for device (<%d,%d>)\n", imajor(inode), iminor(inode));
spin_lock(&device_open_close_mutex);
--device_opened;
fflink_notice("Still %d files in use.\n", device_opened);
spin_unlock(&device_open_close_mutex);
return 0;
}
......@@ -304,6 +227,7 @@ USER_WRITE_CLEANUP:
* */
static long user_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long ioctl_param)
{
int irq_counter;
struct priv_data_struct * p = (struct priv_data_struct *) filp->private_data;
struct user_ioctl_params params;
fflink_notice("Called for device minor %d\n", p->minor);
......@@ -322,14 +246,14 @@ static long user_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long
fflink_info("IOCTL_CMD_USER_WAIT_EVENT with Param-Size: %d byte\n", _IOC_SIZE(ioctl_num));
fflink_info("Want to write %X to address %llX with event %d\n", params.data, params.fpga_addr, params.event);
irq_counter = priv_data.user_condition[params.event];
pcie_writel(params.data, (void*) params.fpga_addr);
if(wait_event_interruptible(p->user_wait_queue, test_bit(params.event, &p->user_condition))) {
if(wait_event_interruptible(p->user_wait_queue[params.event], (irq_counter != p->user_condition[params.event]))) {
fflink_warn("got killed while hanging in waiting queue\n");
break;
}
clear_bit(params.event, &p->user_condition);
fflink_info("Bitmask %ld new Condition %ld\n", BIT_MASK(params.event), p->user_condition);
break;
default:
......@@ -348,11 +272,11 @@ static long user_ioctl(struct file *filp, unsigned int ioctl_num, unsigned long
but not recommended, cause address space will not be filled completely rather than sparse
performing a transaction on the 'wholes' will cause deadlocks immediatly
* @param filp Needed to identify device node and get access to corresponding buffers
* @param vma Struct of virtual memory representation, will be modified to allow user-space access
* @param vma Struct of virtual memory representation, will be modified to allow user-space access
* @return Zero, if memory could be mapped, error code otherwise
* */