Lines 50-60
Link Here
|
50 |
MODULE_DEPEND(rtc, linux, 1, 1, 1); |
50 |
MODULE_DEPEND(rtc, linux, 1, 1, 1); |
51 |
#endif |
51 |
#endif |
52 |
|
52 |
|
53 |
#define CDEV_MAJOR 202 |
|
|
54 |
#if defined(CDEV_MAJOR_) && CDEV_MAJOR != CDEV_MAJOR_ |
55 |
#error "CDEV_MAJOR != CDEV_MAJOR_" |
56 |
#endif |
57 |
|
58 |
#define DEVICE_NAME "rtc" |
53 |
#define DEVICE_NAME "rtc" |
59 |
|
54 |
|
60 |
enum rtc_log_level {Lenter=0, Lexit=1, Linfo, Lwarning, Lfail}; |
55 |
enum rtc_log_level {Lenter=0, Lexit=1, Linfo, Lwarning, Lfail}; |
Lines 68-78
Link Here
|
68 |
#endif /* DEBUG */ |
63 |
#endif /* DEBUG */ |
69 |
|
64 |
|
70 |
struct rtc_softc { |
65 |
struct rtc_softc { |
71 |
#if __FreeBSD_version >= 502117 |
|
|
72 |
struct cdev *dev; /* Back reference to device */ |
66 |
struct cdev *dev; /* Back reference to device */ |
73 |
#else |
|
|
74 |
dev_t dev; /* Back reference to device */ |
75 |
#endif |
76 |
struct { |
67 |
struct { |
77 |
int freq; |
68 |
int freq; |
78 |
struct { |
69 |
struct { |
Lines 97-136
Link Here
|
97 |
static int rtc_modeevent(module_t mod, int cmd, void *arg); |
88 |
static int rtc_modeevent(module_t mod, int cmd, void *arg); |
98 |
|
89 |
|
99 |
static struct cdevsw rtc_cdevsw = { |
90 |
static struct cdevsw rtc_cdevsw = { |
100 |
#if __FreeBSD_version >= 500104 |
|
|
101 |
#if __FreeBSD_version >= 502103 |
102 |
.d_version = D_VERSION, |
91 |
.d_version = D_VERSION, |
103 |
.d_flags = D_NEEDGIANT, |
92 |
.d_flags = D_NEEDGIANT, |
104 |
#else |
|
|
105 |
.d_maj = CDEV_MAJOR, |
106 |
#endif |
107 |
.d_open = rtc_open, |
93 |
.d_open = rtc_open, |
108 |
.d_close = rtc_close, |
94 |
.d_close = rtc_close, |
109 |
.d_ioctl = rtc_ioctl, |
95 |
.d_ioctl = rtc_ioctl, |
110 |
.d_poll = rtc_poll, |
96 |
.d_poll = rtc_poll, |
111 |
.d_read = rtc_read, |
97 |
.d_read = rtc_read, |
112 |
.d_name = DEVICE_NAME, |
98 |
.d_name = DEVICE_NAME, |
113 |
#else |
|
|
114 |
/* open */ rtc_open, |
115 |
/* close */ rtc_close, |
116 |
/* read */ rtc_read, |
117 |
/* write */ nowrite, |
118 |
/* ioctl */ rtc_ioctl, |
119 |
/* poll */ rtc_poll, |
120 |
/* mmap */ nommap, |
121 |
/* strategy */ nostrategy, |
122 |
/* name */ DEVICE_NAME, |
123 |
/* maj */ CDEV_MAJOR, |
124 |
/* dump */ nodump, |
125 |
/* psize */ nopsize, |
126 |
/* flags */ 0, |
127 |
#if __FreeBSD_version <= 500018 |
128 |
/* bmaj */ -1, |
129 |
#endif |
130 |
#if __FreeBSD_version >= 500018 || __FreeBSD_version >= 430000 |
131 |
/* kqfilter */ nokqfilter, |
132 |
#endif |
133 |
#endif |
134 |
}; |
99 |
}; |
135 |
|
100 |
|
136 |
/* |
101 |
/* |
Lines 139-169
Link Here
|
139 |
*/ |
104 |
*/ |
140 |
DEV_MODULE(rtc, rtc_modeevent, 0); |
105 |
DEV_MODULE(rtc, rtc_modeevent, 0); |
141 |
|
106 |
|
142 |
|
|
|
143 |
/* -=-=-=-=-=-=-=-=-= attach/detach device stuff -=-=-=-=-=-=-=-=-= */ |
107 |
/* -=-=-=-=-=-=-=-=-= attach/detach device stuff -=-=-=-=-=-=-=-=-= */ |
144 |
|
108 |
|
145 |
static struct rtc_softc * |
109 |
static struct rtc_softc * |
146 |
#if __FreeBSD_version >= 502017 |
|
|
147 |
rtc_attach(struct cdev *dev) |
110 |
rtc_attach(struct cdev *dev) |
148 |
#else |
|
|
149 |
rtc_attach(dev_t dev) |
150 |
#endif |
151 |
{ |
111 |
{ |
152 |
struct rtc_softc *sc; |
112 |
struct rtc_softc *sc; |
153 |
int unit; |
113 |
int unit; |
154 |
|
114 |
|
155 |
#if __FreeBSD_version >= 500014 |
|
|
156 |
unit = dev2unit(dev); |
115 |
unit = dev2unit(dev); |
157 |
#else |
|
|
158 |
unit = lminor(dev); |
159 |
#endif |
160 |
DLog(Lenter, "%d %p", unit, dev); |
116 |
DLog(Lenter, "%d %p", unit, dev); |
161 |
if (dev->si_drv1) { |
117 |
if (dev->si_drv1) { |
162 |
DLog(Lexit, "old %p, %p", dev, dev->si_drv1); |
118 |
DLog(Lexit, "old %p, %p", dev, dev->si_drv1); |
163 |
return dev->si_drv1; |
119 |
return dev->si_drv1; |
164 |
} |
120 |
} |
165 |
|
121 |
|
166 |
MALLOC(sc, struct rtc_softc*, sizeof(*sc), M_DEVBUF, M_WAITOK); |
122 |
sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK); |
167 |
if (sc==NULL) |
123 |
if (sc==NULL) |
168 |
return NULL; |
124 |
return NULL; |
169 |
|
125 |
|
Lines 172-193
Link Here
|
172 |
sc->dev = dev; |
128 |
sc->dev = dev; |
173 |
sc->var.freq = 1; |
129 |
sc->var.freq = 1; |
174 |
|
130 |
|
175 |
#if __FreeBSD_version >= 500000 |
|
|
176 |
callout_init(&sc->var.rtc_handle, 1); |
131 |
callout_init(&sc->var.rtc_handle, 1); |
177 |
#else |
|
|
178 |
callout_init(&sc->var.rtc_handle); |
179 |
#endif |
180 |
|
132 |
|
181 |
DLog(Lexit, "new %p,%p", dev, sc); |
133 |
DLog(Lexit, "new %p,%p", dev, sc); |
182 |
return sc; |
134 |
return sc; |
183 |
} |
135 |
} |
184 |
|
136 |
|
185 |
static int |
137 |
static int |
186 |
#if __FreeBSD_version >= 502017 |
|
|
187 |
rtc_detach(struct cdev *dev, struct rtc_softc *sc) |
138 |
rtc_detach(struct cdev *dev, struct rtc_softc *sc) |
188 |
#else |
|
|
189 |
rtc_detach(dev_t dev, struct rtc_softc *sc) |
190 |
#endif |
191 |
{ |
139 |
{ |
192 |
int error=0; |
140 |
int error=0; |
193 |
|
141 |
|
Lines 196-202
Link Here
|
196 |
} |
144 |
} |
197 |
|
145 |
|
198 |
callout_stop(&sc->var.rtc_handle); |
146 |
callout_stop(&sc->var.rtc_handle); |
199 |
FREE(sc, M_DEVBUF); |
147 |
free(sc, M_DEVBUF); |
200 |
dev->si_drv1 = NULL; |
148 |
dev->si_drv1 = NULL; |
201 |
return error; |
149 |
return error; |
202 |
} |
150 |
} |
Lines 204-216
Link Here
|
204 |
/* -=-=-=-=-=-=-=-=-= character device stuff -=-=-=-=-=-=-=-=-= */ |
152 |
/* -=-=-=-=-=-=-=-=-= character device stuff -=-=-=-=-=-=-=-=-= */ |
205 |
|
153 |
|
206 |
static int |
154 |
static int |
207 |
#if __FreeBSD_version >= 502017 |
|
|
208 |
rtc_open(struct cdev *dev, int oflag, int otyp, struct thread *p) |
155 |
rtc_open(struct cdev *dev, int oflag, int otyp, struct thread *p) |
209 |
#elif __FreeBSD_version >= 500023 |
|
|
210 |
rtc_open(dev_t dev, int oflag, int otyp, struct thread *p) |
211 |
#else |
212 |
rtc_open(dev_t dev, int oflag, int otyp, struct proc *p) |
213 |
#endif |
214 |
{ |
156 |
{ |
215 |
struct rtc_softc *sc; |
157 |
struct rtc_softc *sc; |
216 |
|
158 |
|
Lines 228-240
Link Here
|
228 |
} |
170 |
} |
229 |
|
171 |
|
230 |
int |
172 |
int |
231 |
#if __FreeBSD_version >= 502017 |
|
|
232 |
rtc_close(struct cdev *dev, int fflag, int otyp, struct thread *p) |
173 |
rtc_close(struct cdev *dev, int fflag, int otyp, struct thread *p) |
233 |
#elif __FreeBSD_version >= 500023 |
|
|
234 |
rtc_close(dev_t dev, int fflag, int otyp, struct thread *p) |
235 |
#else |
236 |
rtc_close(dev_t dev, int fflag, int otyp, struct proc *p) |
237 |
#endif |
238 |
{ |
174 |
{ |
239 |
struct rtc_softc *sc = (struct rtc_softc *) dev->si_drv1; |
175 |
struct rtc_softc *sc = (struct rtc_softc *) dev->si_drv1; |
240 |
|
176 |
|
Lines 244-256
Link Here
|
244 |
} |
180 |
} |
245 |
|
181 |
|
246 |
int |
182 |
int |
247 |
#if __FreeBSD_version >= 502017 |
|
|
248 |
rtc_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, struct thread *p) |
183 |
rtc_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int mode, struct thread *p) |
249 |
#elif __FreeBSD_version >= 500023 |
|
|
250 |
rtc_ioctl(dev_t dev, u_long cmd, caddr_t arg, int mode, struct thread *p) |
251 |
#else |
252 |
rtc_ioctl(dev_t dev, u_long cmd, caddr_t arg, int mode, struct proc *p) |
253 |
#endif |
254 |
{ |
184 |
{ |
255 |
struct rtc_softc *sc = (struct rtc_softc *) dev->si_drv1; |
185 |
struct rtc_softc *sc = (struct rtc_softc *) dev->si_drv1; |
256 |
int error=0, freq, sleep; |
186 |
int error=0, freq, sleep; |
Lines 292-304
Link Here
|
292 |
} |
222 |
} |
293 |
|
223 |
|
294 |
int |
224 |
int |
295 |
#if __FreeBSD_version >= 502017 |
|
|
296 |
rtc_poll(struct cdev *dev, int events, struct thread *p) |
225 |
rtc_poll(struct cdev *dev, int events, struct thread *p) |
297 |
#elif __FreeBSD_version >= 500023 |
|
|
298 |
rtc_poll(dev_t dev, int events, struct thread *p) |
299 |
#else |
300 |
rtc_poll(dev_t dev, int events, struct proc *p) |
301 |
#endif |
302 |
{ |
226 |
{ |
303 |
struct rtc_softc *sc = (struct rtc_softc *) dev->si_drv1; |
227 |
struct rtc_softc *sc = (struct rtc_softc *) dev->si_drv1; |
304 |
int revents = 0; |
228 |
int revents = 0; |
Lines 318-328
Link Here
|
318 |
} |
242 |
} |
319 |
|
243 |
|
320 |
int |
244 |
int |
321 |
#if __FreeBSD_version >= 502017 |
|
|
322 |
rtc_read(struct cdev *dev, struct uio *uio, int flags __unused) |
245 |
rtc_read(struct cdev *dev, struct uio *uio, int flags __unused) |
323 |
#else |
|
|
324 |
rtc_read(dev_t dev, struct uio *uio, int flags __unused) |
325 |
#endif |
326 |
{ |
246 |
{ |
327 |
struct rtc_softc *sc = (struct rtc_softc *) dev->si_drv1; |
247 |
struct rtc_softc *sc = (struct rtc_softc *) dev->si_drv1; |
328 |
int error = 0; |
248 |
int error = 0; |
Lines 351-373
Link Here
|
351 |
} |
271 |
} |
352 |
|
272 |
|
353 |
/* -=-=-=-=-=-=-=-=-= module load/unload stuff -=-=-=-=-=-=-=-=-= */ |
273 |
/* -=-=-=-=-=-=-=-=-= module load/unload stuff -=-=-=-=-=-=-=-=-= */ |
354 |
#if __FreeBSD_version >= 502017 |
|
|
355 |
static struct cdev *rtc_dev = NULL; |
274 |
static struct cdev *rtc_dev = NULL; |
356 |
#else |
|
|
357 |
static dev_t rtc_dev = NULL; |
358 |
#endif |
359 |
|
275 |
|
360 |
static int |
276 |
static int |
361 |
init_module(void) |
277 |
init_module(void) |
362 |
{ |
278 |
{ |
363 |
int error = 0; |
279 |
int error = 0; |
364 |
|
280 |
|
365 |
#if __FreeBSD_version < 500104 |
|
|
366 |
error = cdevsw_add(&rtc_cdevsw); |
367 |
if (error) |
368 |
return error; |
369 |
#endif |
370 |
|
371 |
rtc_dev = make_dev(&rtc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, DEVICE_NAME); |
281 |
rtc_dev = make_dev(&rtc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, DEVICE_NAME); |
372 |
if (rtc_dev==NULL) |
282 |
if (rtc_dev==NULL) |
373 |
error = ENOMEM; |
283 |
error = ENOMEM; |
Lines 375-391
Link Here
|
375 |
return error; |
285 |
return error; |
376 |
} |
286 |
} |
377 |
|
287 |
|
378 |
|
|
|
379 |
|
380 |
static int |
288 |
static int |
381 |
cleanup_module(void) |
289 |
cleanup_module(void) |
382 |
{ |
290 |
{ |
383 |
int error = 0; |
291 |
int error = 0; |
384 |
|
292 |
|
385 |
destroy_dev(rtc_dev); |
293 |
destroy_dev(rtc_dev); |
386 |
#if __FreeBSD_version < 500104 |
|
|
387 |
error = cdevsw_remove(&rtc_cdevsw); |
388 |
#endif |
389 |
DLog(Linfo, "return %d", error); |
294 |
DLog(Linfo, "return %d", error); |
390 |
return error; |
295 |
return error; |
391 |
} |
296 |
} |
Lines 433-455
Link Here
|
433 |
restart: |
338 |
restart: |
434 |
increment.tv_sec = 0; |
339 |
increment.tv_sec = 0; |
435 |
increment.tv_nsec = 1000000000 / sc->var.freq; |
340 |
increment.tv_nsec = 1000000000 / sc->var.freq; |
|
|
341 |
#if P_OSREL_MAJOR(__FreeBSD_version) >= 12 |
342 |
timespecadd(&sc->var.lasttime, &increment, &sc->var.lasttime); |
343 |
timespecadd(&sc->var.lasttime, &increment, &nexttime); |
344 |
#else |
436 |
timespecadd(&sc->var.lasttime, &increment); |
345 |
timespecadd(&sc->var.lasttime, &increment); |
437 |
nexttime.tv_sec = sc->var.lasttime.tv_sec; |
346 |
nexttime.tv_sec = sc->var.lasttime.tv_sec; |
438 |
nexttime.tv_nsec = sc->var.lasttime.tv_nsec; |
347 |
nexttime.tv_nsec = sc->var.lasttime.tv_nsec; |
439 |
timespecadd(&nexttime, &increment); |
348 |
timespecadd(&nexttime, &increment); |
|
|
349 |
#endif |
440 |
if (timespeccmp(&nexttime, &curtime, <)) { |
350 |
if (timespeccmp(&nexttime, &curtime, <)) { |
441 |
/* Catch up if we lag curtime */ |
351 |
/* Catch up if we lag curtime */ |
442 |
sc->var.lasttime.tv_sec = curtime.tv_sec; |
352 |
#if P_OSREL_MAJOR(__FreeBSD_version) >= 12 |
443 |
sc->var.lasttime.tv_nsec = curtime.tv_nsec; |
353 |
timespecsub(&curtime, &increment, &sc->var.lasttime); |
444 |
timespecsub(&sc->var.lasttime, &increment); |
354 |
timespecsub(&nexttime, &curtime, &nexttime); |
445 |
timespecsub(&nexttime, &curtime); |
355 |
#else |
|
|
356 |
sc->var.lasttime.tv_sec = curtime.tv_sec; |
357 |
sc->var.lasttime.tv_nsec = curtime.tv_nsec; |
358 |
timespecsub(&sc->var.lasttime, &increment); |
359 |
timespecsub(&nexttime, &curtime); |
360 |
#endif |
446 |
#if 0 |
361 |
#if 0 |
447 |
printf("lagging curtime by %d.%ld\n", nexttime.tv_sec, nexttime.tv_nsec); |
362 |
printf("lagging curtime by %d.%ld\n", nexttime.tv_sec, nexttime.tv_nsec); |
448 |
#endif |
363 |
#endif |
449 |
goto restart; |
364 |
goto restart; |
450 |
} else { |
365 |
} else { |
|
|
366 |
#if P_OSREL_MAJOR(__FreeBSD_version) >= 12 |
367 |
timespecsub(&nexttime, &curtime, &nexttime); |
368 |
#else |
451 |
timespecsub(&nexttime, &curtime); |
369 |
timespecsub(&nexttime, &curtime); |
452 |
sleep = nexttime.tv_nsec / (1000000000 / hz); |
370 |
#endif |
453 |
} |
371 |
sleep = nexttime.tv_nsec / (1000000000 / hz); |
454 |
callout_reset(&sc->var.rtc_handle, sleep, &rtc_callback, xtp); |
372 |
} |
|
|
373 |
callout_reset(&sc->var.rtc_handle, sleep, &rtc_callback, xtp); |
455 |
} |
374 |
} |