| 1537 | } |
| 1538 | |
| 1539 | static int |
| 1540 | pps_fetch(struct pps_fetch_args *fapi, struct pps_state *pps) |
| 1541 | { |
| 1542 | int err, timo; |
| 1543 | pps_seq_t aseq, cseq; |
| 1544 | struct timeval tv; |
| 1545 | |
| 1546 | if (fapi->tsformat && fapi->tsformat != PPS_TSFMT_TSPEC) |
| 1547 | return (EINVAL); |
| 1548 | |
| 1549 | /* |
| 1550 | * If no timeout is requested, immediately return whatever values were |
| 1551 | * most recently captured. If timeout seconds is -1, that's a request |
| 1552 | * to block without a timeout. WITNESS won't let us sleep forever |
| 1553 | * without a lock (we really don't need a lock), so just repeatedly |
| 1554 | * sleep a long time. |
| 1555 | */ |
| 1556 | if (fapi->timeout.tv_sec || fapi->timeout.tv_nsec) { |
| 1557 | if (fapi->timeout.tv_sec == -1) |
| 1558 | timo = 0x7fffffff; |
| 1559 | else { |
| 1560 | tv.tv_sec = fapi->timeout.tv_sec; |
| 1561 | tv.tv_usec = fapi->timeout.tv_nsec / 1000; |
| 1562 | timo = tvtohz(&tv); |
| 1563 | } |
| 1564 | aseq = atomic_load_int(&pps->ppsinfo.assert_sequence); |
| 1565 | cseq = atomic_load_int(&pps->ppsinfo.clear_sequence); |
| 1566 | while (aseq == atomic_load_int(&pps->ppsinfo.assert_sequence) && |
| 1567 | cseq == atomic_load_int(&pps->ppsinfo.clear_sequence)) { |
| 1568 | if (abi_aware(pps, 1) && pps->driver_mtx != NULL) { |
| 1569 | if (pps->flags & PPSFLAG_MTX_SPIN) { |
| 1570 | err = msleep_spin(pps, pps->driver_mtx, |
| 1571 | "ppsfch", timo); |
| 1572 | } else { |
| 1573 | err = msleep(pps, pps->driver_mtx, PCATCH, |
| 1574 | "ppsfch", timo); |
| 1575 | } |
| 1576 | } else { |
| 1577 | err = tsleep(pps, PCATCH, "ppsfch", timo); |
| 1578 | } |
| 1579 | if (err == EWOULDBLOCK) { |
| 1580 | if (fapi->timeout.tv_sec == -1) { |
| 1581 | continue; |
| 1582 | } else { |
| 1583 | return (ETIMEDOUT); |
| 1584 | } |
| 1585 | } else if (err != 0) { |
| 1586 | return (err); |
| 1587 | } |
| 1588 | } |
| 1589 | } |
| 1590 | |
| 1591 | pps->ppsinfo.current_mode = pps->ppsparam.mode; |
| 1592 | fapi->pps_info_buf = pps->ppsinfo; |
| 1593 | |
| 1594 | return (0); |
| 1595 | } |
| 1596 | |