m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/pci.c
blob: e4cfde6ad2887eba8da7ec92bda14356ccef6a39 (plain)
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);
}