1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include "pci.h"
#include <linux/kernel.h>
#include <linux/pci.h>
#include "char.h"
#include "harddoom.h"
#include "util.h"
#include "harddoomdev.h"
#include "private_data.h"
int init_pci(struct pci_dev *dev) {
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));
return 0;
error_kmalloc:
pci_release_regions(dev);
error_regions:
pci_disable_device(dev);
error_enable:
return err;
}
void cleanup_pci(struct pci_dev *dev) {
struct doom_data *doom_data;
doom_data = pci_get_drvdata(dev);
pci_clear_master(dev);
pci_iounmap(dev, doom_data->iomem);
kfree(doom_data);
pci_release_regions(dev);
pci_disable_device(dev);
}
int doom_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int err = 0;
ORFAIL(init_pci(dev), error_pci);
start_dev(dev);
ORFAIL(new_doomdev(dev), error_doomdev);
return 0;
error_doomdev:
shutdown_dev(dev);
cleanup_pci(dev);
error_pci:
return err;
}
void doom_remove (struct pci_dev *dev)
{
struct doom_data *doom_data;
doom_data = pci_get_drvdata(dev);
destroy_doomdev(doom_data);
shutdown_dev(dev);
cleanup_pci(dev);
}
int doom_suspend (struct pci_dev *dev, pm_message_t state)
{
return 0;
}
int doom_suspend_late (struct pci_dev *dev, pm_message_t state)
{
return 0;
}
int doom_resume_early (struct pci_dev *dev)
{
return 0;
}
int doom_resume (struct pci_dev *dev)
{
return 0;
}
void doom_shutdown (struct pci_dev *dev)
{
}
struct pci_device_id device_ids[1] = {
{ PCI_DEVICE(HARDDOOM_VENDOR_ID, HARDDOOM_DEVICE_ID) }
};
struct pci_driver driver = {
.name = "harddoom",
.id_table = device_ids,
.probe = doom_probe,
.remove = doom_remove,
.suspend = doom_suspend,
.suspend_late = doom_suspend_late,
.resume_early = doom_resume_early,
.resume = doom_resume,
.shutdown = doom_shutdown
};
int pci_init(void)
{
return pci_register_driver(&driver);
}
void pci_cleanup(void)
{
pci_unregister_driver(&driver);
}
|