m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--char.c14
-rw-r--r--char.h6
-rw-r--r--pci.c4
-rw-r--r--pci.h4
4 files changed, 21 insertions, 7 deletions
diff --git a/char.c b/char.c
index 7fe7652..b13b08a 100644
--- a/char.c
+++ b/char.c
@@ -5,6 +5,7 @@
#include "linux/fs.h"
#include "util.h"
+#include "pci.h"
#define DOOMDEV_COUNT 256
#define DOOMDEV_NAME "doom"
@@ -32,13 +33,14 @@ struct file_operations doomdev_fops = {
struct class *doom_class;
-int new_doomdev(void)
+int new_doomdev(struct pci_dev *dev)
{
int err = 0;
int minor;
dev_t devt;
struct cdev *doom_cdev;
struct device *doomdev;
+ struct doom_data *doom_data;
if (next_minor >= DOOMDEV_COUNT) {
return -ENOMEM;
}
@@ -51,6 +53,9 @@ int new_doomdev(void)
doom_cdev->ops = &doomdev_fops;
ORFAIL(cdev_add(doom_cdev, first, 1), error_add);
minor = next_minor++;
+ doom_data = kmalloc(sizeof(*doom_data), GFP_KERNEL);
+ doom_data->minor = minor;
+ pci_set_drvdata(dev, doom_data);
devt = MKDEV(major, minor);
ORFAIL_PTR(device_create(doom_class, NULL, devt, NULL,
"doom%d", minor),
@@ -62,9 +67,12 @@ error_add:
return err;
}
-void destroy_doomdev(void)
+void destroy_doomdev(struct pci_dev *dev)
{
- device_destroy(doom_class, first);
+ struct doom_data *data;
+ data = pci_get_drvdata(dev);
+ device_destroy(doom_class, MKDEV(major, data->minor));
+ kfree(data);
}
int char_init(void)
diff --git a/char.h b/char.h
index 503ba04..31e82a2 100644
--- a/char.h
+++ b/char.h
@@ -1,8 +1,10 @@
#ifndef CHAR_H
#define CHAR_H
-int new_doomdev(void);
-void destroy_doomdev(void);
+#include <linux/pci.h>
+
+int new_doomdev(struct pci_dev *dev);
+void destroy_doomdev(struct pci_dev *dev);
int char_init(void);
void char_cleanup(void);
diff --git a/pci.c b/pci.c
index 3850633..ef6d5bf 100644
--- a/pci.c
+++ b/pci.c
@@ -11,7 +11,7 @@
int doom_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int err = 0;
- ORFAIL(new_doomdev(), error_doomdev);
+ ORFAIL(new_doomdev(dev), error_doomdev);
error_doomdev:
return err;
@@ -19,7 +19,7 @@ error_doomdev:
void doom_remove (struct pci_dev *dev)
{
- destroy_doomdev();
+ destroy_doomdev(dev);
}
int doom_suspend (struct pci_dev *dev, pm_message_t state)
diff --git a/pci.h b/pci.h
index 377530e..04c48f2 100644
--- a/pci.h
+++ b/pci.h
@@ -1,6 +1,10 @@
#ifndef PCI_H
#define PCI_H
+struct doom_data {
+ int minor;
+};
+
int pci_init(void);
void pci_cleanup(void);