Unverified Commit a5560c27 authored by Johannes Wirth's avatar Johannes Wirth Committed by GitHub
Browse files

Merge pull request #328 from esa-tu-darmstadt/feature/fix-multidevice-access-mode

Add list of acquired devices to miscdev
parents d7768b39 e5488f17
Pipeline #2615 passed with stages
in 106 minutes and 37 seconds
......@@ -65,32 +65,39 @@ void tlkm_exit(void)
static int tlkm_miscdev_open(struct inode *inode, struct file *filp)
{
tlkm_ioctl_data *tmp = NULL;
struct tlkm_ioctl_dev_list_head *tmp = NULL;
atomic_inc(&opened_counter);
LOG(TLKM_LF_MODULE, "Device is now opened %d times.",
atomic_read(&opened_counter));
filp->private_data =
(tlkm_ioctl_data *)kmalloc(sizeof(tlkm_ioctl_data), GFP_KERNEL);
kmalloc(sizeof(struct tlkm_ioctl_dev_list_head), GFP_KERNEL);
if (!filp->private_data)
return -ENODEV;
tmp = (tlkm_ioctl_data *)filp->private_data;
tmp->pdev = NULL;
tmp = filp->private_data;
INIT_LIST_HEAD(&tmp->head);
return 0;
}
static int tlkm_miscdev_release(struct inode *inode, struct file *filp)
{
tlkm_ioctl_data *tmp = NULL;
struct tlkm_ioctl_dev_list_head *dev_list;
struct tlkm_ioctl_dev_list_entry *entry, *tmp;
atomic_dec(&opened_counter);
LOG(TLKM_LF_MODULE, "Device is still opened %d times.",
atomic_read(&opened_counter));
if (filp->private_data != NULL) {
tmp = (tlkm_ioctl_data *)filp->private_data;
if (tmp->pdev) {
tlkm_device_release(tmp->pdev, tmp->access);
}
kfree(filp->private_data);
filp->private_data = NULL;
dev_list = filp->private_data;
if (!dev_list) {
ERR("device list not initialized");
return -ENODEV;
}
list_for_each_entry_safe(entry, tmp, &dev_list->head, list) {
tlkm_device_release(entry->pdev, entry->access);
list_del(&entry->list);
kfree(entry);
}
kfree(filp->private_data);
filp->private_data = NULL;
return 0;
}
......@@ -76,32 +76,62 @@ tlkm_ioctl_enum_devices(struct file *fp, unsigned int ioctl,
static long tlkm_ioctl_create_device(struct file *fp, unsigned int ioctl,
struct tlkm_ioctl_device_cmd __user *cmd)
{
tlkm_ioctl_data *tmp = NULL;
int ret = 0;
struct tlkm_ioctl_dev_list_head *dev_list = NULL;
struct tlkm_ioctl_dev_list_entry *new;
struct tlkm_ioctl_device_cmd kc;
if (copy_from_user(&kc, (void __user *)cmd, sizeof(kc))) {
ERR("could not copy create device command from user space");
return -EACCES;
}
LOG(TLKM_LF_IOCTL, "create device #%02u command received", kc.dev_id);
tmp = (tlkm_ioctl_data *)fp->private_data;
tmp->pdev = tlkm_bus_get_device(kc.dev_id);
tmp->access = kc.access;
return tlkm_device_acquire(tlkm_bus_get_device(kc.dev_id), kc.access);
dev_list = fp->private_data;
new = kmalloc(sizeof(*new), GFP_KERNEL);
if (!new) {
ERR("could not allocate memory for list entry");
return -ENOMEM;
}
new->pdev = tlkm_bus_get_device(kc.dev_id);
new->access = kc.access;
ret = tlkm_device_acquire(tlkm_bus_get_device(kc.dev_id), kc.access);
if (ret)
kfree(new);
else
list_add(&new->list, &dev_list->head);
return ret;
}
static long tlkm_ioctl_destroy_device(struct file *fp, unsigned int ioctl,
struct tlkm_ioctl_device_cmd __user *cmd)
{
tlkm_ioctl_data *tmp = NULL;
struct tlkm_device *dev;
struct tlkm_ioctl_dev_list_head *dev_list;
struct tlkm_ioctl_dev_list_entry *entry = NULL, *iter;
struct tlkm_ioctl_device_cmd kc;
if (copy_from_user(&kc, (void __user *)cmd, sizeof(kc))) {
ERR("could not copy destroy device command from user space");
return -EACCES;
}
LOG(TLKM_LF_IOCTL, "destroy device #%02u command received", kc.dev_id);
tlkm_device_release(tlkm_bus_get_device(kc.dev_id), kc.access);
tmp = (tlkm_ioctl_data *)fp->private_data;
tmp->pdev = NULL;
dev = tlkm_bus_get_device(kc.dev_id);
dev_list = fp->private_data;
list_for_each_entry(iter, &dev_list->head, list) {
if (iter->pdev == dev && iter->access == kc.access) {
entry = iter;
break;
}
}
if (!entry) {
ERR("No matching device acquired");
return -ENODEV;
}
tlkm_device_release(dev, kc.access);
list_del(&entry->list);
kfree(entry);
return 0;
}
......
......@@ -22,10 +22,15 @@
#include <linux/fs.h>
typedef struct {
struct tlkm_ioctl_dev_list_head {
struct list_head head;
};
struct tlkm_ioctl_dev_list_entry {
struct list_head list;
struct tlkm_device *pdev;
tlkm_access_t access;
} tlkm_ioctl_data;
};
long tlkm_ioctl_ioctl(struct file *fp, unsigned int ioctl, unsigned long data);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment