| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: kern_todr.c,v 1.45 2020/01/01 23:15:24 thorpej Exp $ */ | | 1 | /* $NetBSD: kern_todr.c,v 1.46 2020/01/03 01:24:48 thorpej Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jason R. Thorpe. | | 8 | * by Jason R. Thorpe. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -60,27 +60,27 @@ | | | @@ -60,27 +60,27 @@ |
60 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 60 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
61 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 61 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
62 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 62 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
63 | * SUCH DAMAGE. | | 63 | * SUCH DAMAGE. |
64 | * | | 64 | * |
65 | * from: Utah Hdr: clock.c 1.18 91/01/21 | | 65 | * from: Utah Hdr: clock.c 1.18 91/01/21 |
66 | * | | 66 | * |
67 | * @(#)clock.c 8.1 (Berkeley) 6/10/93 | | 67 | * @(#)clock.c 8.1 (Berkeley) 6/10/93 |
68 | */ | | 68 | */ |
69 | | | 69 | |
70 | #include "opt_todr.h" | | 70 | #include "opt_todr.h" |
71 | | | 71 | |
72 | #include <sys/cdefs.h> | | 72 | #include <sys/cdefs.h> |
73 | __KERNEL_RCSID(0, "$NetBSD: kern_todr.c,v 1.45 2020/01/01 23:15:24 thorpej Exp $"); | | 73 | __KERNEL_RCSID(0, "$NetBSD: kern_todr.c,v 1.46 2020/01/03 01:24:48 thorpej Exp $"); |
74 | | | 74 | |
75 | #include <sys/param.h> | | 75 | #include <sys/param.h> |
76 | #include <sys/kernel.h> | | 76 | #include <sys/kernel.h> |
77 | #include <sys/systm.h> | | 77 | #include <sys/systm.h> |
78 | #include <sys/device.h> | | 78 | #include <sys/device.h> |
79 | #include <sys/timetc.h> | | 79 | #include <sys/timetc.h> |
80 | #include <sys/intr.h> | | 80 | #include <sys/intr.h> |
81 | #include <sys/rndsource.h> | | 81 | #include <sys/rndsource.h> |
82 | #include <sys/mutex.h> | | 82 | #include <sys/mutex.h> |
83 | | | 83 | |
84 | #include <dev/clock_subr.h> /* hmm.. this should probably move to sys */ | | 84 | #include <dev/clock_subr.h> /* hmm.. this should probably move to sys */ |
85 | | | 85 | |
86 | static int todr_gettime(todr_chip_handle_t, struct timeval *); | | 86 | static int todr_gettime(todr_chip_handle_t, struct timeval *); |
| @@ -387,47 +387,47 @@ do { \ | | | @@ -387,47 +387,47 @@ do { \ |
387 | } \ | | 387 | } \ |
388 | } while (/*CONSTCOND*/0) | | 388 | } while (/*CONSTCOND*/0) |
389 | | | 389 | |
390 | #define DISABLE_TODR_WRITES() \ | | 390 | #define DISABLE_TODR_WRITES() \ |
391 | do { \ | | 391 | do { \ |
392 | if (todr_wenable(tch, 0) != 0) \ | | 392 | if (todr_wenable(tch, 0) != 0) \ |
393 | printf("%s: WARNING: cannot disable TODR writes\n", \ | | 393 | printf("%s: WARNING: cannot disable TODR writes\n", \ |
394 | __func__); \ | | 394 | __func__); \ |
395 | } while (/*CONSTCOND*/0) | | 395 | } while (/*CONSTCOND*/0) |
396 | | | 396 | |
397 | static int | | 397 | static int |
398 | todr_gettime(todr_chip_handle_t tch, struct timeval *tvp) | | 398 | todr_gettime(todr_chip_handle_t tch, struct timeval *tvp) |
399 | { | | 399 | { |
400 | struct clock_ymdhms dt; | | 400 | int rv; |
401 | int rv; | | | |
402 | | | 401 | |
403 | /* | | 402 | /* |
404 | * Write-enable is used even when reading the TODR because | | 403 | * Write-enable is used even when reading the TODR because |
405 | * writing to registers may be required in order to do so. | | 404 | * writing to registers may be required in order to do so. |
406 | */ | | 405 | */ |
407 | | | 406 | |
408 | if (tch->todr_gettime) { | | 407 | if (tch->todr_gettime) { |
409 | ENABLE_TODR_WRITES(); | | 408 | ENABLE_TODR_WRITES(); |
410 | rv = tch->todr_gettime(tch, tvp); | | 409 | rv = tch->todr_gettime(tch, tvp); |
411 | DISABLE_TODR_WRITES(); | | 410 | DISABLE_TODR_WRITES(); |
412 | /* | | 411 | /* |
413 | * Some unconverted ports have their own references to | | 412 | * Some unconverted ports have their own references to |
414 | * rtc_offset. A converted port must not do that. | | 413 | * rtc_offset. A converted port must not do that. |
415 | */ | | 414 | */ |
416 | if (rv == 0) | | 415 | if (rv == 0) |
417 | tvp->tv_sec += rtc_offset * 60; | | 416 | tvp->tv_sec += rtc_offset * 60; |
418 | todr_debug("TODR-GET-SECS", rv, NULL, tvp); | | 417 | todr_debug("TODR-GET-SECS", rv, NULL, tvp); |
419 | return rv; | | 418 | return rv; |
420 | } else if (tch->todr_gettime_ymdhms) { | | 419 | } else if (tch->todr_gettime_ymdhms) { |
| | | 420 | struct clock_ymdhms dt = { 0 }; |
421 | ENABLE_TODR_WRITES(); | | 421 | ENABLE_TODR_WRITES(); |
422 | rv = tch->todr_gettime_ymdhms(tch, &dt); | | 422 | rv = tch->todr_gettime_ymdhms(tch, &dt); |
423 | DISABLE_TODR_WRITES(); | | 423 | DISABLE_TODR_WRITES(); |
424 | todr_debug("TODR-GET-YMDHMS", rv, &dt, NULL); | | 424 | todr_debug("TODR-GET-YMDHMS", rv, &dt, NULL); |
425 | if (rv) | | 425 | if (rv) |
426 | return rv; | | 426 | return rv; |
427 | | | 427 | |
428 | /* | | 428 | /* |
429 | * Simple sanity checks. Note that this includes a | | 429 | * Simple sanity checks. Note that this includes a |
430 | * value for clocks that can return a leap second. | | 430 | * value for clocks that can return a leap second. |
431 | * Note that we don't support double leap seconds, | | 431 | * Note that we don't support double leap seconds, |
432 | * since this was apparently an error/misunderstanding | | 432 | * since this was apparently an error/misunderstanding |
433 | * on the part of the ISO C committee, and can never | | 433 | * on the part of the ISO C committee, and can never |
| @@ -445,39 +445,38 @@ todr_gettime(todr_chip_handle_t tch, str | | | @@ -445,39 +445,38 @@ todr_gettime(todr_chip_handle_t tch, str |
445 | return EINVAL; | | 445 | return EINVAL; |
446 | } | | 446 | } |
447 | tvp->tv_sec = clock_ymdhms_to_secs(&dt) + rtc_offset * 60; | | 447 | tvp->tv_sec = clock_ymdhms_to_secs(&dt) + rtc_offset * 60; |
448 | tvp->tv_usec = 0; | | 448 | tvp->tv_usec = 0; |
449 | return tvp->tv_sec < 0 ? EINVAL : 0; | | 449 | return tvp->tv_sec < 0 ? EINVAL : 0; |
450 | } | | 450 | } |
451 | | | 451 | |
452 | return ENXIO; | | 452 | return ENXIO; |
453 | } | | 453 | } |
454 | | | 454 | |
455 | static int | | 455 | static int |
456 | todr_settime(todr_chip_handle_t tch, struct timeval *tvp) | | 456 | todr_settime(todr_chip_handle_t tch, struct timeval *tvp) |
457 | { | | 457 | { |
458 | struct clock_ymdhms dt; | | 458 | int rv; |
459 | int rv; | | | |
460 | | | 459 | |
461 | if (tch->todr_settime) { | | 460 | if (tch->todr_settime) { |
462 | /* See comments above in gettime why this is ifdef'd */ | | 461 | struct timeval copy = *tvp; |
463 | struct timeval copy = *tvp; | | | |
464 | copy.tv_sec -= rtc_offset * 60; | | 462 | copy.tv_sec -= rtc_offset * 60; |
465 | ENABLE_TODR_WRITES(); | | 463 | ENABLE_TODR_WRITES(); |
466 | rv = tch->todr_settime(tch, ©); | | 464 | rv = tch->todr_settime(tch, ©); |
467 | DISABLE_TODR_WRITES(); | | 465 | DISABLE_TODR_WRITES(); |
468 | todr_debug("TODR-SET-SECS", rv, NULL, tvp); | | 466 | todr_debug("TODR-SET-SECS", rv, NULL, tvp); |
469 | return rv; | | 467 | return rv; |
470 | } else if (tch->todr_settime_ymdhms) { | | 468 | } else if (tch->todr_settime_ymdhms) { |
471 | time_t sec = tvp->tv_sec - rtc_offset * 60; | | 469 | struct clock_ymdhms dt; |
| | | 470 | time_t sec = tvp->tv_sec - rtc_offset * 60; |
472 | if (tvp->tv_usec >= 500000) | | 471 | if (tvp->tv_usec >= 500000) |
473 | sec++; | | 472 | sec++; |
474 | clock_secs_to_ymdhms(sec, &dt); | | 473 | clock_secs_to_ymdhms(sec, &dt); |
475 | ENABLE_TODR_WRITES(); | | 474 | ENABLE_TODR_WRITES(); |
476 | rv = tch->todr_settime_ymdhms(tch, &dt); | | 475 | rv = tch->todr_settime_ymdhms(tch, &dt); |
477 | DISABLE_TODR_WRITES(); | | 476 | DISABLE_TODR_WRITES(); |
478 | todr_debug("TODR-SET-YMDHMS", rv, &dt, NULL); | | 477 | todr_debug("TODR-SET-YMDHMS", rv, &dt, NULL); |
479 | return rv; | | 478 | return rv; |
480 | } else { | | | |
481 | return ENXIO; | | | |
482 | } | | 479 | } |
| | | 480 | |
| | | 481 | return ENXIO; |
483 | } | | 482 | } |