From: Kirill A. Korinsky Subject: Re: qcpas(4) mdt init: add retry To: Marcus Glocker Cc: tech@openbsd.org Date: Sat, 16 May 2026 22:39:48 +0200 On Sat, 16 May 2026 18:12:25 +0200, Marcus Glocker wrote: > > On the Samsung Galaxy Book4 Edge every since I am getting intermittent > mdt initialization errors from qcpas(4) looking like > > qcpas0: failed to shutdown lite firmware > qcpas0: failed to receive ready signal > qcpas0: failed to boot coprocessor > > leaving me without the qcpas(4) HW sensors (they anyway ship no data > on the Samsung currently, but that's a different story I want to tackle > next). > > Implementing a retry loop will help to overcome this situation: > > qcpas0: failed to shutdown lite firmware > qcpas0: failed to receive ready signal > qcpas0: coprocessor boot attempt 2 > qcpas0: failed to receive ready signal > qcpas0: coprocessor boot attempt 3 > > Feedback, regression testers, OKs? > Tested on my honor, it doesn't solve my issue, but it also do not introduce any regression. If it fixes your machine I think it make sense to commit and I OK with it, but I suggest to wait more tests and feedback. On my device it errors like that: qcpas0: failed to receive ready signal qcpas0: coprocessor boot attempt 2 qcpas0: failed to receive ready signal qcpas0: coprocessor boot attempt 3 qcpas0: failed to receive ready signal qcpas0: failed to boot coprocessor I've tried increase number of attempts, add pause... nothing. > > Index: sys/dev/fdt/qcpas.c > =================================================================== > RCS file: /cvs/src/sys/dev/fdt/qcpas.c,v > diff -u -p -u -p -r1.12 qcpas.c > --- sys/dev/fdt/qcpas.c 1 Aug 2025 08:55:09 -0000 1.12 > +++ sys/dev/fdt/qcpas.c 16 May 2026 15:50:14 -0000 > @@ -211,7 +211,7 @@ qcpas_mountroot(struct device *self) > char fwname[128]; > size_t fwlen, dtb_fwlen; > u_char *fw, *dtb_fw; > - int node, ret; > + int i, node, ret; > int error; > > if (qcpas_map_memory(sc) != 0) > @@ -272,7 +272,19 @@ qcpas_mountroot(struct device *self) > free(dtb_fw, M_DEVBUF, dtb_fwlen); > } > > - ret = qcpas_mdt_init(sc, sc->sc_pas_id, fw, fwlen); > + /* > + * Coprocessor boot is intermittent on some platforms > + * (e.g. Samsung Galaxy Book4 Edge): all of the SCM calls > + * succeed but the firmware sometimes silently dies before > + * signalling ready. Retry up to a few times -- when it > + * works, the ready signal arrives within a few hundred ms. > + */ > + for (ret = -1, i = 0; ret != 0 && i < 3; i++) { > + if (i > 0) > + printf("%s: coprocessor boot attempt %d\n", > + sc->sc_dev.dv_xname, i + 1); > + ret = qcpas_mdt_init(sc, sc->sc_pas_id, fw, fwlen); > + } > free(fw, M_DEVBUF, fwlen); > if (ret != 0) { > printf("%s: failed to boot coprocessor\n", > @@ -467,6 +479,7 @@ qcpas_mdt_init(struct qcpas_softc *sc, i > QCPAS_DMA_DVA(sc->sc_metadata[idx])) != 0) { > printf("%s: init image failed\n", sc->sc_dev.dv_xname); > qcpas_dmamem_free(sc, sc->sc_metadata[idx]); > + sc->sc_metadata[idx] = NULL; > return EINVAL; > } > > @@ -474,6 +487,7 @@ qcpas_mdt_init(struct qcpas_softc *sc, i > sc->sc_mem_phys[idx], maxpa - minpa) != 0) { > printf("%s: mem setup failed\n", sc->sc_dev.dv_xname); > qcpas_dmamem_free(sc, sc->sc_metadata[idx]); > + sc->sc_metadata[idx] = NULL; > return EINVAL; > } > > @@ -509,6 +523,7 @@ qcpas_mdt_init(struct qcpas_softc *sc, i > if (qcscm_pas_auth_and_reset(pas_id) != 0) { > printf("%s: auth and reset failed\n", sc->sc_dev.dv_xname); > qcpas_dmamem_free(sc, sc->sc_metadata[idx]); > + sc->sc_metadata[idx] = NULL; > return EINVAL; > } > > @@ -519,6 +534,14 @@ qcpas_mdt_init(struct qcpas_softc *sc, i > if (error) { > printf("%s: failed to receive ready signal\n", > sc->sc_dev.dv_xname); > + /* > + * The coprocessor was started but never signalled ready. > + * Shut it down and release the metadata buffer so the > + * caller can retry from scratch. > + */ > + qcscm_pas_shutdown(pas_id); > + qcpas_dmamem_free(sc, sc->sc_metadata[idx]); > + sc->sc_metadata[idx] = NULL; > return error; > } > -- wbr, Kirill