summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2022-12-03 13:42:24 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2022-12-03 13:42:24 +0000
commiteb9d114544fdff4c0340934d8d5715ac449a6844 (patch)
treed32ac2b28254e37d0b19e82ee55497116aa78352 /sys
parent2886dfe672150ae19cc05a02d7a712f4421e210c (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.c4
-rw-r--r--sys/arch/arm64/dev/rtkit.c83
-rw-r--r--sys/arch/arm64/dev/rtkit.h1
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 *);