int tpm_get_timeouts(struct tpm_chip *chip) { struct tpm_cmd_t tpm_cmd; struct timeout_t *timeout_cap; struct duration_t *duration_cap; ssize_t rc; uint32_t timeout; unsigned int scale = 1; tpm_cmd.header.in = tpm_getcap_header; tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT; if((rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, "attempting to determine the timeouts")) != 0) { printk("transmit failed %d\n", rc); goto duration; } if(be32_to_cpu(tpm_cmd.header.out.return_code) != 0 || be32_to_cpu(tpm_cmd.header.out.length) != sizeof(tpm_cmd.header.out) + sizeof(uint32_t) + 4 * sizeof(uint32_t)) { return -EINVAL; } timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout; /* Don't overwrite default if value is 0 */ timeout = be32_to_cpu(timeout_cap->a); if(timeout && timeout < 1000) { /* timeouts in msc rather usec */ scale = 1000; } if (timeout) chip->timeout_a = MICROSECS(timeout * scale); /*Convert to msec */ ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_a,MILLISECS(TIS_SHORT_TIMEOUT),'a'); timeout = be32_to_cpu(timeout_cap->b); if (timeout) chip->timeout_b = MICROSECS(timeout * scale); /*Convert to msec */ ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_b,MILLISECS(TIS_LONG_TIMEOUT),'b'); timeout = be32_to_cpu(timeout_cap->c); if (timeout) chip->timeout_c = MICROSECS(timeout * scale); /*Convert to msec */ ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_c,MILLISECS(TIS_SHORT_TIMEOUT),'c'); timeout = be32_to_cpu(timeout_cap->d); if (timeout) chip->timeout_d = MICROSECS(timeout * scale); /*Convert to msec */ ADJUST_TIMEOUTS_TO_STANDARD(chip->timeout_d,MILLISECS(TIS_SHORT_TIMEOUT),'d'); duration: tpm_cmd.header.in = tpm_getcap_header; tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION; if((rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, "attempting to determine the durations")) < 0) { return rc; } if(be32_to_cpu(tpm_cmd.header.out.return_code) != 0 || be32_to_cpu(tpm_cmd.header.out.length) != sizeof(tpm_cmd.header.out) + sizeof(uint32_t) + 3 * sizeof(uint32_t)) { return -EINVAL; } duration_cap = &tpm_cmd.params.getcap_out.cap.duration; chip->duration[TPM_SHORT] = MICROSECS(be32_to_cpu(duration_cap->tpm_short)); chip->duration[TPM_MEDIUM] = MICROSECS(be32_to_cpu(duration_cap->tpm_medium)); chip->duration[TPM_LONG] = MICROSECS(be32_to_cpu(duration_cap->tpm_long)); /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above * value wrong and apparently reports msecs rather than usecs. So we * fix up the resulting too-small TPM_SHORT value to make things work. */ if (chip->duration[TPM_SHORT] < MILLISECS(10)) { chip->duration[TPM_SHORT] = SECONDS(1); chip->duration[TPM_MEDIUM] *= 1000; chip->duration[TPM_LONG] *= 1000; printk("Adjusting TPM timeout parameters\n"); } return 0; }
static int udp_select(struct socket *sock, int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { IO_Rec rec; uint32_t nrecs; word_t value; Time_ns t; struct udp_data *udp_data= (struct udp_data *)sock->data; MU_LOCK(&sock->lock); /* XXX really want to keep a domain-wide cache of connections */ if(sock->state != SS_CONNECTED) /* stack needs building */ { struct sockaddr_in *laddr = (struct sockaddr_in *)&(sock->laddr); /* remote address isn't used for anything in recv */ build_stack(udp_data, laddr, NULL); sock->state = SS_CONNECTED; } MU_RELEASE(&sock->lock); MU_LOCK(&sock->rxlock); if (timeout) { t = NOW() + timeout->tv_sec * SECONDS(1) + timeout->tv_usec * MICROSECS(1); } else { t = FOREVER; } value = 0; IO$GetPkt(udp_data->rxio, 0, &rec, t, &nrecs, &value); if (value) { eprintf("udp_select: got a packet cx?!?\n"); ntsc_dbgstop(); } #ifdef PARANOID if (NOW() > t + SECONDS(2)) printf("udp_select: warning: took >2 secs to return from select?\n"); #endif MU_RELEASE(&sock->rxlock); if (nrecs) { // eprintf("sel ok\n"); return 1; /* there's data available */ } else { // eprintf("sel t/o\n"); return 0; /* no data, but not an error - we timed out */ } }