m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-04 21:06:13 +0200
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-04 21:06:13 +0200
commit66d048ece86d238c0712a0a205479ce8842f3053 (patch)
treeb2304c35b16ec0295f85c68c2c4e87cab2d92e49
parent2eaa35293d31075348fe606bef5a58885d8e09a9 (diff)
Perform basic PCI initialization
-rw-r--r--char.c20
-rw-r--r--char.h4
-rw-r--r--pci.c38
-rw-r--r--pci.h1
4 files changed, 45 insertions, 18 deletions
diff --git a/char.c b/char.c
index c752713..db8ffcc 100644
--- a/char.c
+++ b/char.c
@@ -44,11 +44,7 @@ int new_doomdev(struct pci_dev *dev)
return -ENOMEM;
}
- doom_data = kmalloc(sizeof(*doom_data), GFP_KERNEL);
- if (doom_data == NULL) {
- err = -ENOMEM;
- goto error_kmalloc;
- }
+ doom_data = pci_get_drvdata(dev);
doom_data->cdev = cdev_alloc();
if (doom_data->cdev == NULL) {
@@ -63,8 +59,6 @@ int new_doomdev(struct pci_dev *dev)
doom_data->device = device_create(doom_class, &dev->dev, devt, NULL,
"doom%d", minor),
ORFAIL_PTR(doom_data->device, error_create);
-
- pci_set_drvdata(dev, doom_data);
return 0;
@@ -72,19 +66,13 @@ error_create:
cdev_del(doom_data->cdev);
error_add:
error_cdev:
- kfree(doom_data);
-error_kmalloc:
return err;
}
-void destroy_doomdev(struct pci_dev *dev)
+void destroy_doomdev(struct doom_data *doom_data)
{
- struct doom_data *data;
-
- data = pci_get_drvdata(dev);
- device_destroy(doom_class, data->device->devt);
- cdev_del(data->cdev);
- kfree(data);
+ device_destroy(doom_class, doom_data->device->devt);
+ cdev_del(doom_data->cdev);
}
int char_init(void)
diff --git a/char.h b/char.h
index 31e82a2..a708023 100644
--- a/char.h
+++ b/char.h
@@ -3,8 +3,10 @@
#include <linux/pci.h>
+#include "pci.h"
+
int new_doomdev(struct pci_dev *dev);
-void destroy_doomdev(struct pci_dev *dev);
+void destroy_doomdev(struct doom_data *doom_data);
int char_init(void);
void char_cleanup(void);
diff --git a/pci.c b/pci.c
index ef6d5bf..95aad2e 100644
--- a/pci.c
+++ b/pci.c
@@ -10,16 +10,52 @@
int doom_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
+ struct doom_data *doom_data;
int err = 0;
+
+ ORFAIL(pci_enable_device(dev), error_enable);
+ ORFAIL(pci_request_regions(dev, "harddoom"), error_regions);
+
+ doom_data = kmalloc(sizeof(*doom_data), GFP_KERNEL);
+ if (doom_data == NULL) {
+ err = -ENOMEM;
+ goto error_kmalloc;
+ }
+ pci_set_drvdata(dev, doom_data);
+ doom_data->iomem = pci_iomap(dev, 0, 0);
+
+ pci_set_master(dev);
+ pci_set_dma_mask(dev, DMA_BIT_MASK(32));
+ pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(32));
+
ORFAIL(new_doomdev(dev), error_doomdev);
+ return 0;
+
error_doomdev:
+ pci_clear_master(dev);
+ pci_iounmap(dev, doom_data->iomem);
+ kfree(doom_data);
+error_kmalloc:
+ pci_release_regions(dev);
+error_regions:
+ pci_disable_device(dev);
+error_enable:
return err;
}
void doom_remove (struct pci_dev *dev)
{
- destroy_doomdev(dev);
+ struct doom_data *doom_data;
+
+ doom_data = pci_get_drvdata(dev);
+
+ destroy_doomdev(doom_data);
+ pci_clear_master(dev);
+ pci_iounmap(dev, doom_data->iomem);
+ kfree(doom_data);
+ pci_release_regions(dev);
+ pci_disable_device(dev);
}
int doom_suspend (struct pci_dev *dev, pm_message_t state)
diff --git a/pci.h b/pci.h
index 9e8d07f..9386703 100644
--- a/pci.h
+++ b/pci.h
@@ -6,6 +6,7 @@
struct doom_data {
struct cdev *cdev;
struct device *device;
+ void __iomem *iomem;
};
int pci_init(void);