-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathmodule.c
144 lines (120 loc) · 2.96 KB
/
module.c
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/ktime.h>
#include <linux/hrtimer.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/semaphore.h>
#include <linux/workqueue.h>
#include "cc2520.h"
#include "radio.h"
#include "platform.h"
#include "lpl.h"
#include "interface.h"
#include "sack.h"
#include "csma.h"
#include "unique.h"
#include "debug.h"
#define DRIVER_AUTHOR "Andrew Robinson <[email protected]>"
#define DRIVER_DESC "A driver for the CC2520 radio."
#define DRIVER_VERSION "0.5"
uint8_t debug_print;
struct cc2520_state state;
const char cc2520_name[] = "cc2520";
struct cc2520_interface interface_to_unique;
struct cc2520_interface unique_to_lpl;
struct cc2520_interface lpl_to_csma;
struct cc2520_interface csma_to_sack;
struct cc2520_interface sack_to_radio;
void setup_bindings(void)
{
radio_top = &sack_to_radio;
sack_bottom = &sack_to_radio;
sack_top = &csma_to_sack;
csma_bottom = &csma_to_sack;
csma_top = &lpl_to_csma;
lpl_bottom = &lpl_to_csma;
lpl_top = &unique_to_lpl;
unique_bottom = &unique_to_lpl;
unique_top = &interface_to_unique;
interface_bottom = &interface_to_unique;
}
int init_module()
{
int err = 0;
debug_print = DEBUG_PRINT_INFO;
setup_bindings();
memset(&state, 0, sizeof(struct cc2520_state));
INFO((KERN_INFO "[CC2520] - Loading kernel module v%s\n", DRIVER_VERSION));
err = cc2520_plat_gpio_init();
if (err) {
ERR((KERN_ALERT "[CC2520] - gpio driver error. aborting.\n"));
goto error7;
}
err = cc2520_plat_spi_init();
if (err) {
ERR((KERN_ALERT "[cc2520] - spi driver error. aborting.\n"));
goto error6;
}
err = cc2520_interface_init();
if (err) {
ERR((KERN_ALERT "[cc2520] - char driver error. aborting.\n"));
goto error5;
}
err = cc2520_radio_init();
if (err) {
ERR((KERN_ALERT "[cc2520] - radio init error. aborting.\n"));
goto error4;
}
err = cc2520_lpl_init();
if (err) {
ERR((KERN_ALERT "[cc2520] - lpl init error. aborting.\n"));
goto error3;
}
err = cc2520_sack_init();
if (err) {
ERR((KERN_ALERT "[cc2520] - sack init error. aborting.\n"));
goto error2;
}
err = cc2520_csma_init();
if (err) {
ERR((KERN_ALERT "[cc2520] - csma init error. aborting.\n"));
goto error1;
}
err = cc2520_unique_init();
if (err) {
ERR((KERN_ALERT "[cc2520] - unique init error. aborting.\n"));
goto error0;
}
state.wq = create_singlethread_workqueue(cc2520_name);
return 0;
error0:
cc2520_csma_free();
error1:
cc2520_sack_free();
error2:
cc2520_lpl_free();
error3:
cc2520_radio_free();
error4:
cc2520_interface_free();
error5:
cc2520_plat_spi_free();
error6:
cc2520_plat_gpio_free();
error7:
return -1;
}
void cleanup_module()
{
destroy_workqueue(state.wq);
cc2520_interface_free();
cc2520_plat_gpio_free();
cc2520_plat_spi_free();
INFO((KERN_INFO "[cc2520] - Unloading kernel module\n"));
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);