diff options
author | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2018-05-03 20:06:14 +0200 |
---|---|---|
committer | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2018-05-03 20:06:14 +0200 |
commit | 77c090b85d2dc085dce3712d4a5faf8452531d58 (patch) | |
tree | 8943ec00fd7871df6fc12fad61dd31e2de13adc2 | |
parent | 391f8bee7ef5a2e92d24d73f0072915b7cb12b6b (diff) |
Store and use minor number
-rw-r--r-- | char.c | 14 | ||||
-rw-r--r-- | char.h | 6 | ||||
-rw-r--r-- | pci.c | 4 | ||||
-rw-r--r-- | pci.h | 4 |
4 files changed, 21 insertions, 7 deletions
@@ -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) @@ -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); @@ -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) @@ -1,6 +1,10 @@ #ifndef PCI_H #define PCI_H +struct doom_data { + int minor; +}; + int pci_init(void); void pci_cleanup(void); |