Skip to content

Commit 0a3f7f5

Browse files
committed
kernel: fix error propagation for device deferred initialization
This fix makes sure that do_device_init() returns a negative value if the device's initialization failed. Previously, it mistakely returned +errno instead of -errno. This oversight happened during the refactoring of z_sys_init_run_level() to support deferred initialization, from which most of do_device_init() code derives. The rc value computed and stored in dev->state->init_res is the POSITIVE value of the resulting errno. Returning rc therefore breaks the convention of a negative value to signal failure. Signed-off-by: Loic Domaigne <tech@domaigne.com>
1 parent a10f807 commit 0a3f7f5

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

kernel/init.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,28 +313,43 @@ static int do_device_init(const struct device *dev)
313313

314314
if (dev->ops.init != NULL) {
315315
rc = dev->ops.init(dev);
316-
/* Mark device initialized. If initialization
317-
* failed, record the error condition.
316+
/* If initialization failed, record in dev->state->init_res
317+
* the POSITIVE value of the resulting errno
318318
*/
319319
if (rc != 0) {
320+
/* device's init function should return:
321+
* 0 on success
322+
* a negative value on failure (-errno)
323+
* errno value maps to an uint8_t range as of now.
324+
*/
325+
__ASSERT(rc >= -UINT8_MAX && rc < 0, "device %s init: invalid error (%d)",
326+
dev->name, rc);
327+
320328
if (rc < 0) {
321329
rc = -rc;
322330
}
331+
/* handle error value overflow in production
332+
* this is likely a bug in the device's init function. Signals it
333+
*/
323334
if (rc > UINT8_MAX) {
324335
rc = UINT8_MAX;
325336
}
326337
dev->state->init_res = rc;
327338
}
328339
}
329340

341+
/* device initialization has been invoked */
330342
dev->state->initialized = true;
331343

332344
if (rc == 0) {
333345
/* Run automatic device runtime enablement */
334346
(void)pm_device_runtime_auto_enable(dev);
335347
}
336348

337-
return rc;
349+
/* here, the value of rc is either 0 or +errno
350+
* flip the sign to return a negative value on failure as expected
351+
*/
352+
return -rc;
338353
}
339354

340355
/**

0 commit comments

Comments
 (0)