From 85e90d7efdedbec6c4b1bb2a85a952c7a50f4071 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Thu, 12 Oct 2023 22:29:51 +0200 Subject: [PATCH] dcp/afk: Retry harder to init afk endpoints/services Extend start_interface() with the number of expected services so it can stop when all services are initialized. Fixes failed display init on some devices in stage 1 due to a too slow IOP which does not manage to send service announce messages in 20 mailbox / ringbuffer query operations. Proper fix for this is to let the endpoint implementations drive the initialization via afk_epic_work() until the expected services are found. Signed-off-by: Janne Grunau --- src/afk.c | 14 ++++++++------ src/afk.h | 3 ++- src/dcp/dpav_ep.c | 11 +++++++---- src/dcp/dptx_port_ep.c | 11 +++++++---- src/dcp/system_ep.c | 11 +++++++---- src/dcp_iboot.c | 6 ++++-- 6 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/afk.c b/src/afk.c index 6a123c0e6..a47b72558 100644 --- a/src/afk.c +++ b/src/afk.c @@ -705,9 +705,10 @@ static const afk_epic_service_ops_t *afk_match_service(afk_epic_ep_t *ep, const return NULL; } -int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t txsize, size_t rxsize) +int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, int expected, size_t txsize, + size_t rxsize) { - int channels = 0; + int services = 0; struct afk_qe *msg; struct epic_announce *announce; @@ -721,7 +722,7 @@ int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t txsize, siz break; } - for (int tries = 0; tries < 20; tries += 1) { + for (int tries = 0; tries < 500; tries += 1) { s64 epic_unit = -1; char *epic_name = NULL; char *epic_class = NULL; @@ -810,11 +811,12 @@ int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t txsize, siz free(epic_name); free(epic_class); - channels++; afk_epic_rx_ack(epic); + if (++services >= expected) + break; } - if (!channels) { + if (!services) { printf("AFK[ep:%02x]: too many unexpected messages, giving up\n", epic->ep); return -1; } @@ -829,7 +831,7 @@ int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t txsize, siz return -1; } - dprintf("AFK[ep:%02x]: started interface with %d services\n", epic->ep, channels); + dprintf("AFK[ep:%02x]: started interface with %d services\n", epic->ep, services); return 0; } diff --git a/src/afk.h b/src/afk.h index a8816f055..83fb8e669 100644 --- a/src/afk.h +++ b/src/afk.h @@ -43,7 +43,8 @@ afk_epic_ep_t *afk_epic_start_ep(afk_epic_t *afk, int endpoint, const afk_epic_s int afk_epic_shutdown_ep(afk_epic_ep_t *epic); int afk_epic_work(afk_epic_t *afk, int endpoint); -int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t insize, size_t outsize); +int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, int expected, size_t insize, + size_t outsize); int afk_epic_command(afk_epic_ep_t *epic, int channel, u16 sub_type, void *txbuf, size_t txsize, void *rxbuf, size_t *rxsize); diff --git a/src/dcp/dpav_ep.c b/src/dcp/dpav_ep.c index 9f02684c8..7001e6abc 100644 --- a/src/dcp/dpav_ep.c +++ b/src/dcp/dpav_ep.c @@ -14,9 +14,11 @@ #include "../types.h" #include "../utils.h" -#define DCP_DPAV_ENDPOINT 0x24 -#define TXBUF_LEN 0x4000 -#define RXBUF_LEN 0x4000 +#define DCP_DPAV_ENDPOINT 0x24 +#define DCP_DPAV_NUM_SERVICES 4 + +#define TXBUF_LEN 0x4000 +#define RXBUF_LEN 0x4000 typedef struct dcp_dpav_if { afk_epic_ep_t *epic; @@ -53,7 +55,8 @@ dcp_dpav_if_t *dcp_dpav_init(dcp_dev_t *dcp) goto err_free; } - int err = afk_epic_start_interface(dpav->epic, dpav, TXBUF_LEN, RXBUF_LEN); + int err = + afk_epic_start_interface(dpav->epic, dpav, DCP_DPAV_NUM_SERVICES, TXBUF_LEN, RXBUF_LEN); if (err < 0) { printf("dpav: failed to initialize DPAV interface\n"); goto err_shutdown; diff --git a/src/dcp/dptx_port_ep.c b/src/dcp/dptx_port_ep.c index bb1f10228..4fabb3ea4 100644 --- a/src/dcp/dptx_port_ep.c +++ b/src/dcp/dptx_port_ep.c @@ -13,9 +13,11 @@ #include "../types.h" #include "../utils.h" -#define DCP_DPTX_PORT_ENDPOINT 0x2a -#define TXBUF_LEN 0x4000 -#define RXBUF_LEN 0x4000 +#define DCP_DPTX_PORT_ENDPOINT 0x2a +#define DCP_DPTX_PORT_NUM_SERVICES 2 + +#define TXBUF_LEN 0x4000 +#define RXBUF_LEN 0x4000 struct dcpdptx_connection_cmd { u32 unk; @@ -557,7 +559,8 @@ dcp_dptx_if_t *dcp_dptx_init(dcp_dev_t *dcp) goto err_free; } - int err = afk_epic_start_interface(dptx->epic, dptx, TXBUF_LEN, RXBUF_LEN); + int err = afk_epic_start_interface(dptx->epic, dptx, DCP_DPTX_PORT_NUM_SERVICES, TXBUF_LEN, + RXBUF_LEN); if (err < 0) { printf("dcp-dptx: failed to initialize DPTXRemotePort interface\n"); goto err_shutdown; diff --git a/src/dcp/system_ep.c b/src/dcp/system_ep.c index 8d2457529..16aac8818 100644 --- a/src/dcp/system_ep.c +++ b/src/dcp/system_ep.c @@ -14,9 +14,11 @@ #include "../types.h" #include "../utils.h" -#define DCP_SYSTEM_ENDPOINT 0x20 -#define TXBUF_LEN 0x4000 -#define RXBUF_LEN 0x4000 +#define DCP_SYSTEM_ENDPOINT 0x20 +#define DCP_SYSTEM_NUM_SERVICES 2 + +#define TXBUF_LEN 0x4000 +#define RXBUF_LEN 0x4000 typedef struct dcp_system_if { afk_epic_ep_t *epic; @@ -121,7 +123,8 @@ dcp_system_if_t *dcp_system_init(dcp_dev_t *dcp) goto err_free; } - int err = afk_epic_start_interface(system->epic, system, TXBUF_LEN, RXBUF_LEN); + int err = afk_epic_start_interface(system->epic, system, DCP_SYSTEM_NUM_SERVICES, TXBUF_LEN, + RXBUF_LEN); if (err < 0 || !system->sys_service) { printf("dcp-system: failed to initialize system-service\n"); diff --git a/src/dcp_iboot.c b/src/dcp_iboot.c index 8a3841aaf..7f88805fa 100644 --- a/src/dcp_iboot.c +++ b/src/dcp_iboot.c @@ -8,7 +8,8 @@ #include "string.h" #include "utils.h" -#define DCP_IBOOT_ENDPOINT 0x23 +#define DCP_IBOOT_ENDPOINT 0x23 +#define DCP_IBOOT_NUM_SERVICES 1 #define TXBUF_LEN 0x4000 #define RXBUF_LEN 0x4000 @@ -137,7 +138,8 @@ dcp_iboot_if_t *dcp_ib_init(dcp_dev_t *dcp) goto err_free; } - int err = afk_epic_start_interface(iboot->epic, iboot, TXBUF_LEN, RXBUF_LEN); + int err = + afk_epic_start_interface(iboot->epic, iboot, DCP_IBOOT_NUM_SERVICES, TXBUF_LEN, RXBUF_LEN); if (err < 0 || !iboot->enabled) { printf("dcp-iboot: failed to initialize disp0 service\n");