diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-12-03 13:42:24 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-12-03 13:42:24 +0000 |
commit | eb9d114544fdff4c0340934d8d5715ac449a6844 (patch) | |
tree | d32ac2b28254e37d0b19e82ee55497116aa78352 /sys | |
parent | 2886dfe672150ae19cc05a02d7a712f4421e210c (diff) |
Rework the RTKit code such that we don't spin forever if for some reason
we don't get the expected replies from the firmware on the other side.
ok patrick@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm64/dev/aplmbox.c | 4 | ||||
-rw-r--r-- | sys/arch/arm64/dev/rtkit.c | 83 | ||||
-rw-r--r-- | sys/arch/arm64/dev/rtkit.h | 1 |
3 files changed, 50 insertions, 38 deletions
diff --git a/sys/arch/arm64/dev/aplmbox.c b/sys/arch/arm64/dev/aplmbox.c index 9c313af857a..fe3a99d0e32 100644 --- a/sys/arch/arm64/dev/aplmbox.c +++ b/sys/arch/arm64/dev/aplmbox.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aplmbox.c,v 1.3 2022/11/09 19:18:11 kettenis Exp $ */ +/* $OpenBSD: aplmbox.c,v 1.4 2022/12/03 13:42:23 kettenis Exp $ */ /* * Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org> * @@ -187,7 +187,7 @@ aplmbox_recv(void *cookie, void *data, size_t len) ctrl = HREAD4(sc, MBOX_I2A_CTRL); if (ctrl & MBOX_I2A_CTRL_EMPTY) - return EAGAIN; + return EWOULDBLOCK; msg->data0 = HREAD8(sc, MBOX_I2A_RECV0); msg->data1 = HREAD8(sc, MBOX_I2A_RECV1); diff --git a/sys/arch/arm64/dev/rtkit.c b/sys/arch/arm64/dev/rtkit.c index fc0ecab9542..96741760d56 100644 --- a/sys/arch/arm64/dev/rtkit.c +++ b/sys/arch/arm64/dev/rtkit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtkit.c,v 1.9 2022/11/11 11:45:10 kettenis Exp $ */ +/* $OpenBSD: rtkit.c,v 1.10 2022/12/03 13:42:23 kettenis Exp $ */ /* * Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org> * @@ -99,16 +99,7 @@ struct rtkit_state { int rtkit_recv(struct mbox_channel *mc, struct aplmbox_msg *msg) { - int error, timo; - - for (timo = 0; timo < 10000; timo++) { - error = mbox_recv(mc, msg, sizeof(*msg)); - if (error == 0) - break; - delay(10); - } - - return error; + return mbox_recv(mc, msg, sizeof(*msg)); } int @@ -468,36 +459,18 @@ rtkit_init(int node, const char *name, int flags, struct rtkit *rk) int rtkit_boot(struct rtkit_state *state) { - struct mbox_channel *mc = state->mc; - int error; - /* Wake up! */ - error = rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_IOP_PWR_STATE, - RTKIT_MGMT_PWR_STATE_ON); - if (error) - return error; - - while (state->iop_pwrstate != RTKIT_MGMT_PWR_STATE_ON) - rtkit_poll(state); - - return 0; + return rtkit_set_iop_pwrstate(state, RTKIT_MGMT_PWR_STATE_ON); } void rtkit_shutdown(struct rtkit_state *state) { - struct mbox_channel *mc = state->mc; struct rtkit *rk = state->rk; int i; - if (state->ap_pwrstate != RTKIT_MGMT_PWR_STATE_QUIESCED) - rtkit_set_ap_pwrstate(state, RTKIT_MGMT_PWR_STATE_QUIESCED); - - rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_IOP_PWR_STATE, - RTKIT_MGMT_PWR_STATE_SLEEP); - - while (state->iop_pwrstate != RTKIT_MGMT_PWR_STATE_SLEEP) - rtkit_poll(state); + rtkit_set_ap_pwrstate(state, RTKIT_MGMT_PWR_STATE_QUIESCED); + rtkit_set_iop_pwrstate(state, RTKIT_MGMT_PWR_STATE_SLEEP); KASSERT(state->iop_pwrstate == RTKIT_MGMT_PWR_STATE_SLEEP); KASSERT(state->ap_pwrstate == RTKIT_MGMT_PWR_STATE_QUIESCED); @@ -521,7 +494,7 @@ int rtkit_set_ap_pwrstate(struct rtkit_state *state, uint16_t pwrstate) { struct mbox_channel *mc = state->mc; - int error; + int error, timo; if (state->ap_pwrstate == pwrstate) return 0; @@ -531,10 +504,48 @@ rtkit_set_ap_pwrstate(struct rtkit_state *state, uint16_t pwrstate) if (error) return error; - while (state->ap_pwrstate != pwrstate) - rtkit_poll(state); + for (timo = 0; timo < 100000; timo++) { + error = rtkit_poll(state); + if (error == EWOULDBLOCK) { + delay(10); + continue; + } - return 0; + KASSERT(error == 0); + if (state->ap_pwrstate == pwrstate) + break; + } + + return error; +} + +int +rtkit_set_iop_pwrstate(struct rtkit_state *state, uint16_t pwrstate) +{ + struct mbox_channel *mc = state->mc; + int error, timo; + + if (state->iop_pwrstate == pwrstate) + return 0; + + error = rtkit_send(mc, RTKIT_EP_MGMT, RTKIT_MGMT_IOP_PWR_STATE, + pwrstate); + if (error) + return error; + + for (timo = 0; timo < 100000; timo++) { + error = rtkit_poll(state); + if (error == EWOULDBLOCK) { + delay(10); + continue; + } + + KASSERT(error == 0); + if (state->iop_pwrstate == pwrstate) + break; + } + + return error; } int diff --git a/sys/arch/arm64/dev/rtkit.h b/sys/arch/arm64/dev/rtkit.h index b17b005807c..1d11a653771 100644 --- a/sys/arch/arm64/dev/rtkit.h +++ b/sys/arch/arm64/dev/rtkit.h @@ -19,6 +19,7 @@ struct rtkit_state *rtkit_init(int, const char *, int, struct rtkit *); int rtkit_boot(struct rtkit_state *); void rtkit_shutdown(struct rtkit_state *); int rtkit_set_ap_pwrstate(struct rtkit_state *, uint16_t); +int rtkit_set_iop_pwrstate(struct rtkit_state *, uint16_t); int rtkit_poll(struct rtkit_state *); int rtkit_start_endpoint(struct rtkit_state *, uint32_t, void (*)(void *, uint64_t), void *); |