static void print_uptime(void) { int f; struct timespec ts; getnanouptime(&ts); kprintf("Uptime: "); f = 0; if (ts.tv_sec >= 86400) { kprintf("%ldd", ts.tv_sec / 86400); ts.tv_sec %= 86400; f = 1; } if (f || ts.tv_sec >= 3600) { kprintf("%ldh", ts.tv_sec / 3600); ts.tv_sec %= 3600; f = 1; } if (f || ts.tv_sec >= 60) { kprintf("%ldm", ts.tv_sec / 60); ts.tv_sec %= 60; f = 1; } kprintf("%lds\n", ts.tv_sec); }
static int jzsmb_transfer_write(device_t dev, struct iic_msg *msg, int stop_hold) { struct jzsmb_softc *sc; struct timespec start, diff; uint16_t con, resid; int timeo; sc = device_get_softc(dev); timeo = JZSMB_TIMEOUT * msg->len; SMB_ASSERT_LOCKED(sc); con = SMB_READ(sc, SMBCON); con |= SMBCON_STPHLD; SMB_WRITE(sc, SMBCON, con); getnanouptime(&start); for (resid = msg->len; resid > 0; resid--) { for (;;) { getnanouptime(&diff); timespecsub(&diff, &start); if ((SMB_READ(sc, SMBST) & SMBST_TFNF) != 0) { SMB_WRITE(sc, SMBDC, msg->buf[msg->len - resid]); break; } else DELAY((1000 * hz) / JZSMB_TIMEOUT); if (tstohz(&diff) >= timeo) { device_printf(dev, "write timeout (status=0x%02x)\n", SMB_READ(sc, SMBST)); return (EIO); } } } if (!stop_hold) { con = SMB_READ(sc, SMBCON); con &= ~SMBCON_STPHLD; SMB_WRITE(sc, SMBCON, con); } return (0); }
static int jzsmb_transfer_read(device_t dev, struct iic_msg *msg) { struct jzsmb_softc *sc; struct timespec start, diff; uint16_t con, resid; int timeo; sc = device_get_softc(dev); timeo = JZSMB_TIMEOUT * msg->len; SMB_ASSERT_LOCKED(sc); con = SMB_READ(sc, SMBCON); con |= SMBCON_STPHLD; SMB_WRITE(sc, SMBCON, con); getnanouptime(&start); for (resid = msg->len; resid > 0; resid--) { for (int i = 0; i < min(resid, 8); i++) SMB_WRITE(sc, SMBDC, SMBDC_CMD); for (;;) { getnanouptime(&diff); timespecsub(&diff, &start); if ((SMB_READ(sc, SMBST) & SMBST_RFNE) != 0) { msg->buf[msg->len - resid] = SMB_READ(sc, SMBDC) & SMBDC_DAT; break; } else DELAY(1000); if (tstohz(&diff) >= timeo) { device_printf(dev, "read timeout (status=0x%02x)\n", SMB_READ(sc, SMBST)); return (EIO); } } } con = SMB_READ(sc, SMBCON); con &= ~SMBCON_STPHLD; SMB_WRITE(sc, SMBCON, con); return (0); }
int sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap, register_t *retval, copyin_t fetchss, copyout_t storeinf, copyin_t fetchts, copyout_t storets) { /* { syscallarg(const sigset_t *) set; syscallarg(siginfo_t *) info; syscallarg(struct timespec *) timeout; } */ struct proc *p = l->l_proc; int error, signum, timo; struct timespec ts, tsstart, tsnow; ksiginfo_t ksi; /* * Calculate timeout, if it was specified. * * NULL pointer means an infinite timeout. * {.tv_sec = 0, .tv_nsec = 0} means do not block. */ if (SCARG(uap, timeout)) { error = (*fetchts)(SCARG(uap, timeout), &ts, sizeof(ts)); if (error) return error; if ((error = itimespecfix(&ts)) != 0) return error; timo = tstohz(&ts); if (timo == 0) { if (ts.tv_sec == 0 && ts.tv_nsec == 0) timo = -1; /* do not block */ else timo = 1; /* the shortest possible timeout */ } /* * Remember current uptime, it would be used in * ECANCELED/ERESTART case. */ getnanouptime(&tsstart); } else { memset(&tsstart, 0, sizeof(tsstart)); /* XXXgcc */ timo = 0; /* infinite timeout */ } error = (*fetchss)(SCARG(uap, set), &l->l_sigwaitset, sizeof(l->l_sigwaitset)); if (error) return error; /* * Silently ignore SA_CANTMASK signals. psignal1() would ignore * SA_CANTMASK signals in waitset, we do this only for the below * siglist check. */ sigminusset(&sigcantmask, &l->l_sigwaitset); mutex_enter(p->p_lock); /* Check for pending signals in the process, if no - then in LWP. */ if ((signum = sigget(&p->p_sigpend, &ksi, 0, &l->l_sigwaitset)) == 0) signum = sigget(&l->l_sigpend, &ksi, 0, &l->l_sigwaitset); if (signum != 0) { /* If found a pending signal, just copy it out to the user. */ mutex_exit(p->p_lock); goto out; } if (timo < 0) { /* If not allowed to block, return an error */ mutex_exit(p->p_lock); return EAGAIN; } /* * Set up the sigwait list and wait for signal to arrive. * We can either be woken up or time out. */ l->l_sigwaited = &ksi; LIST_INSERT_HEAD(&p->p_sigwaiters, l, l_sigwaiter); error = cv_timedwait_sig(&l->l_sigcv, p->p_lock, timo); /* * Need to find out if we woke as a result of _lwp_wakeup() or a * signal outside our wait set. */ if (l->l_sigwaited != NULL) { if (error == EINTR) { /* Wakeup via _lwp_wakeup(). */ error = ECANCELED; } else if (!error) { /* Spurious wakeup - arrange for syscall restart. */ error = ERESTART; } l->l_sigwaited = NULL; LIST_REMOVE(l, l_sigwaiter); } mutex_exit(p->p_lock); /* * If the sleep was interrupted (either by signal or wakeup), update * the timeout and copyout new value back. It would be used when * the syscall would be restarted or called again. */ if (timo && (error == ERESTART || error == ECANCELED)) { getnanouptime(&tsnow); /* Compute how much time has passed since start. */ timespecsub(&tsnow, &tsstart, &tsnow); /* Substract passed time from timeout. */ timespecsub(&ts, &tsnow, &ts); if (ts.tv_sec < 0) error = EAGAIN; else { /* Copy updated timeout to userland. */ error = (*storets)(&ts, SCARG(uap, timeout), sizeof(ts)); } } out: /* * If a signal from the wait set arrived, copy it to userland. * Copy only the used part of siginfo, the padding part is * left unchanged (userland is not supposed to touch it anyway). */ if (error == 0 && SCARG(uap, info)) { error = (*storeinf)(&ksi.ksi_info, SCARG(uap, info), sizeof(ksi.ksi_info)); } if (error == 0) *retval = ksi.ksi_info._signo; return error; }